From 618033a79abfbcd4a7314074e4f7aba603c604e8 Mon Sep 17 00:00:00 2001
From: Brett Bieber <brett.bieber@gmail.com>
Date: Wed, 27 Jan 2010 16:12:55 +0000
Subject: [PATCH] Add local pear registry of all required packages

---
 lib/.config                                   |    2 +
 .../configsnapshot-2010-01-27 10-05-56.xml    |    2 +
 .../configsnapshot-2010-01-27 10-08-35.xml    |    2 +
 lib/.pear2registry                            |  Bin 0 -> 326656 bytes
 lib/.xmlregistry/channels/channel-__uri.xml   |   13 +
 .../channels/channel-doc.php.net.xml          |   14 +
 .../channels/channel-pear.php.net.xml         |   32 +
 .../channels/channel-pear.unl.edu.xml         |   15 +
 .../channels/channel-pear2.php.net.xml        |   16 +
 .../channels/channel-pecl.php.net.xml         |   25 +
 .../channel-simplecas.googlecode.com##svn.xml |   15 +
 .../channels/channelalias-__uri.txt           |    1 +
 .../channels/channelalias-pear.txt            |    1 +
 .../channels/channelalias-pear2.txt           |    1 +
 .../channels/channelalias-pecl.txt            |    1 +
 .../channels/channelalias-phpdocs.txt         |    1 +
 .../channels/channelalias-simplecas.txt       |    1 +
 .../channels/channelalias-unl.txt             |    1 +
 .../pear.php.net/Archive_Tar/1.3.3-info.xml   |  248 +
 .../pear.php.net/Cache_Lite/1.7.8-info.xml    |  671 ++
 .../Console_Getopt/1.2.3-info.xml             |  156 +
 .../pear.php.net/HTTP_Request2/0.5.1-info.xml |  279 +
 .../pear.php.net/Net_URL2/0.3.1-info.xml      |   97 +
 .../packages/pear.php.net/PEAR/1.9.0-info.xml |  802 ++
 .../Structures_Graph/1.0.2-info.xml           |   92 +
 .../pear.php.net/XML_Util/1.2.1-info.xml      |  404 +
 .../pear.unl.edu/UNL_DWT/0.7.1-info.xml       |  224 +
 .../UNL_Peoplefinder/0.1.0-info.xml           |   94 +
 .../UNL_Templates/1.0.0RC9-info.xml           |  742 ++
 .../SimpleCAS/0.5.0-info.xml                  |  225 +
 lib/data/PEAR/package.dtd                     |  103 +
 lib/data/PEAR/template.spec                   |   72 +
 lib/data/Structures_Graph/LICENSE             |  504 ++
 lib/data/Structures_Graph/genpackage.xml.pl   |   16 +
 lib/data/Structures_Graph/package.sh          |   51 +
 lib/data/Structures_Graph/publish.sh          |    5 +
 .../UNL_Peoplefinder/pear.unl.edu/hr_tree.xml | 7951 +++++++++++++++++
 .../data/tpl_cache/Version2/Document.tpl      |  111 +
 .../data/tpl_cache/Version2/Fixed.tpl         |  137 +
 .../data/tpl_cache/Version2/Liquid.tpl        |  137 +
 .../data/tpl_cache/Version2/Popup.tpl         |  109 +
 .../data/tpl_cache/Version2/Secure.tpl        |  131 +
 .../data/tpl_cache/Version2/Unlaffiliate.tpl  |  125 +
 .../data/tpl_cache/Version2/Unlframework.tpl  |  112 +
 .../Version2/Unlstandardtemplate.tpl          |  131 +
 .../data/tpl_cache/Version3/Absolute.tpl      |  119 +
 .../data/tpl_cache/Version3/Debug.tpl         |  119 +
 .../data/tpl_cache/Version3/Document.tpl      |   91 +
 .../data/tpl_cache/Version3/Fixed.tpl         |  119 +
 .../data/tpl_cache/Version3/Liquid.tpl        |  119 +
 .../data/tpl_cache/Version3/Popup.tpl         |   79 +
 .../data/tpl_cache/Version3/Secure.tpl        |  101 +
 .../tpl_cache/Version3/Shared_column_left.tpl |  131 +
 .../Version3/Shared_column_right.tpl          |  131 +
 lib/docs/Archive_Tar/docs/Archive_Tar.txt     |  461 +
 lib/docs/Cache_Lite/Cache/LICENSE             |  458 +
 lib/docs/Cache_Lite/Cache/TODO                |   46 +
 lib/docs/Cache_Lite/Cache/docs/examples       |  254 +
 lib/docs/Cache_Lite/Cache/docs/technical      |   28 +
 lib/docs/Cache_Lite/Cache/tests/readme        |   17 +
 .../HTTP/docs/examples/upload-rapidshare.php  |   60 +
 lib/docs/Net_URL2/Net/docs/6470.php           |   75 +
 lib/docs/Net_URL2/Net/docs/example.php        |   74 +
 lib/docs/PEAR/INSTALL                         |   53 +
 lib/docs/PEAR/LICENSE                         |   27 +
 lib/docs/PEAR/README                          |   32 +
 .../examples/Zend_Auth_Adapter_SimpleCAS.php  |  134 +
 lib/docs/SimpleCAS/docs/examples/simple.php   |   27 +
 lib/docs/Structures_Graph/docs/generate.sh    |    8 +
 .../Structures_Graph/Structures_Graph.html    |  243 +
 ...uctures_Graph_Manipulator_AcyclicTest.html |  105 +
 ...s_Graph_Manipulator_TopologicalSorter.html |  107 +
 .../Structures_Graph_Node.html                |  549 ++
 ...res_Graph_Manipulator_AcyclicTest_php.html |  119 +
 ...aph_Manipulator_TopologicalSorter_php.html |  133 +
 .../_Structures_Graph_Node_php.html           |  105 +
 .../_Structures_Graph_php.html                |  136 +
 .../tutorial_Structures_Graph.pkg.html        |   75 +
 .../html/classtrees_Structures_Graph.html     |   36 +
 .../docs/html/elementindex.html               |  339 +
 .../html/elementindex_Structures_Graph.html   |  336 +
 .../Structures_Graph/docs/html/errors.html    |   16 +
 .../Structures_Graph/docs/html/index.html     |   24 +
 .../docs/html/li_Structures_Graph.html        |   53 +
 .../docs/html/media/banner.css                |   32 +
 .../docs/html/media/stylesheet.css            |  134 +
 .../Structures_Graph/docs/html/packages.html  |   27 +
 .../Structures_Graph/docs/html/todolist.html  |   21 +
 .../Structures_Graph/Structures_Graph.pkg     |   98 +
 .../UNL_DWT/docs/examples/Template_style1.php |   25 +
 .../UNL_DWT/docs/examples/Template_style1.tpl |   86 +
 lib/docs/UNL_DWT/docs/examples/example.ini    |    5 +
 .../UNL_DWT/docs/examples/example_style1.php  |   28 +
 .../UNL_DWT/docs/examples/scanner_example.php |   11 +
 .../UNL_DWT/docs/examples/template_style1.dwt |   80 +
 .../pear.unl.edu/examples/config.inc.php      |    4 +
 .../pear.unl.edu/examples/getExactMatches.php |   10 +
 .../pear.unl.edu/examples/getLikeMatches.php  |   10 +
 .../pear.unl.edu/examples/getUID.php          |    7 +
 .../examples/customization/CustomClass.php    |  102 +
 .../customization/customization_example.html  |    1 +
 .../customization/customization_example.php   |    8 +
 .../UNL_Templates/docs/examples/example1.php  |   25 +
 .../UNL_Templates/docs/examples/scanner.php   |   11 +
 lib/docs/XML_Util/XML/examples/example.php    |  299 +
 lib/docs/XML_Util/XML/examples/example2.php   |  145 +
 lib/downloads/Archive_Tar-1.3.3.tgz           |  Bin 0 -> 18119 bytes
 lib/downloads/Cache_Lite-1.7.8.tgz            |  Bin 0 -> 30061 bytes
 lib/downloads/Console_Getopt-1.2.3.tgz        |  Bin 0 -> 4011 bytes
 lib/downloads/HTTP_Request2-0.5.1.tgz         |  Bin 0 -> 58027 bytes
 lib/downloads/Net_URL2-0.3.0.tgz              |  Bin 0 -> 8371 bytes
 lib/downloads/Net_URL2-0.3.1.tgz              |  Bin 0 -> 8379 bytes
 lib/downloads/PEAR-1.9.0.tgz                  |  Bin 0 -> 291634 bytes
 lib/downloads/SimpleCAS-0.5.0.tgz             |  Bin 0 -> 7565 bytes
 lib/downloads/Structures_Graph-1.0.2.tgz      |  Bin 0 -> 30947 bytes
 lib/downloads/UNL_DWT-0.7.1.tgz               |  Bin 0 -> 10875 bytes
 lib/downloads/UNL_Templates-1.0.0RC9.tgz      |  Bin 0 -> 18324 bytes
 lib/downloads/XML_Util-1.2.1.tgz              |  Bin 0 -> 17729 bytes
 lib/php/Archive/Tar.php                       | 1848 ++++
 lib/php/Cache/Lite.php                        |  835 ++
 lib/php/Cache/Lite/File.php                   |   93 +
 lib/php/Cache/Lite/Function.php               |  211 +
 lib/php/Cache/Lite/Output.php                 |   72 +
 lib/php/Console/Getopt.php                    |  290 +
 lib/php/HTTP/Request2.php                     |  861 ++
 lib/php/HTTP/Request2/Adapter.php             |  154 +
 lib/php/HTTP/Request2/Adapter/Curl.php        |  461 +
 lib/php/HTTP/Request2/Adapter/Mock.php        |  171 +
 lib/php/HTTP/Request2/Adapter/Socket.php      | 1046 +++
 lib/php/HTTP/Request2/Exception.php           |   62 +
 lib/php/HTTP/Request2/MultipartBody.php       |  274 +
 lib/php/HTTP/Request2/Observer/Log.php        |  215 +
 lib/php/HTTP/Request2/Response.php            |  559 ++
 lib/php/Net/URL2.php                          |  894 ++
 lib/php/OS/Guess.php                          |  338 +
 lib/php/PEAR.php                              | 1137 +++
 lib/php/PEAR/Autoloader.php                   |  218 +
 lib/php/PEAR/Builder.php                      |  474 +
 lib/php/PEAR/ChannelFile.php                  | 1559 ++++
 lib/php/PEAR/ChannelFile/Parser.php           |   68 +
 lib/php/PEAR/Command.php                      |  414 +
 lib/php/PEAR/Command/Auth.php                 |   81 +
 lib/php/PEAR/Command/Auth.xml                 |   30 +
 lib/php/PEAR/Command/Build.php                |   85 +
 lib/php/PEAR/Command/Build.xml                |   10 +
 lib/php/PEAR/Command/Channels.php             |  883 ++
 lib/php/PEAR/Command/Channels.xml             |  123 +
 lib/php/PEAR/Command/Common.php               |  273 +
 lib/php/PEAR/Command/Config.php               |  413 +
 lib/php/PEAR/Command/Config.xml               |   92 +
 lib/php/PEAR/Command/Install.php              | 1266 +++
 lib/php/PEAR/Command/Install.xml              |  276 +
 lib/php/PEAR/Command/Mirror.php               |  139 +
 lib/php/PEAR/Command/Mirror.xml               |   18 +
 lib/php/PEAR/Command/Package.php              | 1108 +++
 lib/php/PEAR/Command/Package.xml              |  237 +
 lib/php/PEAR/Command/Pickle.php               |  421 +
 lib/php/PEAR/Command/Pickle.xml               |   36 +
 lib/php/PEAR/Command/Registry.php             | 1143 +++
 lib/php/PEAR/Command/Registry.xml             |   58 +
 lib/php/PEAR/Command/Remote.php               |  809 ++
 lib/php/PEAR/Command/Remote.xml               |  109 +
 lib/php/PEAR/Command/Test.php                 |  337 +
 lib/php/PEAR/Command/Test.xml                 |   54 +
 lib/php/PEAR/Common.php                       |  837 ++
 lib/php/PEAR/Config.php                       | 2097 +++++
 lib/php/PEAR/Dependency2.php                  | 1358 +++
 lib/php/PEAR/DependencyDB.php                 |  769 ++
 lib/php/PEAR/Downloader.php                   | 1762 ++++
 lib/php/PEAR/Downloader/Package.php           | 2004 +++++
 lib/php/PEAR/ErrorStack.php                   |  985 ++
 lib/php/PEAR/Exception.php                    |  391 +
 lib/php/PEAR/FixPHP5PEARWarnings.php          |    7 +
 lib/php/PEAR/Frontend.php                     |  228 +
 lib/php/PEAR/Frontend/CLI.php                 |  732 ++
 lib/php/PEAR/Installer.php                    | 1823 ++++
 lib/php/PEAR/Installer/Role.php               |  276 +
 lib/php/PEAR/Installer/Role/Cfg.php           |  106 +
 lib/php/PEAR/Installer/Role/Cfg.xml           |   15 +
 lib/php/PEAR/Installer/Role/Common.php        |  174 +
 lib/php/PEAR/Installer/Role/Data.php          |   28 +
 lib/php/PEAR/Installer/Role/Data.xml          |   15 +
 lib/php/PEAR/Installer/Role/Doc.php           |   28 +
 lib/php/PEAR/Installer/Role/Doc.xml           |   15 +
 lib/php/PEAR/Installer/Role/Ext.php           |   28 +
 lib/php/PEAR/Installer/Role/Ext.xml           |   12 +
 lib/php/PEAR/Installer/Role/Php.php           |   28 +
 lib/php/PEAR/Installer/Role/Php.xml           |   15 +
 lib/php/PEAR/Installer/Role/Script.php        |   28 +
 lib/php/PEAR/Installer/Role/Script.xml        |   15 +
 lib/php/PEAR/Installer/Role/Src.php           |   34 +
 lib/php/PEAR/Installer/Role/Src.xml           |   12 +
 lib/php/PEAR/Installer/Role/Test.php          |   28 +
 lib/php/PEAR/Installer/Role/Test.xml          |   15 +
 lib/php/PEAR/Installer/Role/Www.php           |   28 +
 lib/php/PEAR/Installer/Role/Www.xml           |   15 +
 lib/php/PEAR/PackageFile.php                  |  501 ++
 lib/php/PEAR/PackageFile/Generator/v1.php     | 1284 +++
 lib/php/PEAR/PackageFile/Generator/v2.php     |  893 ++
 lib/php/PEAR/PackageFile/Parser/v1.php        |  459 +
 lib/php/PEAR/PackageFile/Parser/v2.php        |  113 +
 lib/php/PEAR/PackageFile/v1.php               | 1612 ++++
 lib/php/PEAR/PackageFile/v2.php               | 2045 +++++
 lib/php/PEAR/PackageFile/v2/Validator.php     | 2154 +++++
 lib/php/PEAR/PackageFile/v2/rw.php            | 1604 ++++
 lib/php/PEAR/Packager.php                     |  201 +
 lib/php/PEAR/REST.php                         |  448 +
 lib/php/PEAR/REST/10.php                      |  867 ++
 lib/php/PEAR/REST/11.php                      |  341 +
 lib/php/PEAR/REST/13.php                      |  299 +
 lib/php/PEAR/Registry.php                     | 2395 +++++
 lib/php/PEAR/RunTest.php                      |  951 ++
 lib/php/PEAR/Task/Common.php                  |  202 +
 lib/php/PEAR/Task/Postinstallscript.php       |  323 +
 lib/php/PEAR/Task/Postinstallscript/rw.php    |  169 +
 lib/php/PEAR/Task/Replace.php                 |  176 +
 lib/php/PEAR/Task/Replace/rw.php              |   61 +
 lib/php/PEAR/Task/Unixeol.php                 |   77 +
 lib/php/PEAR/Task/Unixeol/rw.php              |   56 +
 lib/php/PEAR/Task/Windowseol.php              |   77 +
 lib/php/PEAR/Task/Windowseol/rw.php           |   56 +
 lib/php/PEAR/Validate.php                     |  629 ++
 lib/php/PEAR/Validator/PECL.php               |   63 +
 lib/php/PEAR/XMLParser.php                    |  253 +
 lib/php/PEAR5.php                             |   33 +
 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/Structures/Graph.php                  |  154 +
 .../Graph/Manipulator/AcyclicTest.php         |  136 +
 .../Graph/Manipulator/TopologicalSorter.php   |  153 +
 lib/php/Structures/Graph/Node.php             |  338 +
 lib/php/System.php                            |  621 ++
 lib/php/UNL/DWT.php                           |  274 +
 lib/php/UNL/DWT/Generator.php                 |  476 +
 lib/php/UNL/DWT/Region.php                    |   22 +
 lib/php/UNL/DWT/Scanner.php                   |  138 +
 lib/php/UNL/DWT/createTemplates.php           |   44 +
 lib/php/UNL/Peoplefinder.php                  |   57 +
 lib/php/UNL/Peoplefinder/Department.php       |  174 +
 .../UNL/Peoplefinder/Department/Search.php    |   57 +
 lib/php/UNL/Peoplefinder/Driver/LDAP.php      |  275 +
 .../Driver/LDAP/AdvancedFilter.php            |   79 +
 .../UNL/Peoplefinder/Driver/LDAP/OUFilter.php |   35 +
 .../Driver/LDAP/StandardFilter.php            |  105 +
 .../Driver/LDAP/TelephoneFilter.php           |   30 +
 lib/php/UNL/Peoplefinder/Driver/LDAP/Util.php |  105 +
 .../UNL/Peoplefinder/Driver/WebService.php    |   40 +
 lib/php/UNL/Peoplefinder/DriverInterface.php  |   46 +
 lib/php/UNL/Peoplefinder/Record.php           |  122 +
 lib/php/UNL/Peoplefinder/Renderer/HTML.php    |  518 ++
 lib/php/UNL/Peoplefinder/Renderer/JSON.php    |   37 +
 .../UNL/Peoplefinder/Renderer/Serialized.php  |   37 +
 lib/php/UNL/Peoplefinder/Renderer/XML.php     |   68 +
 lib/php/UNL/Peoplefinder/Renderer/vCard.php   |   60 +
 .../UNL/Peoplefinder/RendererInterface.php    |   10 +
 lib/php/UNL/Templates.php                     |  331 +
 lib/php/UNL/Templates/CachingService.php      |   20 +
 .../Templates/CachingService/CacheLite.php    |   64 +
 lib/php/UNL/Templates/Scanner.php             |   32 +
 lib/php/UNL/Templates/Version.php             |   21 +
 lib/php/UNL/Templates/Version2.php            |   51 +
 lib/php/UNL/Templates/Version2/Document.php   |   42 +
 lib/php/UNL/Templates/Version2/Fixed.php      |   47 +
 lib/php/UNL/Templates/Version2/Liquid.php     |   47 +
 lib/php/UNL/Templates/Version2/Popup.php      |   42 +
 lib/php/UNL/Templates/Version2/Secure.php     |   45 +
 .../UNL/Templates/Version2/Unlaffiliate.php   |   41 +
 .../UNL/Templates/Version2/Unlframework.php   |   45 +
 .../Version2/Unlstandardtemplate.php          |   48 +
 lib/php/UNL/Templates/Version3.php            |   67 +
 lib/php/UNL/Templates/Version3/Absolute.php   |   50 +
 lib/php/UNL/Templates/Version3/Debug.php      |   30 +
 lib/php/UNL/Templates/Version3/Document.php   |   46 +
 lib/php/UNL/Templates/Version3/Fixed.php      |   50 +
 lib/php/UNL/Templates/Version3/Liquid.php     |   50 +
 lib/php/UNL/Templates/Version3/Popup.php      |   45 +
 lib/php/UNL/Templates/Version3/Secure.php     |   48 +
 .../Templates/Version3/Shared_column_left.php |   51 +
 .../Version3/Shared_column_right.php          |   51 +
 lib/php/XML/Util.php                          |  911 ++
 lib/php/pearcmd.php                           |  445 +
 lib/php/peclcmd.php                           |   41 +
 .../tests/Cache_Lite_File_classical.phpt      |   89 +
 .../tests/Cache_Lite_Function_classical.phpt  |   99 +
 .../tests/Cache_Lite_Function_dontcache.phpt  |  128 +
 .../Cache/tests/Cache_Lite_Function_drop.phpt |   48 +
 .../tests/Cache_Lite_Output_classical.phpt    |   51 +
 .../tests/Cache_Lite_automaticCleaning.phpt   |   54 +
 .../Cache/tests/Cache_Lite_classical.phpt     |   51 +
 .../Cache/tests/Cache_Lite_error.phpt         |   61 +
 .../Cache/tests/Cache_Lite_error2.phpt        |   62 +
 .../Cache/tests/Cache_Lite_error3.phpt        |   25 +
 .../Cache/tests/Cache_Lite_eternal.phpt       |   51 +
 .../Cache/tests/Cache_Lite_fatest.phpt        |   55 +
 .../Cache/tests/Cache_Lite_hashed.phpt        |   96 +
 .../Cache/tests/Cache_Lite_lifetime.phpt      |   40 +
 .../Cache/tests/Cache_Lite_memorycache.phpt   |   52 +
 .../Cache/tests/Cache_Lite_serialization.phpt |   52 +
 lib/tests/Cache_Lite/Cache/tests/bench.php    |   27 +
 lib/tests/Cache_Lite/Cache/tests/bench2.php   |   24 +
 lib/tests/Cache_Lite/Cache/tests/bench3.php   |   60 +
 .../Cache/tests/cache_lite_base.inc           |    6 +
 .../Cache/tests/cache_lite_file_base.inc      |    6 +
 .../Cache/tests/cache_lite_function_base.inc  |    6 +
 .../Cache/tests/cache_lite_output_base.inc    |    6 +
 .../Cache_Lite/Cache/tests/callcache.inc      |  149 +
 .../Cache_Lite/Cache/tests/pearbug13693.phpt  |   31 +
 .../Cache_Lite/Cache/tests/pearbug513.phpt    |   52 +
 .../Cache_Lite/Cache/tests/pearbug7618.phpt   |   39 +
 lib/tests/Cache_Lite/Cache/tests/tmpdir.inc   |   64 +
 .../HTTP_Request2/HTTP/tests/AllTests.php     |   79 +
 .../HTTP_Request2/HTTP/tests/ObserverTest.php |  120 +
 .../HTTP/tests/Request2/Adapter/AllTests.php  |   73 +
 .../HTTP/tests/Request2/Adapter/MockTest.php  |  147 +
 .../HTTP/tests/Request2/AllTests.php          |   77 +
 .../HTTP/tests/Request2/MultipartBodyTest.php |  109 +
 .../HTTP/tests/Request2/ResponseTest.php      |  149 +
 .../HTTP_Request2/HTTP/tests/Request2Test.php |  297 +
 .../HTTP_Request2/HTTP/tests/_files/bug_15305 |  Bin 0 -> 16338 bytes
 .../HTTP_Request2/HTTP/tests/_files/empty.gif |  Bin 0 -> 43 bytes
 .../HTTP/tests/_files/plaintext.txt           |    1 +
 .../HTTP/tests/_files/response_cookies        |   13 +
 .../HTTP/tests/_files/response_deflate        |  Bin 0 -> 1654 bytes
 .../HTTP/tests/_files/response_gzip           |  Bin 0 -> 1672 bytes
 .../HTTP/tests/_files/response_gzip_broken    |  Bin 0 -> 221 bytes
 .../HTTP/tests/_files/response_headers        |   12 +
 lib/tests/Structures_Graph/tests/README       |    0
 .../Structures_Graph/tests/all-tests.php      |   39 +
 .../tests/testCase/BasicGraph.php             |  182 +
 .../pear.unl.edu/BrowserTest.php              |   46 +
 .../UNL_Peoplefinder/pear.unl.edu/OUTest.php  |    3 +
 .../pear.unl.edu/PeoplefinderTest.php         |  232 +
 .../testStudentWithNoLocalAddress.html        |   18 +
 .../UNL_Templates/tests/UNL_TemplatesTest.php |  172 +
 lib/tests/XML_Util/XML/tests/AllTests.php     |  132 +
 .../XML/tests/testBasic_apiVersion.phpt       |   18 +
 .../tests/testBasic_attributesToString.phpt   |  118 +
 .../tests/testBasic_collapseEmptyTags.phpt    |   52 +
 .../tests/testBasic_createCDataSection.phpt   |   18 +
 .../XML/tests/testBasic_createComment.phpt    |   18 +
 .../XML/tests/testBasic_createEndElement.phpt |   24 +
 .../tests/testBasic_createStartElement.phpt   |  124 +
 .../XML/tests/testBasic_createTag.phpt        |  155 +
 .../tests/testBasic_createTagFromArray.phpt   |  203 +
 .../testBasic_getDocTypeDeclaration.phpt      |   44 +
 .../tests/testBasic_getXmlDeclaration.phpt    |   36 +
 .../XML/tests/testBasic_isValidName.phpt      |   46 +
 .../XML/tests/testBasic_raiseError.phpt       |   19 +
 .../XML/tests/testBasic_replaceEntities.phpt  |   82 +
 .../XML/tests/testBasic_reverseEntities.phpt  |   81 +
 .../tests/testBasic_splitQualifiedName.phpt   |   32 +
 .../XML_Util/XML/tests/testBug_4950.phpt      |   21 +
 .../XML_Util/XML/tests/testBug_5392.phpt      |   27 +
 lib/www/UNL_Peoplefinder/pear.unl.edu/README  |   19 +
 .../pear.unl.edu/advancedForm.php             |   19 +
 .../pear.unl.edu/apple-touch-icon.png         |  Bin 0 -> 5367 bytes
 .../pear.unl.edu/config-sample.inc.php        |   18 +
 .../pear.unl.edu/config.inc.php               |   15 +
 .../pear.unl.edu/departments/index.php        |   89 +
 .../pear.unl.edu/images/btn_back.gif          |    0
 .../pear.unl.edu/images/home.gif              |  Bin 0 -> 92 bytes
 .../pear.unl.edu/images/icon_question.gif     |  Bin 0 -> 85 bytes
 .../pear.unl.edu/images/mobile.gif            |  Bin 0 -> 90 bytes
 .../pear.unl.edu/images/person.gif            |  Bin 0 -> 124 bytes
 .../UNL_Peoplefinder/pear.unl.edu/index.php   |  141 +
 .../pear.unl.edu/peoplefinder.js              |   13 +
 .../pear.unl.edu/peoplefinder_default.css     |  139 +
 .../UNL_Peoplefinder/pear.unl.edu/service.php |  133 +
 .../pear.unl.edu/small_devices.css            |    4 +
 .../pear.unl.edu/standardForm.php             |   16 +
 378 files changed, 85550 insertions(+)
 create mode 100644 lib/.config
 create mode 100644 lib/.configsnapshots/configsnapshot-2010-01-27 10-05-56.xml
 create mode 100644 lib/.configsnapshots/configsnapshot-2010-01-27 10-08-35.xml
 create mode 100644 lib/.pear2registry
 create mode 100644 lib/.xmlregistry/channels/channel-__uri.xml
 create mode 100644 lib/.xmlregistry/channels/channel-doc.php.net.xml
 create mode 100644 lib/.xmlregistry/channels/channel-pear.php.net.xml
 create mode 100644 lib/.xmlregistry/channels/channel-pear.unl.edu.xml
 create mode 100644 lib/.xmlregistry/channels/channel-pear2.php.net.xml
 create mode 100644 lib/.xmlregistry/channels/channel-pecl.php.net.xml
 create mode 100644 lib/.xmlregistry/channels/channel-simplecas.googlecode.com##svn.xml
 create mode 100644 lib/.xmlregistry/channels/channelalias-__uri.txt
 create mode 100644 lib/.xmlregistry/channels/channelalias-pear.txt
 create mode 100644 lib/.xmlregistry/channels/channelalias-pear2.txt
 create mode 100644 lib/.xmlregistry/channels/channelalias-pecl.txt
 create mode 100644 lib/.xmlregistry/channels/channelalias-phpdocs.txt
 create mode 100644 lib/.xmlregistry/channels/channelalias-simplecas.txt
 create mode 100644 lib/.xmlregistry/channels/channelalias-unl.txt
 create mode 100644 lib/.xmlregistry/packages/pear.php.net/Archive_Tar/1.3.3-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.php.net/Cache_Lite/1.7.8-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.php.net/Console_Getopt/1.2.3-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.php.net/HTTP_Request2/0.5.1-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.php.net/PEAR/1.9.0-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.php.net/Structures_Graph/1.0.2-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.php.net/XML_Util/1.2.1-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.unl.edu/UNL_DWT/0.7.1-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.unl.edu/UNL_Peoplefinder/0.1.0-info.xml
 create mode 100644 lib/.xmlregistry/packages/pear.unl.edu/UNL_Templates/1.0.0RC9-info.xml
 create mode 100644 lib/.xmlregistry/packages/simplecas.googlecode.com!svn/SimpleCAS/0.5.0-info.xml
 create mode 100644 lib/data/PEAR/package.dtd
 create mode 100644 lib/data/PEAR/template.spec
 create mode 100644 lib/data/Structures_Graph/LICENSE
 create mode 100644 lib/data/Structures_Graph/genpackage.xml.pl
 create mode 100644 lib/data/Structures_Graph/package.sh
 create mode 100644 lib/data/Structures_Graph/publish.sh
 create mode 100644 lib/data/UNL_Peoplefinder/pear.unl.edu/hr_tree.xml
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version2/Document.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version2/Fixed.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version2/Liquid.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version2/Popup.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version2/Secure.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version2/Unlaffiliate.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version2/Unlframework.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version2/Unlstandardtemplate.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version3/Absolute.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version3/Debug.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version3/Document.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version3/Fixed.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version3/Liquid.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version3/Popup.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version3/Secure.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version3/Shared_column_left.tpl
 create mode 100644 lib/data/UNL_Templates/data/tpl_cache/Version3/Shared_column_right.tpl
 create mode 100644 lib/docs/Archive_Tar/docs/Archive_Tar.txt
 create mode 100644 lib/docs/Cache_Lite/Cache/LICENSE
 create mode 100644 lib/docs/Cache_Lite/Cache/TODO
 create mode 100644 lib/docs/Cache_Lite/Cache/docs/examples
 create mode 100644 lib/docs/Cache_Lite/Cache/docs/technical
 create mode 100644 lib/docs/Cache_Lite/Cache/tests/readme
 create mode 100644 lib/docs/HTTP_Request2/HTTP/docs/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/PEAR/INSTALL
 create mode 100644 lib/docs/PEAR/LICENSE
 create mode 100644 lib/docs/PEAR/README
 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/Structures_Graph/docs/generate.sh
 create mode 100644 lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Node.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Node_php.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_php.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/Structures_Graph/tutorial_Structures_Graph.pkg.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/classtrees_Structures_Graph.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/elementindex.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/elementindex_Structures_Graph.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/errors.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/index.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/li_Structures_Graph.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/media/banner.css
 create mode 100644 lib/docs/Structures_Graph/docs/html/media/stylesheet.css
 create mode 100644 lib/docs/Structures_Graph/docs/html/packages.html
 create mode 100644 lib/docs/Structures_Graph/docs/html/todolist.html
 create mode 100644 lib/docs/Structures_Graph/docs/tutorials/Structures_Graph/Structures_Graph.pkg
 create mode 100644 lib/docs/UNL_DWT/docs/examples/Template_style1.php
 create mode 100644 lib/docs/UNL_DWT/docs/examples/Template_style1.tpl
 create mode 100644 lib/docs/UNL_DWT/docs/examples/example.ini
 create mode 100644 lib/docs/UNL_DWT/docs/examples/example_style1.php
 create mode 100644 lib/docs/UNL_DWT/docs/examples/scanner_example.php
 create mode 100644 lib/docs/UNL_DWT/docs/examples/template_style1.dwt
 create mode 100644 lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/config.inc.php
 create mode 100644 lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getExactMatches.php
 create mode 100644 lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getLikeMatches.php
 create mode 100644 lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getUID.php
 create mode 100644 lib/docs/UNL_Templates/docs/examples/customization/CustomClass.php
 create mode 100644 lib/docs/UNL_Templates/docs/examples/customization/customization_example.html
 create mode 100644 lib/docs/UNL_Templates/docs/examples/customization/customization_example.php
 create mode 100644 lib/docs/UNL_Templates/docs/examples/example1.php
 create mode 100644 lib/docs/UNL_Templates/docs/examples/scanner.php
 create mode 100644 lib/docs/XML_Util/XML/examples/example.php
 create mode 100644 lib/docs/XML_Util/XML/examples/example2.php
 create mode 100644 lib/downloads/Archive_Tar-1.3.3.tgz
 create mode 100644 lib/downloads/Cache_Lite-1.7.8.tgz
 create mode 100644 lib/downloads/Console_Getopt-1.2.3.tgz
 create mode 100644 lib/downloads/HTTP_Request2-0.5.1.tgz
 create mode 100644 lib/downloads/Net_URL2-0.3.0.tgz
 create mode 100644 lib/downloads/Net_URL2-0.3.1.tgz
 create mode 100644 lib/downloads/PEAR-1.9.0.tgz
 create mode 100644 lib/downloads/SimpleCAS-0.5.0.tgz
 create mode 100644 lib/downloads/Structures_Graph-1.0.2.tgz
 create mode 100644 lib/downloads/UNL_DWT-0.7.1.tgz
 create mode 100644 lib/downloads/UNL_Templates-1.0.0RC9.tgz
 create mode 100644 lib/downloads/XML_Util-1.2.1.tgz
 create mode 100644 lib/php/Archive/Tar.php
 create mode 100644 lib/php/Cache/Lite.php
 create mode 100644 lib/php/Cache/Lite/File.php
 create mode 100644 lib/php/Cache/Lite/Function.php
 create mode 100644 lib/php/Cache/Lite/Output.php
 create mode 100644 lib/php/Console/Getopt.php
 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/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/OS/Guess.php
 create mode 100644 lib/php/PEAR.php
 create mode 100644 lib/php/PEAR/Autoloader.php
 create mode 100644 lib/php/PEAR/Builder.php
 create mode 100644 lib/php/PEAR/ChannelFile.php
 create mode 100644 lib/php/PEAR/ChannelFile/Parser.php
 create mode 100644 lib/php/PEAR/Command.php
 create mode 100644 lib/php/PEAR/Command/Auth.php
 create mode 100644 lib/php/PEAR/Command/Auth.xml
 create mode 100644 lib/php/PEAR/Command/Build.php
 create mode 100644 lib/php/PEAR/Command/Build.xml
 create mode 100644 lib/php/PEAR/Command/Channels.php
 create mode 100644 lib/php/PEAR/Command/Channels.xml
 create mode 100644 lib/php/PEAR/Command/Common.php
 create mode 100644 lib/php/PEAR/Command/Config.php
 create mode 100644 lib/php/PEAR/Command/Config.xml
 create mode 100644 lib/php/PEAR/Command/Install.php
 create mode 100644 lib/php/PEAR/Command/Install.xml
 create mode 100644 lib/php/PEAR/Command/Mirror.php
 create mode 100644 lib/php/PEAR/Command/Mirror.xml
 create mode 100644 lib/php/PEAR/Command/Package.php
 create mode 100644 lib/php/PEAR/Command/Package.xml
 create mode 100644 lib/php/PEAR/Command/Pickle.php
 create mode 100644 lib/php/PEAR/Command/Pickle.xml
 create mode 100644 lib/php/PEAR/Command/Registry.php
 create mode 100644 lib/php/PEAR/Command/Registry.xml
 create mode 100644 lib/php/PEAR/Command/Remote.php
 create mode 100644 lib/php/PEAR/Command/Remote.xml
 create mode 100644 lib/php/PEAR/Command/Test.php
 create mode 100644 lib/php/PEAR/Command/Test.xml
 create mode 100644 lib/php/PEAR/Common.php
 create mode 100644 lib/php/PEAR/Config.php
 create mode 100644 lib/php/PEAR/Dependency2.php
 create mode 100644 lib/php/PEAR/DependencyDB.php
 create mode 100644 lib/php/PEAR/Downloader.php
 create mode 100644 lib/php/PEAR/Downloader/Package.php
 create mode 100644 lib/php/PEAR/ErrorStack.php
 create mode 100644 lib/php/PEAR/Exception.php
 create mode 100644 lib/php/PEAR/FixPHP5PEARWarnings.php
 create mode 100644 lib/php/PEAR/Frontend.php
 create mode 100644 lib/php/PEAR/Frontend/CLI.php
 create mode 100644 lib/php/PEAR/Installer.php
 create mode 100644 lib/php/PEAR/Installer/Role.php
 create mode 100644 lib/php/PEAR/Installer/Role/Cfg.php
 create mode 100644 lib/php/PEAR/Installer/Role/Cfg.xml
 create mode 100644 lib/php/PEAR/Installer/Role/Common.php
 create mode 100644 lib/php/PEAR/Installer/Role/Data.php
 create mode 100644 lib/php/PEAR/Installer/Role/Data.xml
 create mode 100644 lib/php/PEAR/Installer/Role/Doc.php
 create mode 100644 lib/php/PEAR/Installer/Role/Doc.xml
 create mode 100644 lib/php/PEAR/Installer/Role/Ext.php
 create mode 100644 lib/php/PEAR/Installer/Role/Ext.xml
 create mode 100644 lib/php/PEAR/Installer/Role/Php.php
 create mode 100644 lib/php/PEAR/Installer/Role/Php.xml
 create mode 100644 lib/php/PEAR/Installer/Role/Script.php
 create mode 100644 lib/php/PEAR/Installer/Role/Script.xml
 create mode 100644 lib/php/PEAR/Installer/Role/Src.php
 create mode 100644 lib/php/PEAR/Installer/Role/Src.xml
 create mode 100644 lib/php/PEAR/Installer/Role/Test.php
 create mode 100644 lib/php/PEAR/Installer/Role/Test.xml
 create mode 100644 lib/php/PEAR/Installer/Role/Www.php
 create mode 100644 lib/php/PEAR/Installer/Role/Www.xml
 create mode 100644 lib/php/PEAR/PackageFile.php
 create mode 100644 lib/php/PEAR/PackageFile/Generator/v1.php
 create mode 100644 lib/php/PEAR/PackageFile/Generator/v2.php
 create mode 100644 lib/php/PEAR/PackageFile/Parser/v1.php
 create mode 100644 lib/php/PEAR/PackageFile/Parser/v2.php
 create mode 100644 lib/php/PEAR/PackageFile/v1.php
 create mode 100644 lib/php/PEAR/PackageFile/v2.php
 create mode 100644 lib/php/PEAR/PackageFile/v2/Validator.php
 create mode 100644 lib/php/PEAR/PackageFile/v2/rw.php
 create mode 100644 lib/php/PEAR/Packager.php
 create mode 100644 lib/php/PEAR/REST.php
 create mode 100644 lib/php/PEAR/REST/10.php
 create mode 100644 lib/php/PEAR/REST/11.php
 create mode 100644 lib/php/PEAR/REST/13.php
 create mode 100644 lib/php/PEAR/Registry.php
 create mode 100644 lib/php/PEAR/RunTest.php
 create mode 100644 lib/php/PEAR/Task/Common.php
 create mode 100644 lib/php/PEAR/Task/Postinstallscript.php
 create mode 100644 lib/php/PEAR/Task/Postinstallscript/rw.php
 create mode 100644 lib/php/PEAR/Task/Replace.php
 create mode 100644 lib/php/PEAR/Task/Replace/rw.php
 create mode 100644 lib/php/PEAR/Task/Unixeol.php
 create mode 100644 lib/php/PEAR/Task/Unixeol/rw.php
 create mode 100644 lib/php/PEAR/Task/Windowseol.php
 create mode 100644 lib/php/PEAR/Task/Windowseol/rw.php
 create mode 100644 lib/php/PEAR/Validate.php
 create mode 100644 lib/php/PEAR/Validator/PECL.php
 create mode 100644 lib/php/PEAR/XMLParser.php
 create mode 100644 lib/php/PEAR5.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/Structures/Graph.php
 create mode 100644 lib/php/Structures/Graph/Manipulator/AcyclicTest.php
 create mode 100644 lib/php/Structures/Graph/Manipulator/TopologicalSorter.php
 create mode 100644 lib/php/Structures/Graph/Node.php
 create mode 100644 lib/php/System.php
 create mode 100644 lib/php/UNL/DWT.php
 create mode 100644 lib/php/UNL/DWT/Generator.php
 create mode 100644 lib/php/UNL/DWT/Region.php
 create mode 100644 lib/php/UNL/DWT/Scanner.php
 create mode 100644 lib/php/UNL/DWT/createTemplates.php
 create mode 100644 lib/php/UNL/Peoplefinder.php
 create mode 100644 lib/php/UNL/Peoplefinder/Department.php
 create mode 100644 lib/php/UNL/Peoplefinder/Department/Search.php
 create mode 100644 lib/php/UNL/Peoplefinder/Driver/LDAP.php
 create mode 100644 lib/php/UNL/Peoplefinder/Driver/LDAP/AdvancedFilter.php
 create mode 100644 lib/php/UNL/Peoplefinder/Driver/LDAP/OUFilter.php
 create mode 100644 lib/php/UNL/Peoplefinder/Driver/LDAP/StandardFilter.php
 create mode 100644 lib/php/UNL/Peoplefinder/Driver/LDAP/TelephoneFilter.php
 create mode 100644 lib/php/UNL/Peoplefinder/Driver/LDAP/Util.php
 create mode 100644 lib/php/UNL/Peoplefinder/Driver/WebService.php
 create mode 100644 lib/php/UNL/Peoplefinder/DriverInterface.php
 create mode 100644 lib/php/UNL/Peoplefinder/Record.php
 create mode 100644 lib/php/UNL/Peoplefinder/Renderer/HTML.php
 create mode 100644 lib/php/UNL/Peoplefinder/Renderer/JSON.php
 create mode 100644 lib/php/UNL/Peoplefinder/Renderer/Serialized.php
 create mode 100644 lib/php/UNL/Peoplefinder/Renderer/XML.php
 create mode 100644 lib/php/UNL/Peoplefinder/Renderer/vCard.php
 create mode 100644 lib/php/UNL/Peoplefinder/RendererInterface.php
 create mode 100644 lib/php/UNL/Templates.php
 create mode 100644 lib/php/UNL/Templates/CachingService.php
 create mode 100644 lib/php/UNL/Templates/CachingService/CacheLite.php
 create mode 100644 lib/php/UNL/Templates/Scanner.php
 create mode 100644 lib/php/UNL/Templates/Version.php
 create mode 100644 lib/php/UNL/Templates/Version2.php
 create mode 100644 lib/php/UNL/Templates/Version2/Document.php
 create mode 100644 lib/php/UNL/Templates/Version2/Fixed.php
 create mode 100644 lib/php/UNL/Templates/Version2/Liquid.php
 create mode 100644 lib/php/UNL/Templates/Version2/Popup.php
 create mode 100644 lib/php/UNL/Templates/Version2/Secure.php
 create mode 100644 lib/php/UNL/Templates/Version2/Unlaffiliate.php
 create mode 100644 lib/php/UNL/Templates/Version2/Unlframework.php
 create mode 100644 lib/php/UNL/Templates/Version2/Unlstandardtemplate.php
 create mode 100644 lib/php/UNL/Templates/Version3.php
 create mode 100644 lib/php/UNL/Templates/Version3/Absolute.php
 create mode 100644 lib/php/UNL/Templates/Version3/Debug.php
 create mode 100644 lib/php/UNL/Templates/Version3/Document.php
 create mode 100644 lib/php/UNL/Templates/Version3/Fixed.php
 create mode 100644 lib/php/UNL/Templates/Version3/Liquid.php
 create mode 100644 lib/php/UNL/Templates/Version3/Popup.php
 create mode 100644 lib/php/UNL/Templates/Version3/Secure.php
 create mode 100644 lib/php/UNL/Templates/Version3/Shared_column_left.php
 create mode 100644 lib/php/UNL/Templates/Version3/Shared_column_right.php
 create mode 100644 lib/php/XML/Util.php
 create mode 100644 lib/php/pearcmd.php
 create mode 100644 lib/php/peclcmd.php
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_File_classical.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_classical.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_dontcache.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_drop.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Output_classical.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_automaticCleaning.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_classical.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error2.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error3.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_eternal.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_fatest.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_hashed.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_lifetime.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_memorycache.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/Cache_Lite_serialization.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/bench.php
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/bench2.php
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/bench3.php
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/cache_lite_base.inc
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/cache_lite_file_base.inc
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/cache_lite_function_base.inc
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/cache_lite_output_base.inc
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/callcache.inc
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/pearbug13693.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/pearbug513.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/pearbug7618.phpt
 create mode 100644 lib/tests/Cache_Lite/Cache/tests/tmpdir.inc
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/AllTests.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/ObserverTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/Request2/Adapter/AllTests.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/Request2/Adapter/MockTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/Request2/AllTests.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/Request2/MultipartBodyTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/Request2/ResponseTest.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/Request2Test.php
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/_files/bug_15305
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/_files/empty.gif
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/_files/plaintext.txt
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/_files/response_cookies
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/_files/response_deflate
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/_files/response_gzip
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/_files/response_gzip_broken
 create mode 100644 lib/tests/HTTP_Request2/HTTP/tests/_files/response_headers
 create mode 100644 lib/tests/Structures_Graph/tests/README
 create mode 100644 lib/tests/Structures_Graph/tests/all-tests.php
 create mode 100644 lib/tests/Structures_Graph/tests/testCase/BasicGraph.php
 create mode 100644 lib/tests/UNL_Peoplefinder/pear.unl.edu/BrowserTest.php
 create mode 100644 lib/tests/UNL_Peoplefinder/pear.unl.edu/OUTest.php
 create mode 100644 lib/tests/UNL_Peoplefinder/pear.unl.edu/PeoplefinderTest.php
 create mode 100644 lib/tests/UNL_Peoplefinder/pear.unl.edu/testStudentWithNoLocalAddress.html
 create mode 100644 lib/tests/UNL_Templates/tests/UNL_TemplatesTest.php
 create mode 100644 lib/tests/XML_Util/XML/tests/AllTests.php
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_apiVersion.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_attributesToString.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_collapseEmptyTags.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_createCDataSection.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_createComment.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_createEndElement.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_createStartElement.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_createTag.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_createTagFromArray.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_getDocTypeDeclaration.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_getXmlDeclaration.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_isValidName.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_raiseError.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_replaceEntities.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_reverseEntities.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBasic_splitQualifiedName.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBug_4950.phpt
 create mode 100644 lib/tests/XML_Util/XML/tests/testBug_5392.phpt
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/README
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/advancedForm.php
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/apple-touch-icon.png
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/config-sample.inc.php
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/config.inc.php
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/departments/index.php
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/images/btn_back.gif
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/images/home.gif
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/images/icon_question.gif
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/images/mobile.gif
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/images/person.gif
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/index.php
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/peoplefinder.js
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/peoplefinder_default.css
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/service.php
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/small_devices.css
 create mode 100644 lib/www/UNL_Peoplefinder/pear.unl.edu/standardForm.php

diff --git a/lib/.config b/lib/.config
new file mode 100644
index 00000000..c2f90e11
--- /dev/null
+++ b/lib/.config
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<pearconfig version="1.0"><ext_dir>/usr/local/lib/php/extensions/no-debug-non-zts-20090626/</ext_dir><cfg_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/cfg</cfg_dir><doc_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/docs</doc_dir><bin_dir>/Users/bbieber/workspace/UNL_Elgg/lib/bin</bin_dir><www_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/www</www_dir><test_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/tests</test_dir><src_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/src</src_dir><php_bin>/usr/local/bin/php</php_bin><php_ini>/usr/local/lib/php.ini</php_ini><php_prefix></php_prefix><php_suffix></php_suffix></pearconfig>
diff --git a/lib/.configsnapshots/configsnapshot-2010-01-27 10-05-56.xml b/lib/.configsnapshots/configsnapshot-2010-01-27 10-05-56.xml
new file mode 100644
index 00000000..7c345a91
--- /dev/null
+++ b/lib/.configsnapshots/configsnapshot-2010-01-27 10-05-56.xml	
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<pearconfig version="1.0"><php_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/php</php_dir><ext_dir>/usr/local/lib/php/extensions/no-debug-non-zts-20090626/</ext_dir><cfg_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/cfg</cfg_dir><doc_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/docs</doc_dir><bin_dir>/usr/local/bin</bin_dir><data_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/data</data_dir><www_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/www</www_dir><test_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/tests</test_dir><src_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/src</src_dir><php_bin>/usr/local/bin/php</php_bin><php_ini>/usr/local/lib/php.ini</php_ini><php_prefix></php_prefix><php_suffix></php_suffix></pearconfig>
diff --git a/lib/.configsnapshots/configsnapshot-2010-01-27 10-08-35.xml b/lib/.configsnapshots/configsnapshot-2010-01-27 10-08-35.xml
new file mode 100644
index 00000000..3c880872
--- /dev/null
+++ b/lib/.configsnapshots/configsnapshot-2010-01-27 10-08-35.xml	
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<pearconfig version="1.0"><php_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/php</php_dir><ext_dir>/usr/local/lib/php/extensions/no-debug-non-zts-20090626/</ext_dir><cfg_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/cfg</cfg_dir><doc_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/docs</doc_dir><bin_dir>/Users/bbieber/workspace/UNL_Elgg/lib/bin</bin_dir><data_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/data</data_dir><www_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/www</www_dir><test_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/tests</test_dir><src_dir>/Users/bbieber/Documents/workspace/UNL_Elgg/lib/src</src_dir><php_bin>/usr/local/bin/php</php_bin><php_ini>/usr/local/lib/php.ini</php_ini><php_prefix></php_prefix><php_suffix></php_suffix></pearconfig>
diff --git a/lib/.pear2registry b/lib/.pear2registry
new file mode 100644
index 0000000000000000000000000000000000000000..f1a18171f6e65c0ce4cc073126812778b1760c3e
GIT binary patch
literal 326656
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
YzNTV%gorkX1Fre13$7>y%G1#KAE-i0@&Et;

literal 0
HcmV?d00001

diff --git a/lib/.xmlregistry/channels/channel-__uri.xml b/lib/.xmlregistry/channels/channel-__uri.xml
new file mode 100644
index 00000000..987a5938
--- /dev/null
+++ b/lib/.xmlregistry/channels/channel-__uri.xml
@@ -0,0 +1,13 @@
+<?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>__uri</name>
+ <suggestedalias>__uri</suggestedalias>
+ <summary>Pseudo-channel for static packages</summary>
+ <servers>
+  <primary>
+   <xmlrpc>
+    <function version="1.0">****</function>
+   </xmlrpc>
+  </primary>
+ </servers>
+</channel>
diff --git a/lib/.xmlregistry/channels/channel-doc.php.net.xml b/lib/.xmlregistry/channels/channel-doc.php.net.xml
new file mode 100644
index 00000000..d221a21b
--- /dev/null
+++ b/lib/.xmlregistry/channels/channel-doc.php.net.xml
@@ -0,0 +1,14 @@
+<?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>doc.php.net</name>
+ <summary>PHP Documentation team</summary>
+ <suggestedalias>phpdocs</suggestedalias>
+ <servers>
+  <primary>
+   <rest>
+    <baseurl type="REST1.0">http://doc.php.net/rest/</baseurl>
+    <baseurl type="REST1.1">http://doc.php.net/rest/</baseurl>
+   </rest>
+  </primary>
+ </servers>
+</channel>
diff --git a/lib/.xmlregistry/channels/channel-pear.php.net.xml b/lib/.xmlregistry/channels/channel-pear.php.net.xml
new file mode 100644
index 00000000..c7098913
--- /dev/null
+++ b/lib/.xmlregistry/channels/channel-pear.php.net.xml
@@ -0,0 +1,32 @@
+<?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>pear.php.net</name>
+ <suggestedalias>pear</suggestedalias>
+ <summary>PHP Extension and Application Repository</summary>
+ <servers>
+  <primary>
+   <rest>
+    <baseurl type="REST1.0">http://pear.php.net/rest/</baseurl>
+    <baseurl type="REST1.1">http://pear.php.net/rest/</baseurl>
+    <baseurl type="REST1.2">http://pear.php.net/rest/</baseurl>
+    <baseurl type="REST1.3">http://pear.php.net/rest/</baseurl>
+   </rest>
+  </primary>
+  <mirror host="us.pear.php.net">
+   <rest>
+    <baseurl type="REST1.0">http://us.pear.php.net/rest/</baseurl>
+    <baseurl type="REST1.1">http://us.pear.php.net/rest/</baseurl>
+    <baseurl type="REST1.2">http://us.pear.php.net/rest/</baseurl>
+    <baseurl type="REST1.3">http://us.pear.php.net/rest/</baseurl>
+   </rest>
+  </mirror>
+  <mirror host="de.pear.php.net" ssl="yes" port="3452">
+   <rest>
+    <baseurl type="REST1.0">https://de.pear.php.net:3452/rest/</baseurl>
+    <baseurl type="REST1.1">https://de.pear.php.net:3452/rest/</baseurl>
+    <baseurl type="REST1.2">https://de.pear.php.net:3452/rest/</baseurl>
+    <baseurl type="REST1.3">https://de.pear.php.net:3452/rest/</baseurl>
+   </rest>
+  </mirror>
+ </servers>
+</channel>
diff --git a/lib/.xmlregistry/channels/channel-pear.unl.edu.xml b/lib/.xmlregistry/channels/channel-pear.unl.edu.xml
new file mode 100644
index 00000000..54bc5112
--- /dev/null
+++ b/lib/.xmlregistry/channels/channel-pear.unl.edu.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>pear.unl.edu</name>
+ <summary>UNL PHP Extension and Application Repository</summary>
+ <suggestedalias>unl</suggestedalias>
+ <servers>
+  <primary>
+   <rest>
+    <baseurl type="REST1.0">http://pear.unl.edu/Chiara_PEAR_Server_REST/</baseurl>
+    <baseurl type="REST1.1">http://pear.unl.edu/Chiara_PEAR_Server_REST/</baseurl>
+    <baseurl type="REST1.3">http://pear.unl.edu/Chiara_PEAR_Server_REST/</baseurl>
+   </rest>
+  </primary>
+ </servers>
+</channel>
diff --git a/lib/.xmlregistry/channels/channel-pear2.php.net.xml b/lib/.xmlregistry/channels/channel-pear2.php.net.xml
new file mode 100644
index 00000000..dbcaccb2
--- /dev/null
+++ b/lib/.xmlregistry/channels/channel-pear2.php.net.xml
@@ -0,0 +1,16 @@
+<?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>pear2.php.net</name>
+ <suggestedalias>pear2</suggestedalias>
+ <summary>PEAR packages for PHP 5.3+ installed by Pyrus</summary>
+ <servers>
+  <primary>
+   <rest>
+    <baseurl type="REST1.0">http://pear2.php.net/rest/</baseurl>
+    <baseurl type="REST1.1">http://pear2.php.net/rest/</baseurl>
+    <baseurl type="REST1.2">http://pear2.php.net/rest/</baseurl>
+    <baseurl type="REST1.3">http://pear2.php.net/rest/</baseurl>
+   </rest>
+  </primary>
+ </servers>
+</channel>
diff --git a/lib/.xmlregistry/channels/channel-pecl.php.net.xml b/lib/.xmlregistry/channels/channel-pecl.php.net.xml
new file mode 100644
index 00000000..cd6b257f
--- /dev/null
+++ b/lib/.xmlregistry/channels/channel-pecl.php.net.xml
@@ -0,0 +1,25 @@
+<?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>pecl.php.net</name>
+ <suggestedalias>pecl</suggestedalias>
+ <summary>PHP Extension Community Library</summary>
+ <validatepackage version="1.0">PEAR_Validator_PECL</validatepackage>
+ <servers>
+  <primary>
+   <xmlrpc>
+    <function version="1.0">logintest</function>
+    <function version="1.0">package.listLatestReleases</function>
+    <function version="1.0">package.listAll</function>
+    <function version="1.0">package.info</function>
+    <function version="1.0">package.getDownloadURL</function>
+    <function version="1.0">package.getDepDownloadURL</function>
+    <function version="1.0">package.search</function>
+    <function version="1.0">channel.listAll</function>
+   </xmlrpc>
+   <rest>
+    <baseurl type="REST1.0">http://pecl.php.net/rest/</baseurl>
+    <baseurl type="REST1.1">http://pecl.php.net/rest/</baseurl>
+   </rest>
+  </primary>
+ </servers>
+</channel>
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 00000000..dc7b7148
--- /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-__uri.txt b/lib/.xmlregistry/channels/channelalias-__uri.txt
new file mode 100644
index 00000000..9e550d04
--- /dev/null
+++ b/lib/.xmlregistry/channels/channelalias-__uri.txt
@@ -0,0 +1 @@
+__uri
\ No newline at end of file
diff --git a/lib/.xmlregistry/channels/channelalias-pear.txt b/lib/.xmlregistry/channels/channelalias-pear.txt
new file mode 100644
index 00000000..f4730b99
--- /dev/null
+++ b/lib/.xmlregistry/channels/channelalias-pear.txt
@@ -0,0 +1 @@
+pear.php.net
\ No newline at end of file
diff --git a/lib/.xmlregistry/channels/channelalias-pear2.txt b/lib/.xmlregistry/channels/channelalias-pear2.txt
new file mode 100644
index 00000000..7911749f
--- /dev/null
+++ b/lib/.xmlregistry/channels/channelalias-pear2.txt
@@ -0,0 +1 @@
+pear2.php.net
\ No newline at end of file
diff --git a/lib/.xmlregistry/channels/channelalias-pecl.txt b/lib/.xmlregistry/channels/channelalias-pecl.txt
new file mode 100644
index 00000000..2de48f1b
--- /dev/null
+++ b/lib/.xmlregistry/channels/channelalias-pecl.txt
@@ -0,0 +1 @@
+pecl.php.net
\ No newline at end of file
diff --git a/lib/.xmlregistry/channels/channelalias-phpdocs.txt b/lib/.xmlregistry/channels/channelalias-phpdocs.txt
new file mode 100644
index 00000000..1e733d9c
--- /dev/null
+++ b/lib/.xmlregistry/channels/channelalias-phpdocs.txt
@@ -0,0 +1 @@
+doc.php.net
\ No newline at end of file
diff --git a/lib/.xmlregistry/channels/channelalias-simplecas.txt b/lib/.xmlregistry/channels/channelalias-simplecas.txt
new file mode 100644
index 00000000..fdae4898
--- /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/channels/channelalias-unl.txt b/lib/.xmlregistry/channels/channelalias-unl.txt
new file mode 100644
index 00000000..674f0120
--- /dev/null
+++ b/lib/.xmlregistry/channels/channelalias-unl.txt
@@ -0,0 +1 @@
+pear.unl.edu
\ No newline at end of file
diff --git a/lib/.xmlregistry/packages/pear.php.net/Archive_Tar/1.3.3-info.xml b/lib/.xmlregistry/packages/pear.php.net/Archive_Tar/1.3.3-info.xml
new file mode 100644
index 00000000..f1f3100d
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/Archive_Tar/1.3.3-info.xml
@@ -0,0 +1,248 @@
+<?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.8.0RC1" 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>Archive_Tar</name>
+ <channel>pear.php.net</channel>
+ <summary>Tar file management class</summary>
+ <description>This class provides handling of tar files in PHP.
+It supports creating, listing, extracting and adding to tar files.
+Gzip support is available if PHP has the zlib extension built-in or
+loaded. Bz2 compression is also supported with the bz2 extension loaded.</description>
+ <lead>
+  <name>Gregory Beaver</name>
+  <user>cellog</user>
+  <email>cellog@php.net</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Vincent Blavet</name>
+  <user>vblavet</user>
+  <email>vincent@phpconcept.net</email>
+  <active>no</active>
+ </lead>
+ <helper>
+  <name>Stig Bakken</name>
+  <user>ssb</user>
+  <email>stig@php.net</email>
+  <active>no</active>
+ </helper>
+ <date>2010-01-27</date>
+ <time>10:08:51</time>
+ <version>
+  <release>1.3.3</release>
+  <api>1.3.1</api>
+ </version>
+ <stability>
+  <release>stable</release>
+  <api>stable</api>
+ </stability>
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
+ <notes>
+Change the license to New BSD license
+
+   minor bugfix release
+   * fix Bug #9921 compression with bzip2 fails [cellog]
+   * fix Bug #11594 _readLongHeader leaves 0 bytes in filename [jamessas]
+   * fix Bug #11769 Incorrect symlink handing [fajar99]
+ </notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="/" md5sum="29b03715377b18b1fafcff98a99cc9a7" name="docs/Archive_Tar.txt" role="doc"/>
+   <file baseinstalldir="/" md5sum="d6c6633566e7484aff188f798529b061" name="Archive/Tar.php" role="php"/>
+  </dir>
+ </contents>
+ <compatible>
+  <name>PEAR</name>
+  <channel>pear.php.net</channel>
+  <min>1.4.0</min>
+  <max>1.5.0RC2</max>
+ </compatible>
+ <dependencies>
+  <required>
+   <php>
+    <min>4.3.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.5.4</min>
+   </pearinstaller>
+  </required>
+ </dependencies>
+ <phprelease>
+  <changelog>
+   <release>
+    <version>
+     <release>1.3.2</release>
+     <api>1.3.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2007-01-03</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Correct Bug #4016
+Remove duplicate remove error display with '@'
+Correct Bug #3909 : Check existence of OS_WINDOWS constant
+Correct Bug #5452 fix for &quot;lone zero block&quot; when untarring packages
+Change filemode (from pear-core/Archive/Tar.php v.1.21)
+Correct Bug #6486 Can not extract symlinks
+Correct Bug #6933 Archive_Tar (Tar file management class) Directory traversal
+Correct Bug #8114 Files added on-the-fly not storing date
+Correct Bug #9352 Bug on _dirCheck function over nfs path
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.3.1</release>
+     <api>1.3.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2005-03-17</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Correct Bug #3855
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.3.0</release>
+     <api>1.3.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2005-03-06</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Bugs correction (2475, 2488, 2135, 2176)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.2</release>
+     <api>1.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2004-05-08</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Add support for other separator than the space char and bug
+	correction
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.1</release>
+     <api>1.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-05-28</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+* Add support for BZ2 compression
+* Add support for add and extract without using temporary files : methods addString() and extractInString()
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0</release>
+     <api>1.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-01-24</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Change status to stable
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.10-b1</release>
+     <api>0.10-b1</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2003-01-08</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Add support for long filenames (greater than 99 characters)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.9</release>
+     <api>0.9</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2002-05-27</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Auto-detect gzip'ed files
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.4</release>
+     <api>0.4</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2002-05-20</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Windows bugfix: use forward slashes inside archives
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.2</release>
+     <api>0.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2002-02-18</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+From initial commit to stable
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.3</release>
+     <api>0.3</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2002-04-13</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Windows bugfix: used wrong directory separators
+   </notes>
+   </release>
+  </changelog>
+ </phprelease>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.php.net/Cache_Lite/1.7.8-info.xml b/lib/.xmlregistry/packages/pear.php.net/Cache_Lite/1.7.8-info.xml
new file mode 100644
index 00000000..bf234309
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/Cache_Lite/1.7.8-info.xml
@@ -0,0 +1,671 @@
+<?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.8.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>Cache_Lite</name>
+ <channel>pear.php.net</channel>
+ <summary>Fast and Safe little cache system</summary>
+ <description>This package is a little cache system optimized for file containers. It is fast and safe (because it uses file locking and/or anti-corruption tests).</description>
+ <lead>
+  <name>Fabien MARTY</name>
+  <user>fab</user>
+  <email>fab@php.net</email>
+  <active>no</active>
+ </lead>
+ <lead>
+  <name>Markus Tacker</name>
+  <user>tacker</user>
+  <email>tacker@php.net</email>
+  <active>yes</active>
+ </lead>
+ <date>2010-01-27</date>
+ <time>10:09:00</time>
+ <version>
+  <release>1.7.8</release>
+  <api>1.7.7</api>
+ </version>
+ <stability>
+  <release>stable</release>
+  <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+ <notes>
+- Fixing definition of Cache_Lite_File::get(). See Bug #15986.
+ </notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="Cache" md5sum="4c638b951a7c8a4dcb94f10abf1d818b" name="TODO" role="doc"/>
+   <file baseinstalldir="Cache" md5sum="b59be5741e8f3ee07fc1d077c9018ae3" name="tests/tmpdir.inc" role="test"/>
+   <file baseinstalldir="Cache" md5sum="f7a9487bf565e79860114dac982848c5" name="tests/readme" role="doc"/>
+   <file baseinstalldir="Cache" md5sum="3bc88b43e4a320d5a5cab8a6cc50e3cb" name="tests/pearbug13693.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="ce290cff1c6d59f355af2fd24264fb3f" name="tests/pearbug7618.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="0055a5b3f32732ed93eb1d35da967d15" name="tests/pearbug513.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="1a49f54c490135ea472c831750458a92" name="tests/callcache.inc" role="test"/>
+   <file baseinstalldir="Cache" md5sum="21d2f81e4eca52e62d6ff5d627279358" name="tests/Cache_Lite_serialization.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="912efc43bb996181572015e019802f03" name="tests/Cache_Lite_Output_classical.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="90e87442db22f9aae9cc987366616381" name="tests/cache_lite_output_base.inc" role="test"/>
+   <file baseinstalldir="Cache" md5sum="0bbbee2deb4df646b16034ccf128ccbd" name="tests/Cache_Lite_memorycache.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="c0cebda77abb8bec1fcb8a9d66ae0742" name="tests/Cache_Lite_lifetime.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="a744ad847aa90ab010217f36a4b02a73" name="tests/Cache_Lite_hashed.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="5e796fdaf0a7b06e229bdc2057bbb459" name="tests/Cache_Lite_Function_drop.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="5c8fbf9a55fe0e62c543ba537b51ba86" name="tests/Cache_Lite_Function_dontcache.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="58e15eced32aaed91afa7b8c2985e7aa" name="tests/Cache_Lite_Function_classical.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="38b9d571d4e216c79ba682f29e1e2d37" name="tests/cache_lite_function_base.inc" role="test"/>
+   <file baseinstalldir="Cache" md5sum="985482fedda364c2b4f166183e1dd9b4" name="tests/Cache_Lite_File_classical.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="fc9d144785e80a4fca49e241c059de2f" name="tests/cache_lite_file_base.inc" role="test"/>
+   <file baseinstalldir="Cache" md5sum="198f6f9142051df39d9f70e6c9a0b635" name="tests/Cache_Lite_fatest.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="71d8c3bbeb65faff31ee6822391e2744" name="tests/Cache_Lite_eternal.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="554b773f3677d0a64e61e0e4c97ebab1" name="tests/Cache_Lite_error3.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="1d7dc15b1621f98e920a0331ed01fb3c" name="tests/Cache_Lite_error2.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="005a0b4093a22454152b10c5b3a5531a" name="tests/Cache_Lite_error.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="02a3c6ac536076fc77810b843e4a6212" name="tests/Cache_Lite_classical.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="4cfa4bd099dfb552bb6cbfad3e62f12e" name="tests/cache_lite_base.inc" role="test"/>
+   <file baseinstalldir="Cache" md5sum="710f77b0ed753a42a49aad8b779ee18c" name="tests/Cache_Lite_automaticCleaning.phpt" role="test"/>
+   <file baseinstalldir="Cache" md5sum="209c403db75cce49715f4b8e7f16969b" name="tests/bench3.php" role="test"/>
+   <file baseinstalldir="Cache" md5sum="2b5c37b7a863a245a19fd90042b2f147" name="tests/bench2.php" role="test"/>
+   <file baseinstalldir="Cache" md5sum="59e7508427cab7d47b1b62bc07936a93" name="tests/bench.php" role="test"/>
+   <file baseinstalldir="Cache" md5sum="c41b74345fc8b619981af02d047df8c5" name="Lite/Output.php" role="php"/>
+   <file baseinstalldir="Cache" md5sum="0aaaf33889734aff7a04092704824f0f" name="Lite/Function.php" role="php"/>
+   <file baseinstalldir="Cache" md5sum="dd0d4f396cde22cd6270cbb21f632b76" name="Lite/File.php" role="php"/>
+   <file baseinstalldir="Cache" md5sum="79051bf9a99e556432e01076a0d779ee" name="Lite.php" role="php"/>
+   <file baseinstalldir="Cache" md5sum="085e7fb76fb3fa8ba9e9ed0ce95a43f9" name="LICENSE" role="doc"/>
+   <file baseinstalldir="Cache" md5sum="934071f21c17611811e01396ca604c79" name="docs/technical" role="doc"/>
+   <file baseinstalldir="Cache" md5sum="1eb8d968a8b40bebf9b580782fe0a3a7" name="docs/examples" role="doc"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>4.0.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.5.4</min>
+   </pearinstaller>
+   <package>
+    <name>PEAR</name>
+    <channel>pear.php.net</channel>
+   </package>
+  </required>
+ </dependencies>
+ <phprelease>
+  <changelog>
+   <release>
+    <date>2009-07-07</date>
+    <time>00:00:00</time>
+    <version>
+     <release>1.7.8</release>
+     <api>1.7.7</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+- Set magic quotes runtime only if needed. See Bug #15725.
+   </notes>
+   </release>
+   <release>
+    <date>2009-03-07</date>
+    <time>00:00:00</time>
+    <version>
+     <release>1.7.7</release>
+     <api>1.7.7</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+- Fixing definition of Cache_Lite_File::get(). See Bug #15986.
+   </notes>
+   </release>
+   <release>
+    <date>2009-01-25</date>
+    <time>00:00:00</time>
+    <version>
+     <release>1.7.6</release>
+     <api>1.7.4</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+- Changed PEAR dependency to 1.5.4. See http://pear.php.net/advisory-20070507.txt
+   </notes>
+   </release>
+   <release>
+    <date>2009-01-13</date>
+    <version>
+     <release>1.7.5</release>
+     <api>1.7.4</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+- Bug #7446 - use time() instead if mktime() to prevent a strict error beeing raised.
+- Request #11766 - Use mt_rand() instead of rand()
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.7.4</release>
+     <api>1.7.4</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2008-06-08</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Implemented feature request:
+            - #13693 Added new option to Cache_Lite::remove() to check for non-existing cache files.
+            - Added unit test file for Bug #13693
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.7.3</release>
+     <api>1.7.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2008-04-13</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Bugs fixed :
+            - #11224 Fixed improper use of strpos
+            - #11260 Fixed improper use of internal property resulting in memory cache not beeing saved
+            - #12750 Fxied internal cleaning routine
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.7.2</release>
+     <api>1.7.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2006-06-03</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Bugs fixed :
+            - #7799 : setToDebug() doesn't work
+            - #7732 (or #7598) : hashedDirectory refactoring to get rid of some warnings (in some particular cases)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.7.1</release>
+     <api>1.7.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2006-05-14</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Bugs fixed :
+- #7618 : can't save cache correctly (in some particular cases)
+    (thanks to neta-master at ywcafe dot net)
+Other changes :
+- new unit test file (about bug #7618)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.7.0</release>
+     <api>1.7.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2006-02-21</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+No change (just some modifications into online documentation)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.7.0beta2</release>
+     <api>1.7.0beta2</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2006-02-04</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Bugs fixed :
+- 3 unit test files was forgotten in beta1 package.xml    
+New features :
+- request #6681 : new extendLife() method (thanks to alex at vegagames dot net)
+- request #6617 : &quot;$this-&gt;method()&quot; calls are ok with Cache_Lite_Function without workaround 
+                                    (thanks to thomas dot nicolai at unisg dot ch)
+- request #6575 : new options 'dontCacheWhenTheOutputContainsNOCACHE', 'dontCacheWhenTheResultIsFalse', 
+                                    'dontCacheWhenTheResultIsNull' (thanks to thomas dot nicolai at unisg dot ch)
+- new debug option for Cache_Lite_Function                                 
+- new test files
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.7.0beta1</release>
+     <api>1.7.0beta1</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2006-01-29</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+New features :
+- 3 new unit tests
+- a new option is available in the constructor &quot;errorHandlingAPIBreak&quot; (boolean, false by default) ; 
+    if set to true, it introduces a little API break but the error handling is better in CACHE_LITE_ERROR_RETURN
+    mode (specially with the save() method which can return a PEAR_Error object)
+Changes :
+- code refactoring for setToDebug() (thanks to moosh (at) php (dot) net)    
+- code refactoring (thanks to code analyzer)
+Bugs fixed :
+- #6388 : add an explicit dependancy on PEAR package (for error handling) (thanks to moosh (at) php (dot) net)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.6.0</release>
+     <api>1.6.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2005-12-03</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+No change (just some modifications into online documentation)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.6.0beta2</release>
+     <api>1.6.0beta2</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2005-11-25</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+New features :
+- a new phpt test script (eternal caching)
+- you can now call Cache_Lite constructor with any argument (thanks to ratibus at gmail dot com)
+Bug fixed :
+- bugfixes about eternal caching
+Other change : 
+- better code factoring (thanks to ratibus at gmail dot com)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.6.0beta1</release>
+     <api>1.6.0beta1</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2005-11-17</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+New features :
+- phpt test scripts
+- add of drop() method to Cache_Lite_Function (thanks to 
+Hugo Morganho hjm at holos dot pt)    
+- request #5495 : a null lifetime give an eternal caching (need tests)
+Bug fixed :
+- bugfix #5921 : a variable was unused (no consequence for the end user), 
+thanks to moosh at php dot net
+- bugfix #5938 : little mistakes given by Zend Code Analyser 
+- little mistake in the example for Cache_Lite_File
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.5.2</release>
+     <api>1.5.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2005-07-18</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Bug Fixed :
+- a &quot;package.xml&quot; problem (a file was forgotten)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.5.1</release>
+     <api>1.5.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2005-07-10</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Changes :
+- juste a little more docs since 1.5.0 (beta)
+- the state in &quot;stable&quot; now
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.5.0</release>
+     <api>1.5.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2005-06-18</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+New features :
+- add of a doNotTestCacheValidity in Output (like in Lite.php)
+- request #4502 : better control on cache cleaning condition (thanks to 
+vincent lascaux); introduce the idea of a user callback for the 
+cleaning process
+- new Cache_Lite_File module (for a cache controlled by a master file, 
+very usefull for templates or config caching)
+Bug fixed :
+- avoid a potential error message if cache doesn't exist
+- bug #4236 : fread PHP warning on zero length read (because of the change
+of fread() behaviour in PHP) (thanks to rick dot overman at gmail dot com)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.4.1</release>
+     <api>1.4.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2005-03-01</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Bug fixed :
+- problem of non-ISO-8859-1 characters in package.xml (bug #3621)
+- problem of the returning value in clean() method (integer and not void)
+    (thanks to Demian Turner (demian (at) phpkitchen (dot) com))
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.4.0</release>
+     <api>1.4.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2005-01-21</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Changes :
+- juste a little more docs since 1.4.0beta1
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.4.0beta1</release>
+     <api>1.4.0beta1</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2004-12-11</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+New features :
+- hashed cache directory structure with the choice of the level (thanks to Mike Benoit (ipso at snappymail dot ca))
+- new options for cleaning the cache (&quot;not in group&quot;, &quot;too old&quot;...) (thanks to dontilooksweetandinnocent@ambience.ru)
+- automatic cleaning of too old cache files based on a customisable &quot;random method&quot;
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.3.1</release>
+     <api>1.3.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2004-08-16</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Bug fixed :
+- problem with clean() method with memoryCaching activated (thanks to Bojan Mihelac (bmihelac at mihelac dot org))
+- remove() method didn't deal with memoryCaching
+- bug fix #1758, thanks to Dave (djpenton at cs dot mu dot oz dot au)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.3</release>
+     <api>1.3</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2004-02-07</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Changes :
+- Add a warning in examples file because of http://pear.php.net/bugs/bug.php?id=660
+Bug fixed :
+- little warning fix in Cache_Lite_Function (fab)
+- little bug fix in lastModified() method (thanks to Yavor Shahpasov)
+- fix http://pear.php.net/bugs/bug.php?id=513 (thanks to alan@aardwolfweb.com)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.2</release>
+     <api>1.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-10-25</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Changes :
+- Rewrite of Cache_Lite constructor (thanks to Brian E. Lozier) 
+New Features :
+- Add of lastModified() method (for Cache_Lite hackers) (thanks to Harry Fuecks)
+- Introduce automatic serialization (false in default) (thanks to Dan Wilson)
+- Add of an url for a cache_lite tutorial (english (thanks to paj) and french)
+Bug fixed :
+- Change the Cache_Lite::raiseError calls in $this-&gt;raiseError (thanks to Holger Willenborg)
+- Set the default group for remove, since get and save both have it set (thanks to jellybob)
+- Little fix for caching binary data under Windows (thanks to Simeon Franklin)
+- little fix with fileNameProtection set to false (not the default (big thank to Harry Fuecks))
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.1</release>
+     <api>1.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-02-23</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Changes :
+- Move to usage of call_user_func_array() and call_user_func() as call_user_method() is depreciated (thanks to Sterling Hughes) 
+New Features :
+- Introduce memoryCaching (idea of Mike Benoit)
+- Add of a file name protection option (can be faster if set to off) (thanks to Brian Webb for the idea)
+Bug fixed :
+- Little fix : cache was inefficient if the output is only 0 (thanks to Brian Webb)
+- notice fix (thanks to Lorenzo Alberton, Pierre-Alain Joye and Jon Parise)
+- Little fix to avoid file names problems with an exotic group name (thanks to Brian Webb)
+- Fix a possible bug when resave a cache file after a succesfull get (thanks to Michael Caplan)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.1</release>
+     <api>1.0.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2002-11-12</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+Bug fixed :
+- clean() bug with group (Thanks to Ondrej Jombik)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0</release>
+     <api>1.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2002-11-11</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+This is the first stable release of Cache_Lite. There is no big change since the
+0.4 beta release but two months of tests !
+Changes :
+- fix magic_q issue (Thanks to Moshe Doron)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.4</release>
+     <api>0.4</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2002-09-25</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+New features :
+- Add setLifeTime() method to change the cache lifetime dynamicaly
+Changes :
+- changes in the directory layout and in file names to (better) respect PEAR standards
+    =&gt; incompatibility with 0.3 version even there is no incompatible change in the API
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.3</release>
+     <api>0.3</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2002-08-31</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+New features :
+- Add '$doNotTestCacheValidity' optional parameter for the get() method
+Changes :
+- raiseError() method becomes public
+- swap of two lines in _write() method (Thanks to Jean-Francois BUSTARRET)
+Bugs fixed :
+- remove blank spaces at the end of the class (Thanks to Jean-Francois BUSTARRET)
+- E_NOTICEs problems and maybe a minor bug of errors management (Thanks to Sebastian BERGMANN)
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.2.0</release>
+     <api>0.2.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2002-08-10</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+New features :
+- Adding Cache_Lite_Function (to cache the result and output of functions/methods)
+Bugs fixed :
+- In a few cases of cache corruption, it was possible to get some warnings (but the output was correct)
+- Cache_Lite_Output require_once (to load Cache_Lite) wasn't correct
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1.1</release>
+     <api>0.1.1</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2002-08-08</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+A little packaging fix
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1</release>
+     <api>0.1</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2002-08-08</date>
+    <license uri="http://www.gnu.org/copyleft/lesser.html">lgpl</license>
+    <notes>
+This is the first release.
+   </notes>
+   </release>
+  </changelog>
+ </phprelease>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.php.net/Console_Getopt/1.2.3-info.xml b/lib/.xmlregistry/packages/pear.php.net/Console_Getopt/1.2.3-info.xml
new file mode 100644
index 00000000..b4be3935
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/Console_Getopt/1.2.3-info.xml
@@ -0,0 +1,156 @@
+<?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.6.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>Console_Getopt</name>
+ <channel>pear.php.net</channel>
+ <summary>Command-line option parser</summary>
+ <description>This is a PHP implementation of &quot;getopt&quot; supporting both
+short and long options.</description>
+ <lead>
+  <name>Andrei Zmievski</name>
+  <user>andrei</user>
+  <email>andrei@php.net</email>
+  <active>yes</active>
+ </lead>
+ <developer>
+  <name>Stig Bakken</name>
+  <user>ssb</user>
+  <email>stig@php.net</email>
+  <active>no</active>
+ </developer>
+ <helper>
+  <name>Greg Beaver</name>
+  <user>cellog</user>
+  <email>cellog@php.net</email>
+  <active>yes</active>
+ </helper>
+ <date>2010-01-27</date>
+ <time>10:08:51</time>
+ <version>
+  <release>1.2.3</release>
+  <api>1.2.1</api>
+ </version>
+ <stability>
+  <release>stable</release>
+  <api>stable</api>
+ </stability>
+ <license uri="http://www.php.net/license">PHP License</license>
+ <notes>* fix Bug #11068: No way to read plain &quot;-&quot; option [cardoe]</notes>
+ <contents>
+  <dir name="/">
+   <file md5sum="f2175a45c5e5bc7c97e174bdae55b671" name="Console/Getopt.php" role="php"/>
+  </dir>
+ </contents>
+ <compatible>
+  <name>PEAR</name>
+  <channel>pear.php.net</channel>
+  <min>1.4.0</min>
+  <max>1.6.0</max>
+ </compatible>
+ <dependencies>
+  <required>
+   <php>
+    <min>4.3.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.3</min>
+   </pearinstaller>
+  </required>
+ </dependencies>
+ <phprelease>
+  <changelog>
+   <release>
+    <version>
+     <release>1.2.2</release>
+     <api>1.2.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2007-02-17</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>* fix Bug #4475: An ambiguous error occurred when specifying similar longoption name.
+* fix Bug #10055: Not failing properly on short options missing required values</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.2.1</release>
+     <api>1.2.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2006-12-08</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>Fixed bugs #4448 (Long parameter values truncated with longoption parameter) and #7444 (Trailing spaces after php closing tag)</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.2</release>
+     <api>1.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-12-11</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>Fix to preserve BC with 1.0 and allow correct behaviour for new users</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0</release>
+     <api>1.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2002-09-13</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>Stable release</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.11</release>
+     <api>0.11</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2002-05-26</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>POSIX getopt compatibility fix: treat first element of args
+        array as command name</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.10</release>
+     <api>0.10</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2002-05-12</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>Packaging fix</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.9</release>
+     <api>0.9</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2002-05-12</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>Initial release</notes>
+   </release>
+  </changelog>
+ </phprelease>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.php.net/HTTP_Request2/0.5.1-info.xml b/lib/.xmlregistry/packages/pear.php.net/HTTP_Request2/0.5.1-info.xml
new file mode 100644
index 00000000..349f7bbd
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/HTTP_Request2/0.5.1-info.xml
@@ -0,0 +1,279 @@
+<?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>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. Provides cleaner API and pluggable
+Adapters. Currently available are:
+  * 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, 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>2010-01-27</date>
+ <time>10:06:25</time>
+ <version>
+  <release>0.5.1</release>
+  <api>0.5.0</api>
+ </version>
+ <stability>
+  <release>alpha</release>
+  <api>alpha</api>
+ </stability>
+ <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>
+ <contents>
+  <dir name="/">
+   <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="22d7f11b85dd00bd8919a4226a5a0388" name="tests/_files/bug_15305" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="96e929eb014758b7b5712be5c45110b9" name="tests/Request2Test.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="7ae3f0ef61d832d166671b044191efbf" name="tests/Request2/ResponseTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="ec1c8a2a8ab448183ed831ebd1c20518" name="tests/Request2/MultipartBodyTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="3f9867c9347815f15eac65c87b5c55e3" name="tests/Request2/AllTests.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="fb8e45c13ca3fb1c8594e22df9ab90d2" name="tests/Request2/Adapter/MockTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="d389619e0dad1f891a8b18117177496f" name="tests/Request2/Adapter/AllTests.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="f8691b81e639395523bc828b569fa716" name="tests/ObserverTest.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="f24af905aa262adefa4f692e2fe2a167" name="tests/AllTests.php" role="test"/>
+   <file baseinstalldir="HTTP" md5sum="07bfa5cff153994f244ceee9bd77de2a" name="Request2/Response.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="10b4d5d88f298a4e2fe7df08e5a218bb" name="Request2/Observer/Log.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="20b26f829852793a0e545c5df648a9b6" name="Request2/MultipartBody.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="a0b53a6710a47bc718dabc0edef36555" name="Request2/Exception.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="496dda12e9ca16561d9237651b1065e3" name="Request2/Adapter/Socket.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="ee8a541eb43be5cd04fd392770f90548" name="Request2/Adapter/Mock.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="90c77d4b4425b4bb63cf6ee921e5e3d1" name="Request2/Adapter/Curl.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="043e3d6edeeec91f7d21bf825090c2dd" name="Request2/Adapter.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="HTTP" md5sum="588ec605871ca474a8bcc3bf8f8035fc" 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"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.1.4</min>
+   </php>
+   <pearinstaller>
+    <min>1.5.4</min>
+   </pearinstaller>
+   <package>
+    <name>Net_URL2</name>
+    <channel>pear.php.net</channel>
+    <min>0.2.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>
+  <changelog>
+   <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>
+ </phprelease>
+</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 00000000..65a2944c
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/Net_URL2/0.3.1-info.xml
@@ -0,0 +1,97 @@
+<?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.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>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>2010-01-27</date>
+ <time>10:05:56</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>* Fixed Bug #16854: Invalid package.xml making it impossible to install with Pyrus</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.php.net/PEAR/1.9.0-info.xml b/lib/.xmlregistry/packages/pear.php.net/PEAR/1.9.0-info.xml
new file mode 100644
index 00000000..23ae8237
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/PEAR/1.9.0-info.xml
@@ -0,0 +1,802 @@
+<?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.0RC4" 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>PEAR</name>
+ <channel>pear.php.net</channel>
+ <summary>PEAR Base System</summary>
+ <description>The PEAR package contains:
+ * the PEAR installer, for creating, distributing
+   and installing packages
+ * the PEAR_Exception PHP5 error handling mechanism
+ * the PEAR_ErrorStack advanced error handling mechanism
+ * the PEAR_Error error handling mechanism
+ * the OS_Guess class for retrieving info about the OS
+   where PHP is running on
+ * the System class for quick handling of common operations
+   with files and directories
+ * the PEAR base class
+  Features in a nutshell:
+  * full support for channels
+  * pre-download dependency validation
+  * new package.xml 2.0 format allows tremendous flexibility while maintaining BC
+  * support for optional dependency groups and limited support for sub-packaging
+  * robust dependency support
+  * full dependency validation on uninstall
+  * remote install for hosts with only ftp access - no more problems with
+    restricted host installation
+  * full support for mirroring
+  * support for bundling several packages into a single tarball
+  * support for static dependencies on a url-based package
+  * support for custom file roles and installation tasks</description>
+ <lead>
+  <name>Greg Beaver</name>
+  <user>cellog</user>
+  <email>cellog@php.net</email>
+  <active>no</active>
+ </lead>
+ <lead>
+  <name>Pierre-Alain Joye</name>
+  <user>pajoye</user>
+  <email>pierre@php.net</email>
+  <active>no</active>
+ </lead>
+ <lead>
+  <name>Stig Bakken</name>
+  <user>ssb</user>
+  <email>stig@php.net</email>
+  <active>no</active>
+ </lead>
+ <lead>
+  <name>Tomas V.V.Cox</name>
+  <user>cox</user>
+  <email>cox@idecnet.com</email>
+  <active>no</active>
+ </lead>
+ <lead>
+  <name>Helgi Thormar</name>
+  <user>dufuz</user>
+  <email>dufuz@php.net</email>
+  <active>yes</active>
+ </lead>
+ <developer>
+  <name>Tias Guns</name>
+  <user>tias</user>
+  <email>tias@php.net</email>
+  <active>yes</active>
+ </developer>
+ <helper>
+  <name>Tim Jackson</name>
+  <user>timj</user>
+  <email>timj@php.net</email>
+  <active>no</active>
+ </helper>
+ <helper>
+  <name>Bertrand Gugger</name>
+  <user>toggg</user>
+  <email>toggg@php.net</email>
+  <active>no</active>
+ </helper>
+ <helper>
+  <name>Martin Jansen</name>
+  <user>mj</user>
+  <email>mj@php.net</email>
+  <active>no</active>
+ </helper>
+ <date>2010-01-27</date>
+ <time>10:08:50</time>
+ <version>
+  <release>1.9.0</release>
+  <api>1.9.0</api>
+ </version>
+ <stability>
+  <release>stable</release>
+  <api>stable</api>
+ </stability>
+ <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+ <notes>
+* Fix  Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz]
+ </notes>
+ <contents>
+  <dir name="/">
+   <file md5sum="acd010e3bc43c0f72df584acde7b9158" name="template.spec" role="data"/>
+   <file md5sum="8bf4cfb58d10d72b5082c3022c887710" name="System.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="/" md5sum="320849b646e4cdaeca543af666524e73" name="scripts/peclcmd.php" role="php">
+    <tasks:replace from="@php_bin@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@php_dir@" to="php_dir" type="pear-config"/>
+    <tasks:replace from="@pear_version@" to="version" type="package-info"/>
+    <tasks:replace from="@include_path@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="d00c55f2aa48052c25db271e044e7551" name="scripts/pecl.sh" role="script">
+    <tasks:replace from="@php_bin@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@php_dir@" to="php_dir" type="pear-config"/>
+    <tasks:replace from="@pear_version@" to="version" type="package-info"/>
+    <tasks:replace from="@include_path@" to="php_dir" type="pear-config"/>
+    <tasks:unixeol/>
+   </file>
+   <file baseinstalldir="/" md5sum="34c1cb834dd1c03c9e40998b201d52e0" name="scripts/pecl.bat" role="script">
+    <tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config"/>
+    <tasks:replace from="@php_bin@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@include_path@" to="php_dir" type="pear-config"/>
+    <tasks:windowseol/>
+   </file>
+   <file baseinstalldir="/" md5sum="c69b7eb6cf9198ef8f03a19dcb57ca42" name="scripts/peardev.sh" role="script">
+    <tasks:replace from="@php_bin@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@php_dir@" to="php_dir" type="pear-config"/>
+    <tasks:replace from="@pear_version@" to="version" type="package-info"/>
+    <tasks:replace from="@include_path@" to="php_dir" type="pear-config"/>
+    <tasks:unixeol/>
+   </file>
+   <file baseinstalldir="/" md5sum="92cafd038c7d6a212111c84ca4907a13" name="scripts/peardev.bat" role="script">
+    <tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config"/>
+    <tasks:replace from="@php_bin@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@include_path@" to="php_dir" type="pear-config"/>
+    <tasks:windowseol/>
+   </file>
+   <file baseinstalldir="/" md5sum="55426bdbfd8e1bc050a79e3c6095d8e5" name="scripts/pearcmd.php" role="php">
+    <tasks:replace from="@php_bin@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@php_dir@" to="php_dir" type="pear-config"/>
+    <tasks:replace from="@pear_version@" to="version" type="package-info"/>
+    <tasks:replace from="@include_path@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="5b495a3de3c6092bfbd93806937a0e4e" name="scripts/pear.sh" role="script">
+    <tasks:replace from="@php_bin@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@php_dir@" to="php_dir" type="pear-config"/>
+    <tasks:replace from="@pear_version@" to="version" type="package-info"/>
+    <tasks:replace from="@include_path@" to="php_dir" type="pear-config"/>
+    <tasks:unixeol/>
+   </file>
+   <file baseinstalldir="/" md5sum="bd65b087b7707463525e9f0092337793" name="scripts/pear.bat" role="script">
+    <tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config"/>
+    <tasks:replace from="@php_bin@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@include_path@" to="php_dir" type="pear-config"/>
+    <tasks:windowseol/>
+   </file>
+   <file md5sum="d3b517006b304817731eb77cc2154258" name="README" role="doc"/>
+   <file md5sum="1a8f67d58009372a6cbcddd638b128cf" name="PEAR5.php" role="php"/>
+   <file md5sum="c6de49d413a1cf97a1f8a4668766e3ab" name="PEAR/XMLParser.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="a18f1a10bb85cc988f7c2de9914c1e9f" name="PEAR/Validator/PECL.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="c5ea781c8abb14ff62b04b6db5e10e0f" name="PEAR/Validate.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="a5545cfac22a53d0aad99f4acdbee50c" name="PEAR/Task/Windowseol/rw.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="33bc10b55f7c90425054024b42d0e944" name="PEAR/Task/Windowseol.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="0787e483b91cb6842b9cfedbb486aabf" name="PEAR/Task/Unixeol/rw.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="85ee9fd0fa58d4aef2161d5ac5d9b539" name="PEAR/Task/Unixeol.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="d4f525ae7d94c48662d45769643abada" name="PEAR/Task/Replace/rw.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="0fecedc2f99e5f010b327650c353e4db" name="PEAR/Task/Replace.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="bff16b5498aa831d106061ebbaba484c" name="PEAR/Task/Postinstallscript/rw.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="34d4c4f16734388faca7e418ab206f68" name="PEAR/Task/Postinstallscript.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="e61537de629cb2f7f7e1bc497038902e" name="PEAR/Task/Common.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="34a0d9008da01b3987a610d94837a80c" name="PEAR/RunTest.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="897908bf87ac9ae617a0a42e13f8e0cd" name="PEAR/REST/13.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="41f230e5d3282221e6b55466cb0510d3" name="PEAR/REST/11.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="b0b343c594552895492692d52561bc52" name="PEAR/REST/10.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="28e5f3b905280051309e65d3e85d0b15" name="PEAR/REST.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="a58437db39d3d71bb93f44a660334720" name="PEAR/Registry.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="821b72d18cbdc2e8b9c5087bc9b99854" name="PEAR/Packager.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="cf2b5655d9accc025e5cf5f0476302a8" name="PEAR/PackageFile/v2/Validator.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="9a159d7f8e70bf9f57f9ade64dd5e377" name="PEAR/PackageFile/v2/rw.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="7026083ae0b038045dc117d68dc32a0a" name="PEAR/PackageFile/v2.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="7736b857a1153b02453d42dd476d6f8a" name="PEAR/PackageFile/v1.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="a5f847fdba24116593efc223425a9609" name="PEAR/PackageFile/Parser/v2.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="7d3828c0f41aadc34d948f5215c4cd66" name="PEAR/PackageFile/Parser/v1.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="f7ed15b3d6d1aab0b6f8ee2fe0d9d3db" name="PEAR/PackageFile/Generator/v2.php" role="php">
+    <tasks:replace from="@PEAR-VER@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="cd8b1ef4c311e0e4f5a00e5e36d48d43" name="PEAR/PackageFile/Generator/v1.php" role="php">
+    <tasks:replace from="@PEAR-VER@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="df9c5cc34b6fbbf661d534cecb315c9f" name="PEAR/PackageFile.php" role="php">
+    <tasks:replace from="@PEAR-VER@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="7641e71c5785bb33a4261ebe25ed0fd7" name="PEAR/Installer/Role/Www.xml" role="php"/>
+   <file md5sum="8ab36d60bc9eb361885d7d901b107c0c" name="PEAR/Installer/Role/Www.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="a24b596ec987aa5688fc19e8ed4e97ea" name="PEAR/Installer/Role/Test.xml" role="php"/>
+   <file md5sum="5601a755c633dafb639a8fbd1abe0261" name="PEAR/Installer/Role/Test.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="e147d63f168ea156fc2be38caaa63804" name="PEAR/Installer/Role/Src.xml" role="php"/>
+   <file md5sum="656ad25a2fa1a13f53aad6121edfba91" name="PEAR/Installer/Role/Src.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="746461dc3b48af6d24094cb0211608f2" name="PEAR/Installer/Role/Script.xml" role="php"/>
+   <file md5sum="eb20ad9051db4db53a1c30e9f1b0dab5" name="PEAR/Installer/Role/Script.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="ef88f0321d3e481c2130c95122cf76d8" name="PEAR/Installer/Role/Php.xml" role="php"/>
+   <file md5sum="9e4a34e2a332b704417590cb734ffc93" name="PEAR/Installer/Role/Php.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="af71c0ad42d16a323afe24a4f884ef15" name="PEAR/Installer/Role/Ext.xml" role="php"/>
+   <file md5sum="b3c70e10e63273ef1f2e5cd0a2bd33e8" name="PEAR/Installer/Role/Ext.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="b1ce0fe105251c3b75209d6518ee69ac" name="PEAR/Installer/Role/Doc.xml" role="php"/>
+   <file md5sum="5c0b53e95ae25306da82cf6dd87da4dc" name="PEAR/Installer/Role/Doc.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="89a4a2a286e842d45a98974f40a0565c" name="PEAR/Installer/Role/Data.xml" role="php"/>
+   <file md5sum="2cb74a7dd5fdfce5b78717e1847d463c" name="PEAR/Installer/Role/Data.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="d3c3a546ced9a12889eda5e368583944" name="PEAR/Installer/Role/Common.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="d8c62e6275e3aaa7784290912406092c" name="PEAR/Installer/Role/Cfg.xml" role="php"/>
+   <file md5sum="a3bb43296f00bd5459a0fbf8314f8917" name="PEAR/Installer/Role/Cfg.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="0dab463a3402a0401616c7a1630bebcb" name="PEAR/Installer/Role.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="45f4c064607a7d3d4f68b0f06f98db5c" name="PEAR/Installer.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="e613fdf2c8090bf8f7289dbeaa06a97c" name="PEAR/Frontend/CLI.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="52c3acdba716110657f7bf86ca2012e1" name="PEAR/Frontend.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="e0e4cbcec4a972fbad779d0f9d323120" name="PEAR/FixPHP5PEARWarnings.php" role="php"/>
+   <file md5sum="f364e75223744d460a6bb08420ac94f9" name="PEAR/Exception.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="33ce30b4478cdb76e29bd75058c842e3" name="PEAR/ErrorStack.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="73a70ef0ac6d521fcbc972de10341bbe" name="PEAR/Downloader/Package.php" role="php">
+    <tasks:replace from="@PEAR-VER@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="2185eb7a493f863ea3d3510195e7c901" name="PEAR/Downloader.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="c161acaf73f7938ea48b3165d891998b" name="PEAR/DependencyDB.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="b0d1ee5d0acd02ca9351e076f73cc9da" name="PEAR/Dependency2.php" role="php">
+    <tasks:replace from="@PEAR-VER@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="5080a36f685fcef9b160617e8cb02870" name="PEAR/Config.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="7c0ff45e0ee9df0ddbaa9b8c4c31b2fd" name="PEAR/Common.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="a50c32015005e0761cc3b04679b29ed0" name="PEAR/Command/Test.xml" role="php"/>
+   <file md5sum="01252c8d6c005f53f250344bb4453a59" name="PEAR/Command/Test.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="29c02e823879b4e3e291f6b36fb339f1" name="PEAR/Command/Remote.xml" role="php"/>
+   <file md5sum="374366b6f361c401ae22edc5b76b7a90" name="PEAR/Command/Remote.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="49b046cfc14747f0365e02e9c3f0e6dc" name="PEAR/Command/Registry.xml" role="php"/>
+   <file md5sum="567687617b7f406bd1ba55e37060edf8" name="PEAR/Command/Registry.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="28dc842ea725d8787b9f9c3dbca5aa22" name="PEAR/Command/Pickle.xml" role="php"/>
+   <file md5sum="6a794c2a0545fff7300217dd6e133c17" name="PEAR/Command/Pickle.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="6c3061a594644e49b0648798dce6de32" name="PEAR/Command/Package.xml" role="php"/>
+   <file md5sum="2d4e5f5200fdbdbb5f1c2bf0a27ab754" name="PEAR/Command/Package.php" role="php">
+    <tasks:replace from="@DATA-DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="5cb62a04c0a268f4edd64a49a3895c92" name="PEAR/Command/Mirror.xml" role="php"/>
+   <file md5sum="8bc9265e1046ec67a85571557515bb1b" name="PEAR/Command/Mirror.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="2db0386b865d3f9a29f9126728722ece" name="PEAR/Command/Install.xml" role="php"/>
+   <file md5sum="034593b2194bf8feb689722833e1c9b0" name="PEAR/Command/Install.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="91f189cb9423b5e87ee0abc5ea1a2be3" name="PEAR/Command/Config.xml" role="php"/>
+   <file md5sum="f0c106b4ba5e12236c59b161b75f4182" name="PEAR/Command/Config.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="dc4961036d632859bb1bda5e32a8c346" name="PEAR/Command/Common.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="6d5aab4d4308c3005b5f584c7783a031" name="PEAR/Command/Channels.xml" role="php"/>
+   <file md5sum="63a395cf6c752e8121e1fa2ae1f9ac28" name="PEAR/Command/Channels.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="73602fd7f051eaf8d37452d0e3063bdb" name="PEAR/Command/Build.xml" role="php"/>
+   <file md5sum="99e6dae6555a272f16f1cf2265d221c0" name="PEAR/Command/Build.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="8fd87e64002e11fd86eb2f3fbfee6599" name="PEAR/Command/Auth.xml" role="php"/>
+   <file md5sum="7d3f1696902faf5442059393e541ad2d" name="PEAR/Command/Auth.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="150c15a2fb2fd57166ca8276e29cb74b" name="PEAR/Command.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="e839d4a327219441507bd5de7409ee5b" name="PEAR/ChannelFile/Parser.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="f9d18b3c198a2a0f0771036c6b0404f7" name="PEAR/ChannelFile.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="d9d3b94e0d1bf2f2c377a5cd8201481c" name="PEAR/Builder.php" role="php">
+    <tasks:replace from="@PEAR-VER@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="b6d6b167ca1514d0765533d4abafca1d" name="PEAR/Autoloader.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="4e4941a59ed97ca61c93deb6a7ff918c" name="PEAR.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="4a49bc83a392934e57af45c70a589fda" name="package.dtd" role="data"/>
+   <file md5sum="f063d5b84d03538b85f05cde9aae8037" name="OS/Guess.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file md5sum="45b44486d8090de17b2a8b4211fab247" name="LICENSE" role="doc"/>
+   <file md5sum="45b1a9dcc368539cb8f2a65c30b2f453" name="INSTALL" role="doc"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>4.4.0</min>
+    <exclude>5.0</exclude>
+    <exclude>5.1.0</exclude>
+    <exclude>5.1.1</exclude>
+    <exclude>5.1.2</exclude>
+    <exclude>5.1.3</exclude>
+    <exclude>5.1.4</exclude>
+    <exclude>5.1.5</exclude>
+   </php>
+   <pearinstaller>
+    <min>1.4.3</min>
+   </pearinstaller>
+   <package>
+    <name>Archive_Tar</name>
+    <channel>pear.php.net</channel>
+    <min>1.1</min>
+    <recommended>1.3.3</recommended>
+    <exclude>1.3.0</exclude>
+   </package>
+   <package>
+    <name>Structures_Graph</name>
+    <channel>pear.php.net</channel>
+    <min>1.0.2</min>
+    <recommended>1.0.2</recommended>
+   </package>
+   <package>
+    <name>Console_Getopt</name>
+    <channel>pear.php.net</channel>
+    <min>1.2</min>
+    <recommended>1.2.3</recommended>
+   </package>
+   <package>
+    <name>XML_Util</name>
+    <channel>pear.php.net</channel>
+    <min>1.2.0</min>
+    <recommended>1.2.1</recommended>
+   </package>
+   <package>
+    <name>PEAR_Frontend_Web</name>
+    <channel>pear.php.net</channel>
+    <max>0.4</max>
+    <conflicts/>
+   </package>
+   <package>
+    <name>PEAR_Frontend_Gtk</name>
+    <channel>pear.php.net</channel>
+    <max>0.4.0</max>
+    <exclude>0.4.0</exclude>
+    <conflicts/>
+   </package>
+   <extension>
+    <name>xml</name>
+   </extension>
+   <extension>
+    <name>pcre</name>
+   </extension>
+  </required>
+  <group hint="PEAR's web-based installer" name="webinstaller">
+   <package>
+    <name>PEAR_Frontend_Web</name>
+    <channel>pear.php.net</channel>
+    <min>0.5.1</min>
+   </package>
+  </group>
+  <group hint="PEAR's PHP-GTK-based installer" name="gtkinstaller">
+   <package>
+    <name>PEAR_Frontend_Gtk</name>
+    <channel>pear.php.net</channel>
+    <min>0.4.0</min>
+   </package>
+  </group>
+  <group hint="PEAR's PHP-GTK2-based installer" name="gtk2installer">
+   <package>
+    <name>PEAR_Frontend_Gtk2</name>
+    <channel>pear.php.net</channel>
+   </package>
+  </group>
+ </dependencies>
+ <phprelease>
+  <installconditions>
+   <os>
+    <name>windows</name>
+   </os>
+  </installconditions>
+  <filelist>
+   <install as="pear.bat" name="scripts/pear.bat"/>
+   <install as="pearcmd.php" name="scripts/pearcmd.php"/>
+   <install as="peardev.bat" name="scripts/peardev.bat"/>
+   <install as="pecl.bat" name="scripts/pecl.bat"/>
+   <install as="peclcmd.php" name="scripts/peclcmd.php"/>
+   <ignore name="scripts/pear.sh"/>
+   <ignore name="scripts/peardev.sh"/>
+   <ignore name="scripts/pecl.sh"/>
+  </filelist>
+ </phprelease>
+ <phprelease>
+  <filelist>
+   <install as="pear" name="scripts/pear.sh"/>
+   <install as="pearcmd.php" name="scripts/pearcmd.php"/>
+   <install as="peardev" name="scripts/peardev.sh"/>
+   <install as="pecl" name="scripts/pecl.sh"/>
+   <install as="peclcmd.php" name="scripts/peclcmd.php"/>
+   <ignore name="scripts/pear.bat"/>
+   <ignore name="scripts/peardev.bat"/>
+   <ignore name="scripts/pecl.bat"/>
+  </filelist>
+ </phprelease>
+ <changelog>
+  <release>
+   <version>
+    <release>1.8.0alpha1</release>
+    <api>1.8.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>stable</api>
+   </stability>
+   <date>2009-03-09</date>
+   <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+   <notes>
+* Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz]
+* Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz]
+* Implement Request #10825: Only display the &quot;invalid or missing package file&quot;-error if it makes sense [dufuz]
+* Implement Request #11170: script to generate Command/[command].xml [dufuz]
+* Implement Request #11176: improve channel ... has updated its protocols message [dufuz]
+* Implement Request #12706: pear list -a hard to read [dufuz]
+* Implement Request #11353: upgrade-all and upgrade commands to upgrade within the same stability level [dufuz]
+* Implement Request #13015: Add https discovery for channel.xml [dufuz / initial patch by Martin Roos]
+* Implement Request #13927: install-pear.php should have option to set www_dir [timj]
+* Implement Request #14324: Make the pear install command behave similar to apt-get [dufuz]
+* Implement Request #14325: make pear upgrade with no params behave like pear upgrade-all [dufuz]
+  - upgrade-all can be considered deprecated in favor of calling upgrade with no parameters to replicate
+    better what other package managers are doing. upgrade-all will still work as intended.
+* Implement Request #14504: add a channel parameter support to the upgrade function [dufuz]
+  - Options -c ezc and --channel=ezc got added to upgrade and upgrade-all to allow for
+    channel specific upgrades
+* Implement Request #14556: install-pear-nozlib.phar should get download_dir config and other options [cweiske]
+* Implement Request #15566: Add doc.php.net as a default channel [dufuz / saltybeagle]
+
+* Fix PHP Bug #43857: --program-suffix not always reflected everywhere [cellog]
+* Fix PHP Bug #47323: strotime warnings in make install [dufuz]
+
+* Fix Bug #13908: pear info command and maintainers inactive not mentioned [dufuz]
+* Fix Bug #13926: install-pear.php does not set cfg_dir if -d option set with no -c option [timj]
+* Fix Bug #13943: tests fail when php.exe path contains spaces [dufuz / jorrit]
+* Fix Bug #13953: config-set/config-show with channel alias fail [cellog]
+* Fix Bug #13958: When a phpt tests exit() or die() xdebug coverage is not generated, patch by izi (David Jean Louis) [izi / dufuz]
+* Fix Bug #14041: Unpredictable unit test processing sequence [dufuz]
+* Fix Bug #14140: Strict warning not suppressed in the shutdown function [dufuz]
+* Fix Bug #14210: pear list -ia brings warnings [dufuz]
+* Fix Bug #14274: PEAR packager mangles package.xml encoding, then complains about it [dufuz]
+* Fix Bug #14287: cannot upgrade from stable to beta via -beta when config is set to stable [dufuz]
+* Fix Bug #14300: Package files themselves can not be served over https [dufuz / initial patch by Martin Roos]
+* Fix Bug #14437: openbasedir warning when loading config [dufuz]
+* Fix Bug #14558: PackageFile.php creates tmp directory outside configured temp_dir [cweiske]
+* Fix Bug #14947: downloadHttp() is missing Host part of the HTTP Request when using Proxy [ifeghali]
+* Fix Bug #14977: PEAR/Frontend.php doesn't require_once PEAR.php [dufuz]
+* Fix Bug #15750: Unreachable code in PEAR_Downloader [dufuz]
+* Fix Bug #15979: Package files incorrectly removed when splitting a package into multiple pkgs [dufuz]
+* Fix Bug #15914: pear upgrade installs different version if desired version not found [dufuz]
+
+NOTE!
+Functions that have been deprecated for 3+ years in PEAR_Common, please take a moment
+to migrate over to one of the alternatives that have ben provided:
+* PEAR_Common-&gt;downloadHttp (use PEAR_Downloader-&gt;downloadHttp instead)
+* PEAR_Common-&gt;infoFromTgzFile (use PEAR_PackageFile-&gt;fromTgzFile instead)
+* PEAR_Common-&gt;infoFromDescriptionFile (use PEAR_PackageFile-&gt;fromPackageFile instead)
+* PEAR_Common-&gt;infoFromString (use PEAR_PackageFile-&gt;fromXmlstring instead)
+* PEAR_Common-&gt;infoFromArray (use PEAR_PackageFile-&gt;fromAnyFile instead)
+* PEAR_Common-&gt;xmlFromInfo (use a PEAR_PackageFile_v* object's generator instead)
+* PEAR_Common-&gt;validatePackageInfo (use the validation of PEAR_PackageFile objects)
+* PEAR_Common-&gt;analyzeSourceCode (use a PEAR_PackageFile_v* object instead)
+* PEAR_Common-&gt;detectDependencies (use PEAR_Downloader_Package-&gt;detectDependencies instead)
+* PEAR_Common-&gt;buildProvidesArray (use PEAR_PackageFile_v1-&gt;_buildProvidesArray or
+  PEAR_PackageFile_v2_Validator-&gt;_buildProvidesArray)
+
+PHP 4.4 and 5.1.6 are now the minimum PHP requirements, for brave souls
+pear upgrade -f PEAR will allow people with lower versions
+to upgrade to this release but no guarantees will be made that it will work properly.
+
+Support for XML RPC channels has been dropped - The only ones that used it
+(pear.php.net and pecl.php.net) have used the REST interface for years now.
+SOAP support also removed as it was only proof of concept.
+
+Move codebase from the PHP License to New BSD 2 clause license
+   </notes>
+  </release>
+  <release>
+   <date>2009-03-27</date>
+   <version>
+    <release>1.8.0RC1</release>
+    <api>1.8.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>stable</api>
+   </stability>
+   <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+   <notes>
+* Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz]
+* Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz]
+
+* Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz]
+* Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz]
+   </notes>
+  </release>
+  <release>
+   <date>2009-04-10</date>
+   <version>
+    <release>1.8.0</release>
+    <api>1.8.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+   <notes>
+Changes since RC1:
+  * Fix Bug #14792: Bad md5sum for files with replaced content [dufuz]
+  * Fix Bug #16057:-r is limited to 4 directories in depth [dufuz]
+  * Fix Bug #16077: PEAR5::getStaticProperty does not return a reference to the property [dufuz]
+
+  Remove custom XML_Util class in favor of using upstream XML_Util package as dependency
+
+RC1 Release Notes:
+  * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz]
+  * Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz]
+
+  * Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz]
+  * Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz]
+
+Alpha1 Release Notes:
+  * Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz]
+  * Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz]
+  * Implement Request #10825: Only display the &quot;invalid or missing package file&quot;-error if it makes sense [dufuz]
+  * Implement Request #11170: script to generate Command/[command].xml [dufuz]
+  * Implement Request #11176: improve channel ... has updated its protocols message [dufuz]
+  * Implement Request #12706: pear list -a hard to read [dufuz]
+  * Implement Request #11353: upgrade-all and upgrade commands to upgrade within the same stability level [dufuz]
+  * Implement Request #13015: Add https discovery for channel.xml [dufuz / initial patch by Martin Roos]
+  * Implement Request #13927: install-pear.php should have option to set www_dir [timj]
+  * Implement Request #14324: Make the pear install command behave similar to apt-get [dufuz]
+  * Implement Request #14325: make pear upgrade with no params behave like pear upgrade-all [dufuz]
+    - upgrade-all can be considered deprecated in favor of calling upgrade with no parameters to replicate
+      better what other package managers are doing. upgrade-all will still work as intended.
+  * Implement Request #14504: add a channel parameter support to the upgrade function [dufuz]
+    - Options -c ezc and --channel=ezc got added to upgrade and upgrade-all to allow for
+      channel specific upgrades
+  * Implement Request #14556: install-pear-nozlib.phar should get download_dir config and other options [cweiske]
+  * Implement Request #15566: Add doc.php.net as a default channel [dufuz / saltybeagle]
+
+  * Fix PHP Bug #43857: --program-suffix not always reflected everywhere [cellog]
+  * Fix PHP Bug #47323: strotime warnings in make install [dufuz]
+
+  * Fix Bug #13908: pear info command and maintainers inactive not mentioned [dufuz]
+  * Fix Bug #13926: install-pear.php does not set cfg_dir if -d option set with no -c option [timj]
+  * Fix Bug #13943: tests fail when php.exe path contains spaces [dufuz / jorrit]
+  * Fix Bug #13953: config-set/config-show with channel alias fail [cellog]
+  * Fix Bug #13958: When a phpt tests exit() or die() xdebug coverage is not generated, patch by izi (David Jean Louis) [izi / dufuz]
+  * Fix Bug #14041: Unpredictable unit test processing sequence [dufuz]
+  * Fix Bug #14140: Strict warning not suppressed in the shutdown function [dufuz]
+  * Fix Bug #14210: pear list -ia brings warnings [dufuz]
+  * Fix Bug #14274: PEAR packager mangles package.xml encoding, then complains about it [dufuz]
+  * Fix Bug #14287: cannot upgrade from stable to beta via -beta when config is set to stable [dufuz]
+  * Fix Bug #14300: Package files themselves can not be served over https [dufuz / initial patch by Martin Roos]
+  * Fix Bug #14437: openbasedir warning when loading config [dufuz]
+  * Fix Bug #14558: PackageFile.php creates tmp directory outside configured temp_dir [cweiske]
+  * Fix Bug #14947: downloadHttp() is missing Host part of the HTTP Request when using Proxy [ifeghali]
+  * Fix Bug #14977: PEAR/Frontend.php doesn't require_once PEAR.php [dufuz]
+  * Fix Bug #15750: Unreachable code in PEAR_Downloader [dufuz]
+  * Fix Bug #15979: Package files incorrectly removed when splitting a package into multiple pkgs [dufuz]
+  * Fix Bug #15914: pear upgrade installs different version if desired version not found [dufuz]
+
+  NOTE!
+  Functions that have been deprecated for 3+ years in PEAR_Common, please take a moment
+  to migrate over to one of the alternatives that have ben provided:
+  * PEAR_Common-&gt;downloadHttp (use PEAR_Downloader-&gt;downloadHttp instead)
+  * PEAR_Common-&gt;infoFromTgzFile (use PEAR_PackageFile-&gt;fromTgzFile instead)
+  * PEAR_Common-&gt;infoFromDescriptionFile (use PEAR_PackageFile-&gt;fromPackageFile instead)
+  * PEAR_Common-&gt;infoFromString (use PEAR_PackageFile-&gt;fromXmlstring instead)
+  * PEAR_Common-&gt;infoFromArray (use PEAR_PackageFile-&gt;fromAnyFile instead)
+  * PEAR_Common-&gt;xmlFromInfo (use a PEAR_PackageFile_v* object's generator instead)
+  * PEAR_Common-&gt;validatePackageInfo (use the validation of PEAR_PackageFile objects)
+  * PEAR_Common-&gt;analyzeSourceCode (use a PEAR_PackageFile_v* object instead)
+  * PEAR_Common-&gt;detectDependencies (use PEAR_Downloader_Package-&gt;detectDependencies instead)
+  * PEAR_Common-&gt;buildProvidesArray (use PEAR_PackageFile_v1-&gt;_buildProvidesArray or
+    PEAR_PackageFile_v2_Validator-&gt;_buildProvidesArray)
+
+  PHP 4.4 and 5.1.6 are now the minimum PHP requirements, for brave souls
+  pear upgrade -f PEAR will allow people with lower versions
+  to upgrade to this release but no guarantees will be made that it will work properly.
+
+  Support for XML RPC channels has been dropped - The only ones that used it
+  (pear.php.net and pecl.php.net) have used the REST interface for years now.
+  SOAP support also removed as it was only proof of concept.
+
+  Move codebase from the PHP License to New BSD 2 clause license
+   </notes>
+  </release>
+  <release>
+   <date>2009-04-15</date>
+   <version>
+    <release>1.8.1</release>
+    <api>1.8.1</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+   <notes>
+* Fix Bug #16099 	PEAR crash on PHP4 (parse error) [dufuz]
+   </notes>
+  </release>
+  <release>
+   <date>2009-08-18</date>
+   <version>
+    <release>1.9.0RC1</release>
+    <api>1.9.0RC1</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>stable</api>
+   </stability>
+   <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+   <notes>
+* Implement Request #16213: add alias to list-channels output [dufuz]
+* Implement Request #16378: pear svntag [dufuz]
+* Implement Request #16386: PEAR_Config::remove() does not support specifying a channel [timj]
+* Implement Request #16396: package-dependencies should allow package names [dufuz]
+
+* Fix Bug #11181: pear requests channel.xml from main server instead from mirror [dufuz]
+* Fix Bug #14493: pear install --offline doesn't print out errors [dufuz]
+* Fix Bug #11348: pear package-dependencies isn't well explained [dufuz]
+* Fix Bug #16108: PEAR_PackageFile_Generator_v2 PHP4 parse error when running upgrade-all [dufuz]
+* Fix Bug #16113: Installing certain packages fails due incorrect encoding handling [dufuz]
+* Fix Bug #16122: PEAR RunTest failed to run as expected [dufuz]
+* Fix Bug #16366: compiling 5.2.10 leads to non-functioning pear [dufuz]
+* Fix Bug #16387: channel-logout does not support logging out from a non-default channel [timj]
+* Fix Bug #16444: Setting preferred mirror fails [dufuz]
+* Fix the shutdown functions where a index might not exist and thus raise a notice [derick]
+   </notes>
+  </release>
+  <release>
+   <date>2009-08-20</date>
+   <version>
+    <release>1.9.0RC2</release>
+    <api>1.9.0RC2</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>stable</api>
+   </stability>
+   <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+   <notes>
+* REST 1.4 file was occasionally being included but REST 1.4 is not intended for this release cycle [dufuz]
+   </notes>
+  </release>
+  <release>
+   <date>2009-08-21</date>
+   <version>
+    <release>1.9.0RC3</release>
+    <api>1.9.0RC3</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>stable</api>
+   </stability>
+   <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+   <notes>
+* Improved svntag support to handle packages like PEAR it self [dufuz]
+   </notes>
+  </release>
+  <release>
+   <date>2009-08-23</date>
+   <version>
+    <release>1.9.0RC4</release>
+    <api>1.9.0RC4</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>stable</api>
+   </stability>
+   <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+   <notes>
+* Fixed a problem where the original channel could not be set as a preferred_mirror again [dufuz]
+* Make sure channel aliases can't be made to start with - [dufuz]
+* Output issues with pear search [dufuz]
+* Fixed couple of stray notices [dufuz]
+   </notes>
+  </release>
+  <release>
+   <date>2009-09-03</date>
+   <version>
+    <release>1.9.0</release>
+    <api>1.9.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <license uri="http://opensource.org/licenses/bsd-license.php">New BSD License</license>
+   <notes>
+* Fix  Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz]
+   </notes>
+  </release>
+ </changelog>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.php.net/Structures_Graph/1.0.2-info.xml b/lib/.xmlregistry/packages/pear.php.net/Structures_Graph/1.0.2-info.xml
new file mode 100644
index 00000000..1008bdd0
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/Structures_Graph/1.0.2-info.xml
@@ -0,0 +1,92 @@
+<?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.5.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>Structures_Graph</name>
+ <channel>pear.php.net</channel>
+ <summary>Graph datastructure manipulation library</summary>
+ <description>Structures_Graph is a package for creating and manipulating graph datastructures. It allows building of directed
+and undirected graphs, with data and metadata stored in nodes. The library provides functions for graph traversing
+as well as for characteristic extraction from the graph topology.</description>
+ <lead>
+  <name>Sérgio Carvalho</name>
+  <user>sergiosgc</user>
+  <email>sergio.carvalho@portugalmail.com</email>
+  <active>yes</active>
+ </lead>
+ <date>2010-01-27</date>
+ <time>10:08:51</time>
+ <version>
+  <release>1.0.2</release>
+  <api>1.0.0</api>
+ </version>
+ <stability>
+  <release>stable</release>
+  <api>stable</api>
+ </stability>
+ <license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
+ <notes>- Bug #9682 only variables can be returned by reference
+- fix Bug #9661 notice in Structures_Graph_Manipulator_Topological::sort()</notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="" md5sum="63dfc6f0f14e18c13d8a8415c3fe049d" name="tests/testCase/BasicGraph.php" role="test"/>
+   <file baseinstalldir="" md5sum="d41d8cd98f00b204e9800998ecf8427e" name="tests/README" role="test"/>
+   <file baseinstalldir="" md5sum="1b9e35896d229b84601e6754cd44e339" name="tests/all-tests.php" role="test"/>
+   <file baseinstalldir="" md5sum="7e28e01ebfa273e5df2eb1ef7a356635" name="Structures/Graph/Node.php" role="php"/>
+   <file baseinstalldir="" md5sum="0492e677436d29228df93dca23629e06" name="Structures/Graph/Manipulator/TopologicalSorter.php" role="php"/>
+   <file baseinstalldir="" md5sum="f0aff5a1efd188d63b4b8b9e9e840b97" name="Structures/Graph/Manipulator/AcyclicTest.php" role="php"/>
+   <file baseinstalldir="" md5sum="4f25a6275af156f6f8e7b4309cb9f40d" name="Structures/Graph.php" role="php"/>
+   <file baseinstalldir="" md5sum="b81f67f7b5600231735243be73625e54" name="publish.sh" role="data"/>
+   <file baseinstalldir="" md5sum="6e782f281c7d0ce27e54b574247073cb" name="package.sh" role="data"/>
+   <file baseinstalldir="" md5sum="7fbc338309ac38fefcd64b04bb903e34" name="LICENSE" role="data"/>
+   <file baseinstalldir="" md5sum="ab23406ec7bfbb2029ca536378ff57db" name="genpackage.xml.pl" role="data"/>
+   <file baseinstalldir="" md5sum="628eb6532a8047bf5962fe24c1c245df" name="docs/tutorials/Structures_Graph/Structures_Graph.pkg" role="doc"/>
+   <file baseinstalldir="" md5sum="a7a1b748bbda6dfa1632bf6078fc8bb6" name="docs/html/todolist.html" role="doc"/>
+   <file baseinstalldir="" md5sum="78e1e7ec43a6e754cf4d5dace48fe18c" name="docs/html/Structures_Graph/_Structures_Graph_php.html" role="doc"/>
+   <file baseinstalldir="" md5sum="09cb6d17f96553bfb66b99c502676844" name="docs/html/Structures_Graph/_Structures_Graph_Node_php.html" role="doc"/>
+   <file baseinstalldir="" md5sum="c45890d45dd42dc56adb71988c3a45c1" name="docs/html/Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html" role="doc"/>
+   <file baseinstalldir="" md5sum="c46e6566be5249811667ddc7decf405f" name="docs/html/Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html" role="doc"/>
+   <file baseinstalldir="" md5sum="3fa477998b281061361c4d98fb78c3a8" name="docs/html/Structures_Graph/tutorial_Structures_Graph.pkg.html" role="doc"/>
+   <file baseinstalldir="" md5sum="afb0e3afb91beafd1bc16a07ac31c826" name="docs/html/Structures_Graph/Structures_Graph_Node.html" role="doc"/>
+   <file baseinstalldir="" md5sum="fefb65755d57a87d2736e058a1095b03" name="docs/html/Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html" role="doc"/>
+   <file baseinstalldir="" md5sum="1ed0ac55530b7504c00df35f335e7ef3" name="docs/html/Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html" role="doc"/>
+   <file baseinstalldir="" md5sum="a17210dd27171316f5cb446a5bef59ab" name="docs/html/Structures_Graph/Structures_Graph.html" role="doc"/>
+   <file baseinstalldir="" md5sum="005081a4c5d60afcbabc1f4909ebfcad" name="docs/html/packages.html" role="doc"/>
+   <file baseinstalldir="" md5sum="8ff124484e8a009f94a8d0b4d9b8b1cd" name="docs/html/media/stylesheet.css" role="doc"/>
+   <file baseinstalldir="" md5sum="039cb8781dae7b5f5661dc2892fb53b5" name="docs/html/media/banner.css" role="doc"/>
+   <file baseinstalldir="" md5sum="4ec087627323546610b64d69a6aafca6" name="docs/html/li_Structures_Graph.html" role="doc"/>
+   <file baseinstalldir="" md5sum="db3206e7d176ae78fd04f22acead5ffa" name="docs/html/index.html" role="doc"/>
+   <file baseinstalldir="" md5sum="ae809f6ebbf632351648c340d2d6acd4" name="docs/html/errors.html" role="doc"/>
+   <file baseinstalldir="" md5sum="19dd287d44163d2abde1a1d8d52521f8" name="docs/html/elementindex_Structures_Graph.html" role="doc"/>
+   <file baseinstalldir="" md5sum="898dd26ccc1c1572d36e9879afcb5d39" name="docs/html/elementindex.html" role="doc"/>
+   <file baseinstalldir="" md5sum="d0ada99c3b7e95b23461cc3e713f0c3d" name="docs/html/classtrees_Structures_Graph.html" role="doc"/>
+   <file baseinstalldir="" md5sum="ce2da39dbb75e21074eb5e96231a3379" name="docs/generate.sh" role="doc"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>4.2.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.3</min>
+   </pearinstaller>
+  </required>
+ </dependencies>
+ <phprelease>
+  <changelog>
+   <release>
+    <version>
+     <release>1.0.2</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2007-01-07</date>
+    <license uri="http://opensource.org/licenses/lgpl-license.php">LGPL</license>
+    <notes>- Bug #9682 only variables can be returned by reference
+- fix Bug #9661 notice in Structures_Graph_Manipulator_Topological::sort()</notes>
+   </release>
+  </changelog>
+ </phprelease>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.php.net/XML_Util/1.2.1-info.xml b/lib/.xmlregistry/packages/pear.php.net/XML_Util/1.2.1-info.xml
new file mode 100644
index 00000000..b015a947
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.php.net/XML_Util/1.2.1-info.xml
@@ -0,0 +1,404 @@
+<?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.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>XML_Util</name>
+ <channel>pear.php.net</channel>
+ <summary>XML utility class</summary>
+ <description>Selection of methods that are often needed when working with XML documents.  Functionality includes creating of attribute lists from arrays, creation of tags, validation of XML names and more.</description>
+ <lead>
+  <name>Chuck Burgess</name>
+  <user>ashnazg</user>
+  <email>ashnazg@php.net</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Stephan Schmidt</name>
+  <user>schst</user>
+  <email>schst@php-tools.net</email>
+  <active>no</active>
+ </lead>
+ <helper>
+  <name>Davey Shafik</name>
+  <user>davey</user>
+  <email>davey@php.net</email>
+  <active>no</active>
+ </helper>
+ <date>2010-01-27</date>
+ <time>10:08:51</time>
+ <version>
+  <release>1.2.1</release>
+  <api>1.2.0</api>
+ </version>
+ <stability>
+  <release>stable</release>
+  <api>stable</api>
+ </stability>
+ <license uri="http://opensource.org/licenses/bsd-license">BSD License</license>
+ <notes>Fixed Bug #14760: Bug in getDocTypeDeclaration() [ashnazg|fpospisil]</notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="XML" md5sum="9bb265dafaaf06c86ca5c48f50368ded" name="Util.php" role="php">
+    <tasks:replace from="@version@" to="version" type="package-info"/>
+   </file>
+   <file baseinstalldir="XML" md5sum="b4127883df40a4b0d1736ad42215ee25" name="tests/testBug_5392.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="1850856692ff6c6df5e8acb16e1080ce" name="tests/testBug_4950.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="ab035534463cae8cc903e907aead8ffe" name="tests/testBasic_splitQualifiedName.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="431856aa83a23396a9f00915dd2be192" name="tests/testBasic_reverseEntities.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="e6717d43001775cccd52bd5195cf02e0" name="tests/testBasic_replaceEntities.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="300a6192f7cc6f7bc3d8f2576b51e4b0" name="tests/testBasic_raiseError.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="a727860d55c14194fdaffa839a59a540" name="tests/testBasic_isValidName.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="5bc1926a488a6b63ec6366bfcf06a50a" name="tests/testBasic_getXmlDeclaration.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="817882a0ab33e60f17ee71874ad975f0" name="tests/testBasic_getDocTypeDeclaration.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="d2792da0d9c5f0987ee4587912017aa9" name="tests/testBasic_createTagFromArray.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="5f453edadebaa3435c8e6f09a3aaaa9c" name="tests/testBasic_createTag.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="ad786fb687e1eea1f6890a7424709c79" name="tests/testBasic_createStartElement.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="ba75d66c2f0fb0010c71f3bcd1f64eb2" name="tests/testBasic_createEndElement.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="c101844768f146653c59c81978060158" name="tests/testBasic_createComment.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="4c87fda94fdfb7a78ba84998d6e28f45" name="tests/testBasic_createCDataSection.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="dc4202f1451bbeb62a5bc7d56a7c774c" name="tests/testBasic_collapseEmptyTags.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="4b17c0df7fbfb1bb2f3f636ebd6c2cbd" name="tests/testBasic_attributesToString.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="73088689d58b71cd4f86013c88b72216" name="tests/testBasic_apiVersion.phpt" role="test"/>
+   <file baseinstalldir="XML" md5sum="0af0cff09232a6c275803bb36213cdd9" name="tests/AllTests.php" role="test"/>
+   <file baseinstalldir="XML" md5sum="77355702c9e861d3fc0a5318ea689eee" name="examples/example2.php" role="doc"/>
+   <file baseinstalldir="XML" md5sum="06b6662b91b1a466e7b5113f37d4725f" name="examples/example.php" role="doc"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>4.3.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.3</min>
+   </pearinstaller>
+   <extension>
+    <name>pcre</name>
+   </extension>
+  </required>
+ </dependencies>
+ <phprelease>
+  <changelog>
+   <release>
+    <version>
+     <release>1.2.1</release>
+     <api>1.2.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2008-12-07</date>
+    <license uri="http://opensource.org/licenses/bsd-license">BSD License</license>
+    <notes>Fixed Bug #14760: Bug in getDocTypeDeclaration() [ashnazg|fpospisil]</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.2.0</release>
+     <api>1.2.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2008-07-26</date>
+    <license uri="http://opensource.org/licenses/bsd-license">BSD License</license>
+    <notes>Changed license to New BSD License (Req #13826 [ashnazg])
+Added a test suite against all API methods [ashnazg]
+Switch to package.xml v2 [ashnazg]
+Added Req #13839: Missing XHTML empty tags to collapse [ashnazg|drry]
+Fixed Bug #5392: encoding of ISO-8859-1 is the only supported encoding [ashnazg]
+Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|drry]
+-- (this fix differs from the one in v1.2.0a1)</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.2.0RC1</release>
+     <api>1.2.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-07-12</date>
+    <license uri="http://opensource.org/licenses/bsd-license">BSD License</license>
+    <notes>Changed license to New BSD License (Req #13826 [ashnazg])
+Added a test suite against all API methods [ashnazg]
+Switch to package.xml v2 [ashnazg]
+Added Req #13839: Missing XHTML empty tags to collapse [ashnazg|drry]
+Fixed Bug #5392: encoding of ISO-8859-1 is the only supported encoding [ashnazg]
+Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|drry]
+-- (this fix differs from the one in v1.2.0a1)</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.2.0a2</release>
+     <api>1.2.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2008-05-22</date>
+    <license uri="http://opensource.org/licenses/bsd-license">BSD License</license>
+    <notes>Changed license to New BSD License (Req #13826 [ashnazg])
+Added a test suite against all API methods [ashnazg]
+Switch to package.xml v2 [ashnazg]
+Added Req #13839: Missing XHTML empty tags to collapse [ashnazg|drry]
+Fixed Bug #5392: encoding of ISO-8859-1 is the only supported encoding [ashnazg]
+Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|drry]
+-- (this fix differs from the one in v1.2.0a1)</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.2.0a1</release>
+     <api>1.2.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2008-05-04</date>
+    <license uri="http://opensource.org/licenses/bsd-license">BSD License</license>
+    <notes>Changed license to New BSD License (Req #13826 [ashnazg])
+Added a test suite against all API methods [ashnazg]
+Switch to package.xml v2 [ashnazg]
+Fixed Bug #4950: Incorrect CDATA serializing [ashnazg|ja.doma]</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.1.4</release>
+     <api>1.1.4</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2006-12-16</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>- Fixed bug #9561: Not allowing underscores in middle of tags</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.1.2</release>
+     <api>1.1.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2006-12-01</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>- fixed bug #5419: isValidName() now checks for character classes
+- implemented request #8196: added optional parameter to influence array sorting to createTag() createTagFromArray() and createStartElement()</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.1.1</release>
+     <api>1.1.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2004-12-23</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>- fixed bug in replaceEntities() and reverseEntities() in conjunction with XML_UTIL_ENTITIES_HTML
+- createTag() and createTagFromArray() now accept XML_UTIL_ENTITIES_XML, XML_UTIL_ENTITIES_XML_REQUIRED, XML_UTIL_ENTITIES_HTML, XML_UTIL_ENTITIES_NONE and XML_UTIL_CDATA_SECTION as $replaceEntities parameter</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.1.0</release>
+     <api>1.1.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2004-11-19</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>- Added collapseEmptyTags (patch by Sebastian Bergmann and Thomas Duffey)</notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2004-10-28</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>- Added reverseEntities() (request #2639)</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.6.1</release>
+     <api>0.6.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2004-10-28</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>- Added check for tag name (either as local part or qualified name) in createTagFromArray() (bug #1083)</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.6.0</release>
+     <api>0.6.0</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2004-06-07</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>- Fixed bug 1438 (namespaces not accepted for isValidName()) (thanks to davey)
+- added optional parameter to replaceEntities() to define the set of entities to replace
+- added optional parameter to attributesToString() to define, whether entities should be replaced (requested by Sebastian Bergmann)
+- allowed second parameter to XML_Util::attributesToString() to be an array containing options (easier to use, if you only need to set the last parameter)
+- introduced XML_Util::raiseError() to avoid the necessity of including PEAR.php, will only be included on error</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.6.0beta1</release>
+     <api>0.6.0beta1</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2004-05-24</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>- Fixed bug 1438 (namespaces not accepted for isValidName()) (thanks to davey)
+- added optional parameter to replaceEntities() to define the set of entities to replace
+- added optional parameter to attributesToString() to define, whether entities should be replaced (requested by Sebastian Bergmann)
+- allowed second parameter to XML_Util::attributesToString() to be an array containing options (easier to use, if you only need to set the last parameter)
+- introduced XML_Util::raiseError() to avoid the necessity of including PEAR.php, will only be included on error</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.5.2</release>
+     <api>0.5.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-11-22</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>now creates XHTML compliant empty tags (Davey),
+minor whitespace fixes (Davey)</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.5.1</release>
+     <api>0.5.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-09-26</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>added default namespace parameter (optional) in splitQualifiedName() (requested by Sebastian Bergmann)</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.5</release>
+     <api>0.5</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-09-23</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>added support for multiline attributes in attributesToString(), createTag*() and createStartElement (requested by Yavor Shahpasov for XML_Serializer),
+added createComment</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.4</release>
+     <api>0.4</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-09-21</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>added createCDataSection(),
+added support for CData sections in createTag* methods,
+fixed bug #23,
+fixed bug in splitQualifiedName()</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.3</release>
+     <api>0.3</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-09-12</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>added createStartElement() and createEndElement()</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.2.1</release>
+     <api>0.2.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-09-05</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>fixed bug with zero as tag content in createTagFromArray and createTag</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.2</release>
+     <api>0.2</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-08-12</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>added XML_Util::getDocTypeDeclaration()</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1.1</release>
+     <api>0.1.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-08-02</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>bugfix: removed bug in createTagFromArray</notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1</release>
+     <api>0.1</api>
+    </version>
+    <stability>
+     <release>stable</release>
+     <api>stable</api>
+    </stability>
+    <date>2003-08-01</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>inital release</notes>
+   </release>
+  </changelog>
+ </phprelease>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.unl.edu/UNL_DWT/0.7.1-info.xml b/lib/.xmlregistry/packages/pear.unl.edu/UNL_DWT/0.7.1-info.xml
new file mode 100644
index 00000000..506d8cce
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.unl.edu/UNL_DWT/0.7.1-info.xml
@@ -0,0 +1,224 @@
+<?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.8.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>UNL_DWT</name>
+ <channel>pear.unl.edu</channel>
+ <summary>This package generates php class files (objects) from Dreamweaver template files.</summary>
+ <description>This package generates php class files (objects) from Dreamweaver template files.</description>
+ <lead>
+  <name>Brett Bieber</name>
+  <user>saltybeagle</user>
+  <email>brett.bieber@gmail.com</email>
+  <active>yes</active>
+ </lead>
+ <date>2010-01-27</date>
+ <time>10:09:00</time>
+ <version>
+  <release>0.7.1</release>
+  <api>0.7.1</api>
+ </version>
+ <stability>
+  <release>beta</release>
+  <api>beta</api>
+ </stability>
+ <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD</license>
+ <notes>
+Declare debug method correctly as static.
+ </notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="/" md5sum="d1fe9ae1c22c92cda6d57b9847fda7b2" name="UNL/DWT/Scanner.php" role="php"/>
+   <file baseinstalldir="/" md5sum="be81db10741075600fc87ebbc4c4ca53" name="UNL/DWT/Region.php" role="php"/>
+   <file baseinstalldir="/" md5sum="aea406280cedf3a0e9b32ab7ee354b3f" name="UNL/DWT/Generator.php" role="php"/>
+   <file baseinstalldir="/" md5sum="8ccd77b7def177033c20128da938d1ff" name="UNL/DWT/createTemplates.php" role="php"/>
+   <file baseinstalldir="/" md5sum="c8b1f16f587798a1e37574477d2627bd" name="UNL/DWT.php" role="php">
+    <tasks:replace from="@PHP_BIN@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@DOC_DIR@" to="doc_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="b524ef4684be7dba47ed8c245577347a" name="docs/examples/Template_style1.tpl" role="doc"/>
+   <file baseinstalldir="/" md5sum="3f97c4a024dfed9210b14db5068ba7d0" name="docs/examples/Template_style1.php" role="doc"/>
+   <file baseinstalldir="/" md5sum="0d5a4f5ca86e9c2a3c0050f39acbb034" name="docs/examples/template_style1.dwt" role="doc"/>
+   <file baseinstalldir="/" md5sum="fbc254138e8456e983e18c0c02cc7d30" name="docs/examples/scanner_example.php" role="doc"/>
+   <file baseinstalldir="/" md5sum="5d389d72ffe3a15a5dd597cd791a6963" name="docs/examples/example_style1.php" role="doc">
+    <tasks:replace from="@PHP_BIN@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@DOC_DIR@" to="doc_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="783c64aafb491c789fc71a5bf80d1755" name="docs/examples/example.ini" role="doc">
+    <tasks:replace from="@PHP_BIN@" to="php_bin" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@DOC_DIR@" to="doc_dir" type="pear-config"/>
+   </file>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.0.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.3</min>
+   </pearinstaller>
+   <package>
+    <name>UNL_Templates</name>
+    <channel>pear.unl.edu</channel>
+    <max>0.5.2</max>
+    <conflicts/>
+   </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>2006-01-26</date>
+    <license>PHP License</license>
+    <notes>
+First release, only basic functionality.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1.1</release>
+     <api>0.1.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2006-02-06</date>
+    <license>PHP License</license>
+    <notes>
+Added generator options generator_include/eclude_regex and extends and extends_location.
+Create dwt_location and tpl_location if it does not exist yet.
+Remove editable region tags for locked regions.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.1.2</release>
+     <api>0.1.0</api>
+    </version>
+    <stability>
+     <release>alpha</release>
+     <api>alpha</api>
+    </stability>
+    <date>2006-02-24</date>
+    <license>PHP License</license>
+    <notes>
+* Added missing setOption function. Initially only debug option is available.
+* Renamed internally used function between to UNL_DWT_between
+* created externally callable replaceRegions function.
+* debug function for outputting messages levels 0-5.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.5.0</release>
+     <api>0.1.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2006-08-15</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+* Fix Bug #16: Locked regions arent detected correctly.
+				 * Fix Bug #1: Include path modified incorrectly.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.5.1</release>
+     <api>0.1.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-02-07</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+* Switch to using static properties, PHP 5, add docheader.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.6.0</release>
+     <api>0.2.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-03-26</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD</license>
+    <notes>
+Move code around. DWT.php is now in UNL/DWT.php instead of UNL/DWT/DWT.php = not compatible with old versions of UNL_Templates!
+* Switch to using static properties
+* Upgrade a lot of code to PHP 5
+* Add phpdoc headers and coding standards fixes
+* Switch to BSD license.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.6.1</release>
+     <api>0.2.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-04-08</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD</license>
+    <notes>
+Change is_a() to instanceof to fix warning.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.7.0</release>
+     <api>0.7.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-06-30</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD</license>
+    <notes>
+Move region class into separate file.
+Add scanner for simply scanning a dwt for regions, this does not replace the
+generator, but supplements it.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.7.1</release>
+     <api>0.7.1</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2009-07-01</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD</license>
+    <notes>
+Declare debug method correctly as static.
+   </notes>
+   </release>
+  </changelog>
+ </phprelease>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.unl.edu/UNL_Peoplefinder/0.1.0-info.xml b/lib/.xmlregistry/packages/pear.unl.edu/UNL_Peoplefinder/0.1.0-info.xml
new file mode 100644
index 00000000..21affbe5
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.unl.edu/UNL_Peoplefinder/0.1.0-info.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.1" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1" 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.1     http://pear.php.net/dtd/package-2.1.xsd">
+ <name>UNL_Peoplefinder</name>
+ <channel>pear.unl.edu</channel>
+ <summary>The UNL faculty staff and student directory.
+</summary>
+ <description>
+The UNL_Peoplefinder package contains all the source code for the UNL directory.
+Additionally, this package provides an API which developers can use to retrieve
+directory information and perform searches.
+</description>
+ <lead>
+  <name>Brett Bieber</name>
+  <user>saltybeagle</user>
+  <email>brett.bieber@gmail.com</email>
+  <active>yes</active>
+ </lead>
+ <date>2010-01-27</date>
+ <time>10:10:32</time>
+ <version>
+  <release>0.1.0</release>
+  <api>0.1.0</api>
+ </version>
+ <stability>
+  <release>alpha</release>
+  <api>alpha</api>
+ </stability>
+ <license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
+ <notes>Package UNL_Peoplefinder release notes for version 0.1.0.
+
+Basic functionality is available. The default driver uses the
+web service, and no LDAP connection info is required.
+
+
+Package UNL_Peoplefinder API release notes for version 0.1.0.</notes>
+ <contents>
+  <dir name="/">
+   <file role="www" name="www/standardForm.php" md5sum="0bb606ab21c3e7b7ffe2b1927d0157d8"/>
+   <file role="www" name="www/small_devices.css" md5sum="671b2a2b7ff388a6c7a0256a27dc57a7"/>
+   <file role="www" name="www/service.php" md5sum="49caa1e90509e3af7431dd3276b16ed1"/>
+   <file role="www" name="www/README" md5sum="387849598c64632e513c7eefa2155e12"/>
+   <file role="www" name="www/peoplefinder_default.css" md5sum="6f1677797f73b1a31fecba23a6ce11b2"/>
+   <file role="www" name="www/peoplefinder.js" md5sum="bc5c3ec9319cc14f1d3ae22ed731321b"/>
+   <file role="www" name="www/index.php" md5sum="51f36d605af956784f4ab16047dfc02f"/>
+   <file role="www" name="www/images/person.gif" md5sum="833a67d6d816e88d0bfe25b2854d2295"/>
+   <file role="www" name="www/images/mobile.gif" md5sum="c5489ea5b5eb1d8814e2b49f6fdb9cdd"/>
+   <file role="www" name="www/images/icon_question.gif" md5sum="e26a423eed7840f8eece890631e246b9"/>
+   <file role="www" name="www/images/home.gif" md5sum="d2c93d8510e7fc077f9ef7765ff20a89"/>
+   <file role="www" name="www/departments/index.php" md5sum="37bbf184fb9944a5e29c33dd7ce6d323"/>
+   <file role="www" name="www/config.inc.php" md5sum="49d1a921b7b4edb23b1e2e4bdc766000"/>
+   <file role="www" name="www/config-sample.inc.php" md5sum="3b75e12039198b0f51c41a6e7c8360eb"/>
+   <file role="www" name="www/apple-touch-icon.png" md5sum="e182bd1eb8858d0f406187e21d03c6fd"/>
+   <file role="www" name="www/advancedForm.php" md5sum="be5159d40d1cc6f9ed6399089fd748da"/>
+   <file role="test" name="tests/testStudentWithNoLocalAddress.html" md5sum="1636d84da04979ce70d9d46b862f896b"/>
+   <file role="test" name="tests/PeoplefinderTest.php" md5sum="d4da346cb13ca1357ee89b37b59dba6c"/>
+   <file role="test" name="tests/OUTest.php" md5sum="e40ef5265dd4213fdcbfeb0735e1b8b0"/>
+   <file role="test" name="tests/BrowserTest.php" md5sum="9cce4b1ffdbab7375b1cf3f60fb4987d"/>
+   <file role="php" name="src/UNL/Peoplefinder/RendererInterface.php" md5sum="7b52d098c49dd4e9915741ac794d8f4a"/>
+   <file role="php" name="src/UNL/Peoplefinder/Renderer/XML.php" md5sum="9b612809c71a7af3b22de36ea4988b78"/>
+   <file role="php" name="src/UNL/Peoplefinder/Renderer/vCard.php" md5sum="7c9aeb7c9a898849c173dd894f0f3a05"/>
+   <file role="php" name="src/UNL/Peoplefinder/Renderer/Serialized.php" md5sum="b7edf78a1f82cd2e790e879462ae5dd3"/>
+   <file role="php" name="src/UNL/Peoplefinder/Renderer/JSON.php" md5sum="7fa212209cb5e86cb2aefda0b2fca12d"/>
+   <file role="php" name="src/UNL/Peoplefinder/Renderer/HTML.php" md5sum="9f2789e9724ce6d8033be663c9ed4131"/>
+   <file role="php" name="src/UNL/Peoplefinder/Record.php" md5sum="7071048e5e91575c01ccb92019c7cafe"/>
+   <file role="php" name="src/UNL/Peoplefinder/DriverInterface.php" md5sum="8f211374f1a6609f9609ea90c74afcba"/>
+   <file role="php" name="src/UNL/Peoplefinder/Driver/WebService.php" md5sum="5abd2c0936d173df09c1a36cbd4ee510"/>
+   <file role="php" name="src/UNL/Peoplefinder/Driver/LDAP/Util.php" md5sum="7dc7a0423d62a6e193523d84ad89f4af"/>
+   <file role="php" name="src/UNL/Peoplefinder/Driver/LDAP/TelephoneFilter.php" md5sum="6cfe4455d67a76d642dc4b8239e367ac"/>
+   <file role="php" name="src/UNL/Peoplefinder/Driver/LDAP/StandardFilter.php" md5sum="87b019a6a8a57d0bdfe37145800e23d6"/>
+   <file role="php" name="src/UNL/Peoplefinder/Driver/LDAP/OUFilter.php" md5sum="7028b5a762580c32c76f70c8ccdd14bc"/>
+   <file role="php" name="src/UNL/Peoplefinder/Driver/LDAP/AdvancedFilter.php" md5sum="4547ed66c563bd0f8b24d1f07728dbfd"/>
+   <file role="php" name="src/UNL/Peoplefinder/Driver/LDAP.php" md5sum="5b2d241e70cccdff56d6504691fad864"/>
+   <file role="php" name="src/UNL/Peoplefinder/Department/Search.php" md5sum="3c3a87e9fc95a53231dd408b45c82d0a"/>
+   <file role="php" name="src/UNL/Peoplefinder/Department.php" md5sum="763b1e19c28712a251c1552857cf8e7d"/>
+   <file role="php" name="src/UNL/Peoplefinder.php" md5sum="86236345234234cc5a4dd1e66a2e8393"/>
+   <file role="doc" name="examples/getUID.php" md5sum="b2e8620bc6e9b9ce921ebea48bab3133"/>
+   <file role="doc" name="examples/getLikeMatches.php" md5sum="ff695239f9295eabaa187cf74e056408"/>
+   <file role="doc" name="examples/getExactMatches.php" md5sum="187f8be90f09db8cb49a7aec912be8c4"/>
+   <file role="doc" name="examples/config.inc.php" md5sum="8aa9afd73dcf4178a8214b98eb2c5771"/>
+   <file role="data" name="data/hr_tree.xml" md5sum="d9962fcbef0e4e6ed3869f9dc4843899"/>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.2.0</min>
+   </php>
+   <pearinstaller>
+    <min>2.0.0a1</min>
+   </pearinstaller>
+  </required>
+ </dependencies>
+ <phprelease/>
+</package>
diff --git a/lib/.xmlregistry/packages/pear.unl.edu/UNL_Templates/1.0.0RC9-info.xml b/lib/.xmlregistry/packages/pear.unl.edu/UNL_Templates/1.0.0RC9-info.xml
new file mode 100644
index 00000000..4b1688f1
--- /dev/null
+++ b/lib/.xmlregistry/packages/pear.unl.edu/UNL_Templates/1.0.0RC9-info.xml
@@ -0,0 +1,742 @@
+<?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>UNL_Templates</name>
+ <channel>pear.unl.edu</channel>
+ <summary>The UNL HTML Templates as a PEAR Package.</summary>
+ <description>This package allows you to render UNL Template styled pages using PHP Objects.</description>
+ <lead>
+  <name>Brett Bieber</name>
+  <user>saltybeagle</user>
+  <email>brett.bieber@gmail.com</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Ned Hummel</name>
+  <user>nhummel2</user>
+  <email>nhummel2@math.unl.edu</email>
+  <active>yes</active>
+ </lead>
+ <date>2010-01-27</date>
+ <time>10:09:00</time>
+ <version>
+  <release>1.0.0RC9</release>
+  <api>1.0.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>
+Feature Release!
+Added support for specifying the template version, 2 or 3.
+* UNL_Templates::$options['version'] = 3; to use the new templates.
+* Added the secure template.
+* Add debug template.
+* Updated Version 3 templates to reflect footer changes.
+
+Additional work to prevent broken pages.
+* If local files are not present for the &lt;!--#include statements, it will grab them remotely.
+* If wdn/templates_3.0 does not exist locally it will use a template with absolute references to prevent broken pages.
+
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $media = 'all')
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+* contactinfo=&gt;footerContactInfo.html
+
+New Remote Template Scanner UNL_Templates_Scanner
+* Scans a rendered UNL Template page for the editable content areas.
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+* Remove debug code causing cache to never be used.
+* Fix debugging.
+* Merge UNL_DWT::$options with options from ini file instead of overwriting.
+* Set default timezone to use before we use date functions.
+* Add newlines after header additions.
+* Fix addScriptDeclaration method to comment out CDATA to prevent syntax errors.
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+ </notes>
+ <contents>
+  <dir name="/">
+   <file baseinstalldir="/" md5sum="f9b3c237b7a6b8500ef0d18f4e1c9595" name="UNL/Templates/Version3/Shared_column_right.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="c8e40b9ff760f0d6da578f6f52e85ab2" name="UNL/Templates/Version3/Shared_column_left.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="e6bcc877d8fe24beb229aec454710e5e" name="UNL/Templates/Version3/Secure.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="1d63a45e6f7e86585182a09ff8e33962" name="UNL/Templates/Version3/Popup.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="5ae65bf4c045a5b9b65b726b52d6cd26" name="UNL/Templates/Version3/Liquid.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="041aae52a187c4986e495a8643b43ae4" name="UNL/Templates/Version3/Fixed.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="01035abd6b488663747399e74d0065bc" name="UNL/Templates/Version3/Document.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="05eb7e3f0639e79aeb2e4f5061a356f1" name="UNL/Templates/Version3/Debug.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="315f0d6be4459208f7733e6e29f99c91" name="UNL/Templates/Version3/Absolute.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="f307432bd99d2cccc6ed4fca2782604e" name="UNL/Templates/Version3.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="48a0fd1e66226418db0c7c5202343881" name="UNL/Templates/Version2/Unlstandardtemplate.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="e902fc42cdcb7633fbe07f4d509a1b97" name="UNL/Templates/Version2/Unlframework.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="bdac0dc69918a491efcee2450d99738f" name="UNL/Templates/Version2/Unlaffiliate.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="f43c4b5320cf2def6d90c71f3e22c1fb" name="UNL/Templates/Version2/Secure.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="0a1b634408248289e89649a49bd7759c" name="UNL/Templates/Version2/Popup.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="55c715aa91f18226f5be4c3f427b2dea" name="UNL/Templates/Version2/Liquid.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="3fbccc1b6e7a0287577972b4c25a0d19" name="UNL/Templates/Version2/Fixed.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="ef2068426bb8f73ac706b18a472df967" name="UNL/Templates/Version2/Document.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="44c17f55c20fce235d7d2556dc43b23c" name="UNL/Templates/Version2.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="c7df0501ec102431d7be6a6cfd133b5b" name="UNL/Templates/Version.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="82740c1fadfd1160bb9c67006947ab3b" name="UNL/Templates/Scanner.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="5b09b184e7d59a2520e99c0b5c66428a" name="UNL/Templates/CachingService/CacheLite.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="07884c3a9bf75657e54782423a088eb4" name="UNL/Templates/CachingService.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="66cf2ca7074e1ae7d602e94a438ff95a" name="UNL/Templates.php" role="php">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="12aa5989d1255dccc299a3dcdd6c6ba8" name="tests/UNL_TemplatesTest.php" role="test">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="9a7ce82868ddb7afc2b291b0b0ec6bd1" name="docs/examples/scanner.php" role="doc">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="3c1307e7a73e10f1af082ec3a48e481f" name="docs/examples/example1.php" role="doc">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="e9769bdf0cf9ec36430b3f70ec687037" name="docs/examples/customization/customization_example.php" role="doc">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="26c8d867af8ffd4d8d60e348573f9c3d" name="docs/examples/customization/customization_example.html" role="doc">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="7e35aab85f95ad61fe43e50fbf1719a2" name="docs/examples/customization/CustomClass.php" role="doc">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="742720269e3488e0fa34f0ad53b2cb00" name="data/tpl_cache/Version3/Shared_column_right.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="d33744a26d2f229c5b9172557733f35f" name="data/tpl_cache/Version3/Shared_column_left.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="3d0a70139d0d736d7b5a1c9db203407f" name="data/tpl_cache/Version3/Secure.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="806405f82ed8f12e584e44b6f8d42dc8" name="data/tpl_cache/Version3/Popup.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="962756c965f0f2881e88c83a72fe0545" name="data/tpl_cache/Version3/Liquid.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="d264bf1f5ae2655836aa69a8bcfbd4e6" name="data/tpl_cache/Version3/Fixed.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="636db467eaccd481f1697e85b4f1d814" name="data/tpl_cache/Version3/Document.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="deae0c7ac5529cdc5713e11febd022f0" name="data/tpl_cache/Version3/Debug.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="8d735ef7de849049870801a47d7098e2" name="data/tpl_cache/Version3/Absolute.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="2082f29e6219b9fdad0faffb2bf9a427" name="data/tpl_cache/Version2/Unlstandardtemplate.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="465cb4e7eef89560faf0c63065d8a9d3" name="data/tpl_cache/Version2/Unlframework.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="9f4650a475623a3cf293998c0e5b3233" name="data/tpl_cache/Version2/Unlaffiliate.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="962fecd9908d504e4749f7eb79dc4736" name="data/tpl_cache/Version2/Secure.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="a70442037d218c0dc948638bca8e5e08" name="data/tpl_cache/Version2/Popup.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="1a936fdcd4d17383490bd5aef1219ce8" name="data/tpl_cache/Version2/Liquid.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="df5ce334e93b844794699f3cc62d20b9" name="data/tpl_cache/Version2/Fixed.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+   <file baseinstalldir="/" md5sum="61cc4ae92fac84a7d38131769c2298ba" name="data/tpl_cache/Version2/Document.tpl" role="data">
+    <tasks:replace from="@DATA_DIR@" to="data_dir" type="pear-config"/>
+    <tasks:replace from="@PHP_DIR@" to="php_dir" type="pear-config"/>
+   </file>
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.0.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.3</min>
+   </pearinstaller>
+   <package>
+    <name>Cache_Lite</name>
+    <channel>pear.php.net</channel>
+    <min>1.0</min>
+   </package>
+   <package>
+    <name>UNL_DWT</name>
+    <channel>pear.unl.edu</channel>
+    <min>0.7.1</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>2006-03-02</date>
+    <license>PHP License</license>
+    <notes>
+First release, only basic functionality, we assume you have /unlpub/templatedependents/ set up on your server already.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.5.0</release>
+     <api>0.5.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2006-08-14</date>
+    <license uri="http://www.php.net/license">PHP License</license>
+    <notes>
+Updates the package to use the new 2006-08 UNL Templates. Template dependents /ucomm/templatedependents/ are still required outside of this package. Added new replacement functions to handle the template dependent replacements.
+		Removed evalPHPFile function... not needed anymore.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.5.1</release>
+     <api>0.5.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2007-01-05</date>
+    <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD License</license>
+    <notes>
+Change license to BSD, update tpl_cache to UNL Templates created on 2007-01-05. No other changes.
+	All users with previous versions do not need to upgrade because the server will automatically serve out new tpl files.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>0.5.2</release>
+     <api>0.5.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2007-11-29</date>
+    <license uri="http://www.opensource.org/licenses/bsd-license.php">BSD License</license>
+    <notes>
+Add check that file can actually be opened.
+No other changes.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0RC1</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-03-26</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+Feature Release!
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $type = 'text/css', $media = null)
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+
+Thanks to Ned Hummel for picking up this baby.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0RC2</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-06-30</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+Feature Release!
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $media = 'all')
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+* Remove debug code causing cache to never be used.
+* Fix debugging.
+* Merge UNL_DWT::$options with options from ini file instead of overwriting.
+* Set default timezone to use before we use date functions.
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+
+Thanks to Ned Hummel for picking up this baby.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0RC3</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-06-30</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+Feature Release!
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $media = 'all')
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+
+New Remote Template Scanner UNL_Templates_Scanner
+* Scans a rendered UNL Template page for the editable content areas.
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+* Remove debug code causing cache to never be used.
+* Fix debugging.
+* Merge UNL_DWT::$options with options from ini file instead of overwriting.
+* Set default timezone to use before we use date functions.
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+
+Thanks to Ned Hummel for picking up this baby.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0RC4</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2008-11-06</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+Feature Release!
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $media = 'all')
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+
+New Remote Template Scanner UNL_Templates_Scanner
+* Scans a rendered UNL Template page for the editable content areas.
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+* Remove debug code causing cache to never be used.
+* Fix debugging.
+* Merge UNL_DWT::$options with options from ini file instead of overwriting.
+* Set default timezone to use before we use date functions.
+* Add newlines after header additions.
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+
+Thanks to Ned Hummel for picking up this baby.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0RC5</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2009-07-01</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+Feature Release!
+Added support for specifying the template version, 2 or 3.
+* UNL_Templates::$options['version'] = 3; to use the new templates.
+
+Additional work to prevent broken pages.
+* If local files are not present for the &lt;!--#include statements, it will grab them remotely.
+* If wdn/templates_3.0 does not exist locally it will use a template with absolute references to prevent broken pages.
+
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $media = 'all')
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+
+New Remote Template Scanner UNL_Templates_Scanner
+* Scans a rendered UNL Template page for the editable content areas.
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+* Remove debug code causing cache to never be used.
+* Fix debugging.
+* Merge UNL_DWT::$options with options from ini file instead of overwriting.
+* Set default timezone to use before we use date functions.
+* Add newlines after header additions.
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0RC6</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2009-07-13</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+Feature Release!
+Added support for specifying the template version, 2 or 3.
+* UNL_Templates::$options['version'] = 3; to use the new templates.
+
+Additional work to prevent broken pages.
+* If local files are not present for the &lt;!--#include statements, it will grab them remotely.
+* If wdn/templates_3.0 does not exist locally it will use a template with absolute references to prevent broken pages.
+
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $media = 'all')
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+
+New Remote Template Scanner UNL_Templates_Scanner
+* Scans a rendered UNL Template page for the editable content areas.
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+* Remove debug code causing cache to never be used.
+* Fix debugging.
+* Merge UNL_DWT::$options with options from ini file instead of overwriting.
+* Set default timezone to use before we use date functions.
+* Add newlines after header additions.
+* Fix addScriptDeclaration method to comment out CDATA to prevent syntax errors.
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0RC7</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2009-07-29</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+Feature Release!
+Added support for specifying the template version, 2 or 3.
+* UNL_Templates::$options['version'] = 3; to use the new templates.
+* Added the secure template.
+* Updated Version 3 templates to reflect footer changes.
+
+Additional work to prevent broken pages.
+* If local files are not present for the &lt;!--#include statements, it will grab them remotely.
+* If wdn/templates_3.0 does not exist locally it will use a template with absolute references to prevent broken pages.
+
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $media = 'all')
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+
+New Remote Template Scanner UNL_Templates_Scanner
+* Scans a rendered UNL Template page for the editable content areas.
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+* Remove debug code causing cache to never be used.
+* Fix debugging.
+* Merge UNL_DWT::$options with options from ini file instead of overwriting.
+* Set default timezone to use before we use date functions.
+* Add newlines after header additions.
+* Fix addScriptDeclaration method to comment out CDATA to prevent syntax errors.
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0RC8</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2009-08-12</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+Feature Release!
+Added support for specifying the template version, 2 or 3.
+* UNL_Templates::$options['version'] = 3; to use the new templates.
+* Added the secure template.
+* Updated Version 3 templates to reflect footer changes.
+
+Additional work to prevent broken pages.
+* If local files are not present for the &lt;!--#include statements, it will grab them remotely.
+* If wdn/templates_3.0 does not exist locally it will use a template with absolute references to prevent broken pages.
+
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $media = 'all')
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+* contactinfo=&gt;footerContactInfo.html
+
+New Remote Template Scanner UNL_Templates_Scanner
+* Scans a rendered UNL Template page for the editable content areas.
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+* Remove debug code causing cache to never be used.
+* Fix debugging.
+* Merge UNL_DWT::$options with options from ini file instead of overwriting.
+* Set default timezone to use before we use date functions.
+* Add newlines after header additions.
+* Fix addScriptDeclaration method to comment out CDATA to prevent syntax errors.
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+   </notes>
+   </release>
+   <release>
+    <version>
+     <release>1.0.0RC9</release>
+     <api>1.0.0</api>
+    </version>
+    <stability>
+     <release>beta</release>
+     <api>beta</api>
+    </stability>
+    <date>2009-09-10</date>
+    <license uri="http://www1.unl.edu/wdn/wiki/Software_License">BSD License</license>
+    <notes>
+Feature Release!
+Added support for specifying the template version, 2 or 3.
+* UNL_Templates::$options['version'] = 3; to use the new templates.
+* Added the secure template.
+* Add debug template.
+* Updated Version 3 templates to reflect footer changes.
+
+Additional work to prevent broken pages.
+* If local files are not present for the &lt;!--#include statements, it will grab them remotely.
+* If wdn/templates_3.0 does not exist locally it will use a template with absolute references to prevent broken pages.
+
+New methods:
+* addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+* addScript($url, $type = 'text/javascript')
+* addScriptDeclaration($content, $type = 'text/javascript')
+* addStyleDeclaration($content, $type = 'text/css')
+* addStyleSheet($url, $media = 'all')
+* __toString()  Now you can just use echo $page;
+
+Auto loading of files - now supporting:
+* optionalfooter=&gt;optionalFooter.html
+* collegenavigationlist=&gt;unitNavigation.html
+* contactinfo=&gt;footerContactInfo.html
+
+New Remote Template Scanner UNL_Templates_Scanner
+* Scans a rendered UNL Template page for the editable content areas.
+
+Other fixes:
+* Use static vars instead of PEAR::getStaticProperty() - fixes E_STRICT warnings
+* Remove debug code causing cache to never be used.
+* Fix debugging.
+* Merge UNL_DWT::$options with options from ini file instead of overwriting.
+* Set default timezone to use before we use date functions.
+* Add newlines after header additions.
+* Fix addScriptDeclaration method to comment out CDATA to prevent syntax errors.
+
+Add example of a custom class with auto-breadcrumb generation and body content loading.
+   </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 00000000..6eee6894
--- /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>2010-01-27</date>
+ <time>10:06:31</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/PEAR/package.dtd b/lib/data/PEAR/package.dtd
new file mode 100644
index 00000000..5b471b7f
--- /dev/null
+++ b/lib/data/PEAR/package.dtd
@@ -0,0 +1,103 @@
+<!--
+     $Id: package.dtd,v 1.38 2005-11-12 02:23:07 cellog Exp $
+
+     This is the PEAR package description, version 1.0.
+     It should be used with the informal public identifier:
+
+         "-//PHP Group//DTD PEAR Package 1.0//EN//XML"
+
+     Copyright (c) 1997-2005 The PHP Group             
+
+     This source file is subject to version 3.00 of the PHP license,
+     that is bundled with this package in the file LICENSE, and is
+     available at through the world-wide-web at
+     http://www.php.net/license/3_0.txt. 
+     If you did not receive a copy of the PHP license and are unable to
+     obtain it through the world-wide-web, please send a note to
+     license@php.net so we can mail you a copy immediately.
+
+     Authors:
+         Stig S. Bakken <ssb@fast.no>
+         Gregory Beaver <cellog@php.net>
+
+  -->
+<!ENTITY % NUMBER "CDATA">
+<!ELEMENT package (name,summary,description,license?,maintainers,release,changelog?)>
+<!ATTLIST package type    (source|binary|empty) "empty"
+                  version CDATA                 #REQUIRED
+                  packagerversion CDATA         #IMPLIED>
+
+<!ELEMENT name (#PCDATA)>
+
+<!ELEMENT summary (#PCDATA)>
+
+<!ELEMENT license (#PCDATA)>
+
+<!ELEMENT description (#PCDATA)>
+
+<!ELEMENT maintainers (maintainer)+>
+
+<!ELEMENT maintainer (user|role|name|email)+>
+
+<!ELEMENT user (#PCDATA)>
+
+<!ELEMENT role (#PCDATA)>
+
+<!ELEMENT email (#PCDATA)>
+
+<!ELEMENT changelog (release)+>
+
+<!ELEMENT release (version,date,license,state,notes,warnings?,provides*,deps?,configureoptions?,filelist?)>
+
+<!ELEMENT version (#PCDATA)>
+
+<!ELEMENT date (#PCDATA)>
+
+<!ELEMENT state (#PCDATA)>
+
+<!ELEMENT notes (#PCDATA)>
+
+<!ELEMENT warnings (#PCDATA)>
+
+<!ELEMENT deps (dep*)>
+
+<!ELEMENT dep (#PCDATA)>
+<!ATTLIST dep type    (pkg|ext|php) #REQUIRED
+	                       rel     (has|eq|lt|le|gt|ge)                          #IMPLIED
+	                       version CDATA                                     #IMPLIED
+	                       optional (yes|no)     'no'>
+
+<!ELEMENT configureoptions (configureoption)+>
+
+<!ELEMENT configureoption EMPTY>
+<!ATTLIST configureoption name CDATA #REQUIRED
+                                           default CDATA #IMPLIED
+                                           prompt CDATA #REQUIRED>
+
+<!ELEMENT provides EMPTY>
+<!ATTLIST provides type (ext|prog|class|function|feature|api) #REQUIRED
+                                name CDATA #REQUIRED
+                                extends CDATA #IMPLIED>
+<!ELEMENT filelist (dir|file)+>
+
+<!ELEMENT dir (dir|file)+>
+<!ATTLIST dir name           CDATA #REQUIRED
+              role           (php|ext|src|test|doc|data|script) 'php'
+              baseinstalldir CDATA #IMPLIED>
+
+<!ELEMENT file (replace*)>
+<!ATTLIST file role           (php|ext|src|test|doc|data|script) 'php'
+               debug          (na|on|off)        'na'
+               format         CDATA              #IMPLIED
+               baseinstalldir CDATA              #IMPLIED
+               platform       CDATA              #IMPLIED
+               md5sum         CDATA              #IMPLIED
+               name           CDATA              #REQUIRED
+               install-as     CDATA              #IMPLIED>
+
+<!ELEMENT replace EMPTY>
+<!ATTLIST replace type (php-const|pear-config|package-info) #REQUIRED
+                              from CDATA #REQUIRED
+                              to CDATA #REQUIRED>
+
+
diff --git a/lib/data/PEAR/template.spec b/lib/data/PEAR/template.spec
new file mode 100644
index 00000000..37b477f8
--- /dev/null
+++ b/lib/data/PEAR/template.spec
@@ -0,0 +1,72 @@
+Summary: PEAR: @summary@
+Name: @rpm_package@
+Version: @version@
+Release: 1
+License: @release_license@
+Group: Development/Libraries
+Source: http://@master_server@/get/@package@-%{version}.tgz
+BuildRoot: %{_tmppath}/%{name}-root
+URL: http://@master_server@/package/@package@
+Prefix: %{_prefix}
+BuildArchitectures: @arch@
+@extra_headers@
+
+%description
+@description@
+
+%prep
+rm -rf %{buildroot}/*
+%setup -c -T
+# XXX Source files location is missing here in pear cmd
+pear -v -c %{buildroot}/pearrc \
+        -d php_dir=%{_libdir}/php/pear \
+        -d doc_dir=/docs \
+        -d bin_dir=%{_bindir} \
+        -d data_dir=%{_libdir}/php/pear/data \
+        -d test_dir=%{_libdir}/php/pear/tests \
+        -d ext_dir=%{_libdir} \@extra_config@
+        -s
+
+%build
+echo BuildRoot=%{buildroot}
+
+%postun
+# if refcount = 0 then package has been removed (not upgraded)
+if [ "$1" -eq "0" ]; then
+    pear uninstall --nodeps -r @possible_channel@@package@
+    rm @rpm_xml_dir@/@package@.xml
+fi
+
+
+%post
+# if refcount = 2 then package has been upgraded
+if [ "$1" -ge "2" ]; then
+    pear upgrade --nodeps -r @rpm_xml_dir@/@package@.xml
+else
+    pear install --nodeps -r @rpm_xml_dir@/@package@.xml
+fi
+
+%install
+pear -c %{buildroot}/pearrc install --nodeps -R %{buildroot} \
+        $RPM_SOURCE_DIR/@package@-%{version}.tgz
+rm %{buildroot}/pearrc
+rm %{buildroot}/%{_libdir}/php/pear/.filemap
+rm %{buildroot}/%{_libdir}/php/pear/.lock
+rm -rf %{buildroot}/%{_libdir}/php/pear/.registry
+if [ "@doc_files@" != "" ]; then
+     mv %{buildroot}/docs/@package@/* .
+     rm -rf %{buildroot}/docs
+fi
+mkdir -p %{buildroot}@rpm_xml_dir@
+tar -xzf $RPM_SOURCE_DIR/@package@-%{version}.tgz package@package2xml@.xml
+cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml
+
+#rm -rf %{buildroot}/*
+#pear -q install -R %{buildroot} -n package@package2xml@.xml
+#mkdir -p %{buildroot}@rpm_xml_dir@
+#cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml
+
+%files
+    %defattr(-,root,root)
+    %doc @doc_files@
+    /
diff --git a/lib/data/Structures_Graph/LICENSE b/lib/data/Structures_Graph/LICENSE
new file mode 100644
index 00000000..b1e3f5a2
--- /dev/null
+++ b/lib/data/Structures_Graph/LICENSE
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/lib/data/Structures_Graph/genpackage.xml.pl b/lib/data/Structures_Graph/genpackage.xml.pl
new file mode 100644
index 00000000..3b54fe7e
--- /dev/null
+++ b/lib/data/Structures_Graph/genpackage.xml.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+while (<>) {
+    if (!/FILESGOHERE/) {
+        print $_;
+    } else {
+        open FILELIST,'find Structures -type f | grep -v .arch-ids |';
+        while (<FILELIST>) {
+	    $md5sum = `md5sum $_`;
+	    chomp($md5sum);
+	    $md5sum = substr $md5sum, 0, 32;
+#    $_ =~ s/\//\\\//g;
+            chomp($_);
+            print "    <file role=\"php\" md5sum=\"$md5sum\" name=\"$_\" />\n";
+        }
+    }
+}
diff --git a/lib/data/Structures_Graph/package.sh b/lib/data/Structures_Graph/package.sh
new file mode 100644
index 00000000..11c36c2d
--- /dev/null
+++ b/lib/data/Structures_Graph/package.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+VERSION=`tla tree-version 2>&1 | sed "s/^.*\([0-9][0-9]*\.[0-9][0-9]*\)$/\1/g"`
+TARGET_DIR=BUILD/
+TARGET_DIRS=`find Structures -type d | grep -v .arch-ids`
+mkdir -p $TARGET_DIR
+./genpackage.xml.pl > BUILD/package.xml << EOF
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<package version="1.0">
+ <name>Structures_Graph</name>
+ <summary>Graph datastructure manipulation library</summary>
+ <license>LGPL</license>
+ <description>
+ Structures_Graph is a package for creating and manipulating graph datastructures. It allows building of directed
+ and undirected graphs, with data and metadata stored in nodes. The library provides functions for graph traversing
+ as well as for characteristic extraction from the graph topology.
+ </description>
+ <maintainers>
+  <maintainer>
+   <user>sergiosgc</user>
+   <name>S�rgio Carvalho</name>
+   <email>sergio.carvalho@portugalmail.com</email>
+   <role>lead</role>
+  </maintainer>
+ </maintainers>
+
+ <release>
+  <version>1.0.3</version>
+  <date>2007-01-30</date>
+  <state>stable</state>
+  <notes>
+  Version 1.0.3 is functionally equivalent to 1.0.2, but released with a v1.0 package.xml to deal with bug #9965:installation problem
+  </notes>
+  <filelist>
+FILESGOHERE
+  </filelist>
+ </release>
+ <deps>
+  <dep type="pkg" rel="ge" version="1.2">PEAR</dep>
+ </deps>
+</package>
+EOF
+for dir in $TARGET_DIRS
+do
+    mkdir -p $TARGET_DIR/$dir
+    cp `find $dir -maxdepth 1 -type f | grep -v .arch-ids` $TARGET_DIR/$dir
+done
+cp LICENSE BUILD
+(cd BUILD; pear package)
+rm -Rf BUILD/package.xml BUILD/LICENSE BUILD/Structures
+
+
diff --git a/lib/data/Structures_Graph/publish.sh b/lib/data/Structures_Graph/publish.sh
new file mode 100644
index 00000000..1632e233
--- /dev/null
+++ b/lib/data/Structures_Graph/publish.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+./package.sh
+scp BUILD/*.tgz root@sergiocarvalho.com:/home/httpd/vhosts/com/sergiocarvalho/pear-base/pear
+(cd docs; ./generate.sh)
+scp -r docs/html/* root@iluvatar.portugalmail.pt:/home/httpd/vhosts/com/sergiocarvalho/pear-base/pear/docs/Structures_Graph
diff --git a/lib/data/UNL_Peoplefinder/pear.unl.edu/hr_tree.xml b/lib/data/UNL_Peoplefinder/pear.unl.edu/hr_tree.xml
new file mode 100644
index 00000000..b5ca227e
--- /dev/null
+++ b/lib/data/UNL_Peoplefinder/pear.unl.edu/hr_tree.xml
@@ -0,0 +1,7951 @@
+<?xml version="1.0"?>
+<!DOCTYPE tree SYSTEM "treeml.dtd">
+<!-- Generated Tue Nov 17 14:04:19 2009 -->
+<tree>
+ <declarations>
+   <attributeDecl name="name"        type="String" />
+   <attributeDecl name="org_unit"    type="Integer"/>
+   <attributeDecl name="building"    type="String" />
+   <attributeDecl name="room"        type="String" />
+   <attributeDecl name="city"        type="String" />
+   <attributeDecl name="state"       type="String" />
+   <attributeDecl name="postal_code" type="String" />
+ </declarations>
+<branch>
+ <attribute name="name" value="University of Nebraska Board of Regents"/>
+ <attribute name="org_unit" value="50000000"/>
+ <branch>
+  <attribute name="name" value="Office of the President"/>
+  <attribute name="org_unit" value="50000001"/>
+  <attribute name="building" value="Varner Hall"/>
+  <attribute name="room" value="135"/>
+  <attribute name="city" value="Lincoln"/>
+  <attribute name="state" value="NE"/>
+  <attribute name="postal_code" value="68583-0745"/>
+  <branch>
+   <attribute name="name" value="University of Nebraska Central Admin"/>
+   <attribute name="org_unit" value="50000002"/>
+   <branch>
+    <attribute name="name" value="Office of the President"/>
+    <attribute name="org_unit" value="50000094"/>
+    <attribute name="building" value="Varner Hall"/>
+    <attribute name="room" value="135"/>
+    <attribute name="city" value="Lincoln"/>
+    <attribute name="state" value="NE"/>
+    <attribute name="postal_code" value="68583-0745"/>
+    <branch>
+     <attribute name="name" value="Executive VP and Provost"/>
+     <attribute name="org_unit" value="50000095"/>
+     <attribute name="building" value="Varner Hall"/>
+     <attribute name="room" value="106"/>
+     <attribute name="city" value="Lincoln"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68583-0743"/>
+     <branch>
+      <attribute name="name" value="Online Worldwide"/>
+      <attribute name="org_unit" value="50000329"/>
+      <attribute name="building" value="Varner Hall"/>
+      <attribute name="room" value="106"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0743"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="International Affairs"/>
+      <attribute name="org_unit" value="50006377"/>
+      <attribute name="building" value="Varner Hall"/>
+      <attribute name="room" value="145"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0743"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Peter Kiewit Institute"/>
+      <attribute name="org_unit" value="50006525"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="VP for Business and Finance"/>
+     <attribute name="org_unit" value="50000096"/>
+     <attribute name="building" value="Varner Hall"/>
+     <attribute name="room" value="207"/>
+     <attribute name="city" value="Lincoln"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68583-0742"/>
+     <branch>
+      <attribute name="name" value="Facilities Planning"/>
+      <attribute name="org_unit" value="50000326"/>
+      <attribute name="building" value="Varner Hall"/>
+      <attribute name="room" value="207"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0742"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Audit and Advisory Services"/>
+      <attribute name="org_unit" value="50000327"/>
+      <attribute name="building" value="Varner Hall"/>
+      <attribute name="room" value="207"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0742"/>
+      <branch>
+       <attribute name="name" value="Administrative Systems Group"/>
+       <attribute name="org_unit" value="50002325"/>
+      </branch>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="VP for University Affairs"/>
+     <attribute name="org_unit" value="50000097"/>
+     <attribute name="building" value="Varner Hall"/>
+     <attribute name="room" value="124"/>
+     <attribute name="city" value="Lincoln"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68583-0745"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="VP and General Counsel"/>
+     <attribute name="org_unit" value="50000098"/>
+     <attribute name="building" value="Varner Hall"/>
+     <attribute name="room" value="227"/>
+     <attribute name="city" value="Lincoln"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68583-0745"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="CIO &amp; UN Computing Serv Network"/>
+     <attribute name="org_unit" value="50000324"/>
+     <attribute name="building" value="Nebraska Hall"/>
+     <attribute name="room" value="235"/>
+     <attribute name="city" value="Lincoln"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0521"/>
+     <branch>
+      <attribute name="name" value="SAP Technical Support Team"/>
+      <attribute name="org_unit" value="50000332"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Applications Team"/>
+      <attribute name="org_unit" value="50000333"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Infrastructure Team"/>
+      <attribute name="org_unit" value="50000334"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Information Access Team"/>
+      <attribute name="org_unit" value="50000350"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="SIS Technical Support Team"/>
+      <attribute name="org_unit" value="50000351"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Identity Management Team"/>
+      <attribute name="org_unit" value="50000354"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Directorate Team"/>
+      <attribute name="org_unit" value="50000756"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Applications Team (UNL)"/>
+      <attribute name="org_unit" value="50001072"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Customer Support Team"/>
+      <attribute name="org_unit" value="50001073"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Porfolio Management Office"/>
+      <attribute name="org_unit" value="50001375"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="235"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Customer Administration Team"/>
+      <attribute name="org_unit" value="50003675"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="327"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0521"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Financial Management"/>
+      <attribute name="org_unit" value="50004376"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Information Security Team"/>
+      <attribute name="org_unit" value="50004475"/>
+     </branch>
+    </branch>
+   </branch>
+  </branch>
+  <branch>
+   <attribute name="name" value="University of Nebraska - Lincoln"/>
+   <attribute name="org_unit" value="50000003"/>
+   <branch>
+    <attribute name="name" value="Office of the Chancellor"/>
+    <attribute name="org_unit" value="50000081"/>
+    <attribute name="building" value="ADM"/>
+    <attribute name="room" value="201"/>
+    <attribute name="city" value="UNL"/>
+    <attribute name="state" value="NE"/>
+    <attribute name="postal_code" value="68588-0419"/>
+    <branch>
+     <attribute name="name" value="Business and Finance"/>
+     <attribute name="org_unit" value="50000084"/>
+     <attribute name="building" value="ADM"/>
+     <attribute name="room" value="210"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0425"/>
+     <branch>
+      <attribute name="name" value="Financial Services"/>
+      <attribute name="org_unit" value="50000819"/>
+      <attribute name="building" value="ADM"/>
+      <attribute name="room" value="313"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0429"/>
+      <branch>
+       <attribute name="name" value="Accounting"/>
+       <attribute name="org_unit" value="50000977"/>
+       <attribute name="building" value="ADM"/>
+       <attribute name="room" value="401"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0439"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Budget"/>
+       <attribute name="org_unit" value="50000978"/>
+       <attribute name="building" value="ADM"/>
+       <attribute name="room" value="309"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0427"/>
+       <branch>
+        <attribute name="name" value="Available Positions"/>
+        <attribute name="org_unit" value="50005775"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Bursar"/>
+       <attribute name="org_unit" value="50000979"/>
+       <attribute name="building" value="ADM"/>
+       <attribute name="room" value="121"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0412"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Payroll Services"/>
+       <attribute name="org_unit" value="50000980"/>
+       <attribute name="building" value="ADM"/>
+       <attribute name="room" value="403"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0436"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Student Accounts"/>
+       <attribute name="org_unit" value="50000983"/>
+       <attribute name="building" value="ADM"/>
+       <attribute name="room" value="124"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0413"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Academic Conferences"/>
+       <attribute name="org_unit" value="50001053"/>
+       <attribute name="building" value="NCCE"/>
+       <attribute name="room" value="271"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-9100"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Financial Systems"/>
+       <attribute name="org_unit" value="50006425"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="FM&amp;P Administration"/>
+      <attribute name="org_unit" value="50000820"/>
+      <attribute name="building" value="FMC"/>
+      <attribute name="room" value="1901 Y St/Admin"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0605"/>
+      <branch>
+       <attribute name="name" value="FM&amp;P Facilities Plan &amp; Construction"/>
+       <attribute name="org_unit" value="50001002"/>
+       <attribute name="building" value="FMC"/>
+       <attribute name="room" value="1901 Y St/FPC"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0605"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="FM&amp;P Building Systems Maintenance"/>
+       <attribute name="org_unit" value="50001004"/>
+       <attribute name="building" value="FMC"/>
+       <attribute name="room" value="1901 Y St/BSM"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0605"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="FM&amp;P Custodial Services"/>
+       <attribute name="org_unit" value="50001005"/>
+       <attribute name="building" value="FMC"/>
+       <attribute name="room" value="1901 Y St/Cust"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0605"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="FM&amp;P Utility Services"/>
+       <attribute name="org_unit" value="50001009"/>
+       <attribute name="building" value="FMC"/>
+       <attribute name="room" value="1901 Y St/Utility Svc"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0605"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="FM&amp;P Landscape Services"/>
+       <attribute name="org_unit" value="50001012"/>
+       <attribute name="building" value="LAND"/>
+       <attribute name="room" value="1340 N 17th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0609"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="FM&amp;P Business Operations"/>
+       <attribute name="org_unit" value="50006426"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Human Resources"/>
+      <attribute name="org_unit" value="50000821"/>
+      <attribute name="building" value="ADM"/>
+      <attribute name="room" value="407"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0438"/>
+      <branch>
+       <attribute name="name" value="Retirees"/>
+       <attribute name="org_unit" value="50001351"/>
+       <attribute name="building" value="501"/>
+       <attribute name="room" value="128"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0244"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Ancillary Units"/>
+       <attribute name="org_unit" value="50001407"/>
+       <attribute name="building" value="501"/>
+       <attribute name="room" value="128"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0244"/>
+       <branch>
+        <attribute name="name" value="NE Alumni Assn"/>
+        <attribute name="org_unit" value="50001400"/>
+        <attribute name="building" value="WICK"/>
+        <attribute name="room" value="1520 R St"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0216"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="UN Foundation"/>
+        <attribute name="org_unit" value="50001401"/>
+        <attribute name="building" value="1111"/>
+        <attribute name="room" value="1111 Lincoln Mall"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0650"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="SPF Swine Accrediting Agency"/>
+        <attribute name="org_unit" value="50001402"/>
+        <attribute name="building" value="1840 N 48th St"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68504-1997"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="NE Crop Improvement Assn"/>
+        <attribute name="org_unit" value="50001403"/>
+        <attribute name="building" value="PS"/>
+        <attribute name="room" value="266"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0911"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="NE Pork Producers"/>
+        <attribute name="org_unit" value="50001404"/>
+        <attribute name="building" value="ANS"/>
+        <attribute name="room" value="103"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0909"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="UN Board of Regents"/>
+        <attribute name="org_unit" value="50001405"/>
+        <attribute name="building" value="VARH"/>
+        <attribute name="room" value="3835 Holdrege St"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0745"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="UN Federal Credit Union"/>
+        <attribute name="org_unit" value="50001406"/>
+        <attribute name="building" value="UNFCU"/>
+        <attribute name="room" value="1630 Q St"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0209"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="NE 4-H Foundation"/>
+        <attribute name="org_unit" value="50001725"/>
+        <attribute name="building" value="AGH"/>
+        <attribute name="room" value="114"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0700"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Volunteers"/>
+       <attribute name="org_unit" value="50001509"/>
+       <attribute name="building" value="ADM"/>
+       <attribute name="room" value="407"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0438"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Operations Analysis"/>
+      <attribute name="org_unit" value="50000822"/>
+      <attribute name="building" value="ADM"/>
+      <attribute name="room" value="314"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0428"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="University Police"/>
+      <attribute name="org_unit" value="50000823"/>
+      <attribute name="building" value="UPOL"/>
+      <attribute name="room" value="1335 N 17th St"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0634"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="University Services"/>
+      <attribute name="org_unit" value="50000824"/>
+      <attribute name="building" value="BSC"/>
+      <attribute name="room" value="1700 Y St"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0646"/>
+      <branch>
+       <attribute name="name" value="Environmental Health &amp; Safety"/>
+       <attribute name="org_unit" value="50001010"/>
+       <attribute name="building" value="AGW1"/>
+       <attribute name="room" value="3630 E Campus Loop"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0824"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Inventory Control"/>
+       <attribute name="org_unit" value="50001011"/>
+       <attribute name="building" value="BSC"/>
+       <attribute name="room" value="1700 Y St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0606"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Mail Services"/>
+       <attribute name="org_unit" value="50001013"/>
+       <attribute name="building" value="MAIL"/>
+       <attribute name="room" value="1100 N 17th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0699"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Printing Services"/>
+       <attribute name="org_unit" value="50001014"/>
+       <attribute name="building" value="NH"/>
+       <attribute name="room" value="28"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0513"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Purchasing"/>
+       <attribute name="org_unit" value="50001016"/>
+       <attribute name="building" value="BSC"/>
+       <attribute name="room" value="1700 Y St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0645"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Transportation Services"/>
+       <attribute name="org_unit" value="50001017"/>
+       <attribute name="building" value="TRAN"/>
+       <attribute name="room" value="1931 N 14th St"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0603"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Parking and Transit Services"/>
+       <attribute name="org_unit" value="50001018"/>
+       <attribute name="building" value="SDPG"/>
+       <attribute name="room" value="Ste A"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0161"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="University Stores"/>
+       <attribute name="org_unit" value="50001019"/>
+       <attribute name="building" value="STOR"/>
+       <attribute name="room" value="1100 N 17th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0644"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Shared Services"/>
+       <attribute name="org_unit" value="50001309"/>
+       <attribute name="building" value="BSC"/>
+       <attribute name="room" value="1700 Y St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0647"/>
+       <branch>
+        <attribute name="name" value="NCard Office"/>
+        <attribute name="org_unit" value="50001475"/>
+        <attribute name="building" value="BSC"/>
+        <attribute name="room" value="1700 Y St"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0647"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="University Services Business Center"/>
+       <attribute name="org_unit" value="50003775"/>
+       <attribute name="building" value="Y St"/>
+       <attribute name="room" value="1700"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0694"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Department of E-Commerce"/>
+       <attribute name="org_unit" value="50004175"/>
+      </branch>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Academic Affairs"/>
+     <attribute name="org_unit" value="50000085"/>
+     <attribute name="building" value="Administration"/>
+     <attribute name="room" value="208"/>
+     <attribute name="city" value="Lincoln"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0420"/>
+     <branch>
+      <attribute name="name" value="Extended Education &amp; Outreach"/>
+      <attribute name="org_unit" value="50000791"/>
+      <attribute name="building" value="Hardin Center"/>
+      <attribute name="room" value="340"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0499"/>
+      <branch>
+       <attribute name="name" value="EE&amp;O Business Operations"/>
+       <attribute name="org_unit" value="50000911"/>
+       <attribute name="building" value="NCCE"/>
+       <attribute name="room" value="271"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-9100"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="EE&amp;O Independent Study HS"/>
+       <attribute name="org_unit" value="50001052"/>
+       <attribute name="building" value="NCCE"/>
+       <attribute name="room" value="271"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-9100"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="EE&amp;O Distance Education Srvcs"/>
+       <attribute name="org_unit" value="50003002"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="EE&amp;O Distance Education Pgms"/>
+       <attribute name="org_unit" value="50003003"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="EE&amp;O Instructional Design &amp; Dev"/>
+       <attribute name="org_unit" value="50003004"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="EE&amp;O Information Services"/>
+       <attribute name="org_unit" value="50005300"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Architecture"/>
+      <attribute name="org_unit" value="50000896"/>
+      <attribute name="building" value="Architecture Hall"/>
+      <attribute name="room" value="210"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0106"/>
+      <branch>
+       <attribute name="name" value="Architecture"/>
+       <attribute name="org_unit" value="50001020"/>
+       <attribute name="building" value="Architecture Hall"/>
+       <attribute name="room" value="232"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0107"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Community &amp; Regional Planning"/>
+       <attribute name="org_unit" value="50001021"/>
+       <attribute name="building" value="Architecture Hall"/>
+       <attribute name="room" value="302"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0105"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Interior Design"/>
+       <attribute name="org_unit" value="50005025"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Landscape Architecture Program"/>
+       <attribute name="org_unit" value="50005026"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Business Administration"/>
+      <attribute name="org_unit" value="50000897"/>
+      <attribute name="building" value="CBA"/>
+      <attribute name="room" value="215"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0405"/>
+      <branch>
+       <attribute name="name" value="Bureau Business Research"/>
+       <attribute name="org_unit" value="50001023"/>
+       <attribute name="building" value="CBA"/>
+       <attribute name="room" value="114"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0406"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Economics"/>
+       <attribute name="org_unit" value="50001024"/>
+       <attribute name="building" value="CBA"/>
+       <attribute name="room" value="340"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0489"/>
+       <branch>
+        <attribute name="name" value="Economic Education"/>
+        <attribute name="org_unit" value="50001025"/>
+        <attribute name="building" value="CBA"/>
+        <attribute name="room" value="339"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0402"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Finance"/>
+       <attribute name="org_unit" value="50001026"/>
+       <attribute name="building" value="CBA"/>
+       <attribute name="room" value="210"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0490"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Management"/>
+       <attribute name="org_unit" value="50001027"/>
+       <attribute name="building" value="CBA"/>
+       <attribute name="room" value="209"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0491"/>
+       <branch>
+        <attribute name="name" value="Ctr for Entrepreneurship"/>
+        <attribute name="org_unit" value="50001302"/>
+        <attribute name="building" value="CBA"/>
+        <attribute name="room" value="209"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0487"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Marketing"/>
+       <attribute name="org_unit" value="50001028"/>
+       <attribute name="building" value="CBA"/>
+       <attribute name="room" value="310"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0492"/>
+       <branch>
+        <attribute name="name" value="Agribusiness"/>
+        <attribute name="org_unit" value="50001303"/>
+        <attribute name="building" value="CBA"/>
+        <attribute name="room" value="310"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0492"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="School of Accountancy"/>
+       <attribute name="org_unit" value="50001029"/>
+       <attribute name="building" value="CBA"/>
+       <attribute name="room" value="307"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0488"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Hixson-Lied Fine &amp; Performing Arts"/>
+      <attribute name="org_unit" value="50000898"/>
+      <attribute name="building" value="Woods Hall"/>
+      <attribute name="room" value="102"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0144"/>
+      <branch>
+       <attribute name="name" value="Art &amp; Art History"/>
+       <attribute name="org_unit" value="50001030"/>
+       <attribute name="building" value="120 Richards Hall"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0114"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Mary Riepma Ross Media Arts Center"/>
+       <attribute name="org_unit" value="50001031"/>
+       <attribute name="building" value="Architecture Hall"/>
+       <attribute name="room" value="116"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0144"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="School of Music"/>
+       <attribute name="org_unit" value="50001032"/>
+       <attribute name="building" value="Westbrook"/>
+       <attribute name="room" value="120"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0100"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Johnny Carson School-Theatre &amp; Film"/>
+       <attribute name="org_unit" value="50001033"/>
+       <attribute name="building" value="Temple"/>
+       <attribute name="room" value="215"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0201"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Law"/>
+      <attribute name="org_unit" value="50000899"/>
+      <attribute name="building" value="Law College"/>
+      <attribute name="room" value="103"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0902"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="International Affairs"/>
+      <attribute name="org_unit" value="50000901"/>
+      <attribute name="building" value="420 University Terrace"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0682"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Ofc of Dean - Undergraduate Studies"/>
+      <attribute name="org_unit" value="50002975"/>
+      <attribute name="building" value="ADM"/>
+      <attribute name="room" value="210"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588 0434"/>
+      <branch>
+       <attribute name="name" value="Division of General Studies"/>
+       <attribute name="org_unit" value="50000902"/>
+       <attribute name="building" value="Administration"/>
+       <attribute name="room" value="33"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0471"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="University Honors Program"/>
+       <attribute name="org_unit" value="50001109"/>
+       <attribute name="building" value="Neihardt Hall"/>
+       <attribute name="room" value="118"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0659"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="University Foundations Program"/>
+       <attribute name="org_unit" value="50001111"/>
+       <attribute name="building" value="Andrews Hall"/>
+       <attribute name="room" value="338"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0370"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Information Services"/>
+      <attribute name="org_unit" value="50000904"/>
+      <attribute name="building" value="Love Library"/>
+      <attribute name="room" value="450"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0496"/>
+      <branch>
+       <attribute name="name" value="Telecommunications Center"/>
+       <attribute name="org_unit" value="50001034"/>
+       <attribute name="building" value="Nebraska Hall"/>
+       <attribute name="room" value="211"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0522"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="University Libraries"/>
+      <attribute name="org_unit" value="50000905"/>
+      <attribute name="building" value="Love Library"/>
+      <attribute name="room" value="141"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0410"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Arts &amp; Sciences"/>
+      <attribute name="org_unit" value="50000906"/>
+      <attribute name="building" value="Oldfather Hall"/>
+      <attribute name="room" value="1223"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0312"/>
+      <branch>
+       <attribute name="name" value="Anthropology"/>
+       <attribute name="org_unit" value="50001075"/>
+       <attribute name="building" value="Bessey Hall"/>
+       <attribute name="room" value="126"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0368"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="School of Biological Sciences"/>
+       <attribute name="org_unit" value="50001076"/>
+       <attribute name="building" value="Manter Hall"/>
+       <attribute name="room" value="348"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0118"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Center of Great Plains Studies"/>
+       <attribute name="org_unit" value="50001077"/>
+       <attribute name="building" value="1155 Q Street"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0214"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Chemistry"/>
+       <attribute name="org_unit" value="50001078"/>
+       <attribute name="building" value="Hamilton Hall"/>
+       <attribute name="room" value="545"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0304"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Classics &amp; Religious Studies"/>
+       <attribute name="org_unit" value="50001079"/>
+       <attribute name="building" value="Andrews Hall"/>
+       <attribute name="room" value="237"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0337"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Communication Studies"/>
+       <attribute name="org_unit" value="50001080"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="432"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0329"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Computer Science &amp; Engineering"/>
+       <attribute name="org_unit" value="50001081"/>
+       <attribute name="building" value="Ferguson Hall"/>
+       <attribute name="room" value="115"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0115"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Ctr Children Family &amp; the Law"/>
+       <attribute name="org_unit" value="50001082"/>
+       <attribute name="building" value="121 South 13th Street"/>
+       <attribute name="room" value="Suite 302"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0227"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="English"/>
+       <attribute name="org_unit" value="50001083"/>
+       <attribute name="building" value="Andrews Hall"/>
+       <attribute name="room" value="202"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0333"/>
+       <branch>
+        <attribute name="name" value="Program of English as 2nd Language"/>
+        <attribute name="org_unit" value="50001101"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Ethnic Studies"/>
+       <attribute name="org_unit" value="50001084"/>
+       <attribute name="building" value="Lyman Hall"/>
+       <attribute name="room" value="124"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0335"/>
+       <branch>
+        <attribute name="name" value="African American &amp; African Studies"/>
+        <attribute name="org_unit" value="50001096"/>
+        <attribute name="building" value="Oldfather Hall"/>
+        <attribute name="room" value="730"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0320"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Latin American &amp; Latino Studies"/>
+        <attribute name="org_unit" value="50001097"/>
+        <attribute name="building" value="Lyman Hall"/>
+        <attribute name="room" value="124"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0335"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Native American Studies"/>
+        <attribute name="org_unit" value="50001098"/>
+        <attribute name="building" value="Lyman Hall"/>
+        <attribute name="room" value="124"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0335"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Geosciences"/>
+       <attribute name="org_unit" value="50001086"/>
+       <attribute name="building" value="Bessey Hall"/>
+       <attribute name="room" value="214"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0340"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="History"/>
+       <attribute name="org_unit" value="50001087"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="610"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0327"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Mathematics"/>
+       <attribute name="org_unit" value="50001088"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="810"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0323"/>
+       <branch>
+        <attribute name="name" value="Mathematics Association of America"/>
+        <attribute name="org_unit" value="50001089"/>
+        <attribute name="building" value="1740 Vine Street"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0658"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Ctr for Science Math &amp; Computer Ed"/>
+        <attribute name="org_unit" value="50003076"/>
+        <attribute name="building" value="Morrill hall"/>
+        <attribute name="room" value="126"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0350"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Modern Language &amp; Literature"/>
+       <attribute name="org_unit" value="50001090"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="1111"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0315"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Philosophy"/>
+       <attribute name="org_unit" value="50001091"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="1010"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0321"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Physics &amp; Astronomy"/>
+       <attribute name="org_unit" value="50001092"/>
+       <attribute name="building" value="Brace Lab"/>
+       <attribute name="room" value="116"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0111"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Political Science"/>
+       <attribute name="org_unit" value="50001093"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="511"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0328"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Psychology"/>
+       <attribute name="org_unit" value="50001094"/>
+       <attribute name="building" value="Burnett Hall"/>
+       <attribute name="room" value="238"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0308"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Sociology"/>
+       <attribute name="org_unit" value="50001095"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="711"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0324"/>
+       <branch>
+        <attribute name="name" value="Bureau of Sociological Research"/>
+        <attribute name="org_unit" value="50001100"/>
+        <attribute name="building" value="Oldfather Hall"/>
+        <attribute name="room" value="731"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0325"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="A&amp;S General"/>
+       <attribute name="org_unit" value="50001103"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="1223"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0312"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Environmental Studies"/>
+       <attribute name="org_unit" value="50001104"/>
+       <attribute name="building" value="BcH"/>
+       <attribute name="room" value="304"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0746"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Judaic Studies"/>
+       <attribute name="org_unit" value="50001106"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="1213"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68508-0346"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Women&#39;s &amp; Gender Studies"/>
+       <attribute name="org_unit" value="50001107"/>
+       <attribute name="building" value="Oldfather Hall"/>
+       <attribute name="room" value="1209"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68508-0341"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="International Studies"/>
+       <attribute name="org_unit" value="50002150"/>
+       <attribute name="building" value="420"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0689"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Statistics"/>
+       <attribute name="org_unit" value="50003050"/>
+       <attribute name="building" value="103 MILH"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0712"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Antarctic Drilling Program"/>
+       <attribute name="org_unit" value="50004825"/>
+       <attribute name="building" value="Bessey Hall"/>
+       <attribute name="room" value="126"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0341"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Survey Research &amp; Methodology/Gallup"/>
+       <attribute name="org_unit" value="50005076"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Geography-SNR"/>
+       <attribute name="org_unit" value="50006276"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Engineering"/>
+      <attribute name="org_unit" value="50000907"/>
+      <attribute name="building" value="Nebraska Hall"/>
+      <attribute name="room" value="W181"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0501"/>
+      <branch>
+       <attribute name="name" value="Eng Dean&#39;s Office-Omaha"/>
+       <attribute name="org_unit" value="50001057"/>
+       <attribute name="building" value="Engineering"/>
+       <attribute name="room" value="116"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Chemical &amp; Biomolecular Engineering"/>
+       <attribute name="org_unit" value="50001058"/>
+       <attribute name="building" value="Avery Hall"/>
+       <attribute name="room" value="236"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0126"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Civil Engineering-Lincoln"/>
+       <attribute name="org_unit" value="50001059"/>
+       <attribute name="building" value="Nebraska Hall"/>
+       <attribute name="room" value="W348"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0531"/>
+       <branch>
+        <attribute name="name" value="Civil Engineering-Omaha"/>
+        <attribute name="org_unit" value="50001310"/>
+        <attribute name="building" value="Engineering Bldg"/>
+        <attribute name="room" value="129"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182-0178"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Computer &amp; Electronics Engineering"/>
+       <attribute name="org_unit" value="50001060"/>
+       <attribute name="building" value="Peter Kiewit Institute"/>
+       <attribute name="room" value="200"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182-0181"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="School of Architecture &amp; ConstructionUNL"/>
+       <attribute name="org_unit" value="50004975"/>
+       <branch>
+        <attribute name="name" value="Construction Management"/>
+        <attribute name="org_unit" value="50001061"/>
+        <attribute name="building" value="Nebraska Hall"/>
+        <attribute name="room" value="W145"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0500"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Construction Systems"/>
+        <attribute name="org_unit" value="50001062"/>
+        <attribute name="building" value="Peter Kiewit Institute"/>
+        <attribute name="room" value="107C"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182-0181"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Architectural Engineering"/>
+        <attribute name="org_unit" value="50001408"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Electrical Engineering"/>
+       <attribute name="org_unit" value="50001063"/>
+       <attribute name="building" value="Walter Scott Engr"/>
+       <attribute name="room" value="209N"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0511"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Engineering Mechanics"/>
+       <attribute name="org_unit" value="50001064"/>
+       <attribute name="building" value="Nebraska Hall"/>
+       <attribute name="room" value="W317.4"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0526"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Industrial &amp; Mgmt Syst Engineering"/>
+       <attribute name="org_unit" value="50001065"/>
+       <attribute name="building" value="Nebraska Hall"/>
+       <attribute name="room" value="175"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0518"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Mechanical Engineering"/>
+       <attribute name="org_unit" value="50001067"/>
+       <attribute name="building" value="Walter Scott Engr"/>
+       <attribute name="room" value="104N"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0656"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Engineering Research Center"/>
+       <attribute name="org_unit" value="50001068"/>
+       <attribute name="building" value="Nebraska Hall"/>
+       <attribute name="room" value="W150"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0502"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nebraska Transportation Center"/>
+       <attribute name="org_unit" value="50005500"/>
+       <branch>
+        <attribute name="name" value="Mid-America Transportation Center"/>
+        <attribute name="org_unit" value="50001069"/>
+        <attribute name="building" value="Nebraska Hall"/>
+        <attribute name="room" value="113"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0530"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Midwest Roadside Safety Facility"/>
+        <attribute name="org_unit" value="50001070"/>
+        <attribute name="building" value="Nebraska Hall"/>
+        <attribute name="room" value="W328.1"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0529"/>
+       </branch>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Journalism &amp; Mass Comm"/>
+      <attribute name="org_unit" value="50000908"/>
+      <attribute name="building" value="Avery Hall"/>
+      <attribute name="room" value="206"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0127"/>
+      <branch>
+       <attribute name="name" value="Advertising"/>
+       <attribute name="org_unit" value="50001035"/>
+       <attribute name="building" value="Avery Hall"/>
+       <attribute name="room" value="206"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0127"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Broadcasting"/>
+       <attribute name="org_unit" value="50001036"/>
+       <attribute name="building" value="Avery Hall"/>
+       <attribute name="room" value="206"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0127"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="News - Editorial"/>
+       <attribute name="org_unit" value="50001037"/>
+       <attribute name="building" value="Avery Hall"/>
+       <attribute name="room" value="206"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0127"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College Human Res &amp; Family Sciences"/>
+      <attribute name="org_unit" value="50000909"/>
+      <attribute name="building" value="Home Economics"/>
+      <attribute name="room" value="105"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0800"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Education &amp; Human Sci"/>
+      <attribute name="org_unit" value="50000910"/>
+      <attribute name="building" value="Mable Lee Hall"/>
+      <attribute name="room" value="233"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0234"/>
+      <branch>
+       <attribute name="name" value="Child, Youth &amp; Family Studies"/>
+       <attribute name="org_unit" value="50001040"/>
+       <attribute name="building" value="Home Economics"/>
+       <attribute name="room" value="123"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0801"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nutrition &amp; Health Sciences"/>
+       <attribute name="org_unit" value="50001041"/>
+       <attribute name="building" value="Ruth Leverton Hall"/>
+       <attribute name="room" value="316A"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0806"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Textiles Clothing &amp; Design"/>
+       <attribute name="org_unit" value="50001042"/>
+       <attribute name="building" value="Home Economics"/>
+       <attribute name="room" value="234D"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0802"/>
+       <branch>
+        <attribute name="name" value="Intl Quilt Study Center &amp; Museum"/>
+        <attribute name="org_unit" value="50005976"/>
+        <attribute name="building" value="HECO"/>
+        <attribute name="room" value="234"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0802"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Education &amp; Human Sciences @ Omaha"/>
+       <attribute name="org_unit" value="50001043"/>
+       <attribute name="building" value="Arts &amp; Sciences Hall"/>
+       <attribute name="room" value="108"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182-0214"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Educational Psychology"/>
+       <attribute name="org_unit" value="50001047"/>
+       <attribute name="building" value="Educational Psychology"/>
+       <attribute name="room" value="114"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0345"/>
+       <branch>
+        <attribute name="name" value="Buros Center for Testing"/>
+        <attribute name="org_unit" value="50001044"/>
+        <attribute name="building" value="Buros Institute"/>
+        <attribute name="room" value="21"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0348"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Center for Instructional Innovation"/>
+        <attribute name="org_unit" value="50001312"/>
+        <attribute name="building" value="Ctr for Instructional Innovati"/>
+        <attribute name="room" value="209"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0384"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Teaching, Learning &amp; Teacher Ed"/>
+       <attribute name="org_unit" value="50001045"/>
+       <attribute name="building" value="Mabel Lee Hall"/>
+       <attribute name="room" value="231"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0234"/>
+       <branch>
+        <attribute name="name" value="Instructional Design Center"/>
+        <attribute name="org_unit" value="50001051"/>
+        <attribute name="building" value="Henzlik Hall"/>
+        <attribute name="room" value="122"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0351"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Educational Administration"/>
+       <attribute name="org_unit" value="50001046"/>
+       <attribute name="building" value="Dept of Educational Administr"/>
+       <attribute name="room" value="141"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="06588-0360"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Health &amp; Human Performance"/>
+       <attribute name="org_unit" value="50001048"/>
+       <attribute name="building" value="Mabel Lee Hall"/>
+       <attribute name="room" value="232"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0229"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Special Ed &amp; Communic Disorders"/>
+       <attribute name="org_unit" value="50001049"/>
+       <attribute name="building" value="Barkley Center"/>
+       <attribute name="room" value="304"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0738"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Natl Ctr for Info Technology in Educ"/>
+       <attribute name="org_unit" value="50002525"/>
+       <attribute name="building" value="Mabel Lee Hall"/>
+       <attribute name="room" value="231"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0234"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="NE Ctr  Rsrch on Youth,Fam &amp; School"/>
+       <attribute name="org_unit" value="50004425"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="University Television"/>
+      <attribute name="org_unit" value="50000912"/>
+      <attribute name="building" value="Telecommunications"/>
+      <attribute name="room" value="403"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0747"/>
+      <branch>
+       <attribute name="name" value="Great Plains NITV Library"/>
+       <attribute name="org_unit" value="50001056"/>
+       <attribute name="building" value="Telecommunications"/>
+       <attribute name="room" value="403"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0747"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Academic Senate"/>
+      <attribute name="org_unit" value="50001108"/>
+      <attribute name="building" value="1227 R Street"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0210"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Summer Sessions"/>
+      <attribute name="org_unit" value="50001110"/>
+      <attribute name="building" value="ADM"/>
+      <attribute name="room" value="208"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0421"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="J S Raikes School of Comp Sci &amp; Mgmt"/>
+      <attribute name="org_unit" value="50001313"/>
+      <attribute name="building" value="630 North 14th Street"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0690"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Public Policy Center"/>
+      <attribute name="org_unit" value="50001525"/>
+      <attribute name="building" value="121 S. 13th Street"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0228"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Plains Humanities Alliance"/>
+      <attribute name="org_unit" value="50001676"/>
+      <attribute name="building" value="Andrews Hall"/>
+      <attribute name="room" value="334"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0392"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Research"/>
+     <attribute name="org_unit" value="50000086"/>
+     <attribute name="building" value="ADM"/>
+     <attribute name="room" value="302"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0433"/>
+     <branch>
+      <attribute name="name" value="Graduate Studies"/>
+      <attribute name="org_unit" value="50000900"/>
+      <attribute name="building" value="SHE"/>
+      <attribute name="room" value="1100"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0619"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Technology Development"/>
+      <attribute name="org_unit" value="50000931"/>
+      <attribute name="building" value="ALEX"/>
+      <attribute name="room" value="312 N 14th St"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0467"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="University Museum"/>
+      <attribute name="org_unit" value="50000932"/>
+      <attribute name="building" value="MORR"/>
+      <attribute name="room" value="307"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0338"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="University Press"/>
+      <attribute name="org_unit" value="50000933"/>
+      <attribute name="building" value="LAU"/>
+      <attribute name="room" value="233 N 8th St"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0255"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Nebraska Research Initiative"/>
+      <attribute name="org_unit" value="50000935"/>
+      <attribute name="building" value="ADM"/>
+      <attribute name="room" value="310"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0433"/>
+      <branch>
+       <attribute name="name" value="NRI Center of Biotechnology"/>
+       <attribute name="org_unit" value="50001318"/>
+       <attribute name="building" value="BEAD"/>
+       <attribute name="room" value="N300"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0665"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nebr Ctr for Materials &amp; Nanoscience"/>
+       <attribute name="org_unit" value="50001319"/>
+       <attribute name="building" value="BL"/>
+       <attribute name="room" value="111"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0113"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Sponsored Programs"/>
+      <attribute name="org_unit" value="50000982"/>
+      <attribute name="building" value="ALEX"/>
+      <attribute name="room" value="312 N 14th St"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0431"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Sponsored Pgm-Pre Award"/>
+      <attribute name="org_unit" value="50001314"/>
+      <attribute name="building" value="ALEX"/>
+      <attribute name="room" value="312 N 14th St"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0430"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Research Resp-Human Res Prot  Prog"/>
+      <attribute name="org_unit" value="50001315"/>
+      <attribute name="building" value="ALEX"/>
+      <attribute name="room" value="312 N 14th St"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0415"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="EPSCOR"/>
+      <attribute name="org_unit" value="50001323"/>
+      <attribute name="building" value="WHIT"/>
+      <attribute name="room" value="203"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Center for Plant Science Innovation"/>
+      <attribute name="org_unit" value="50002500"/>
+      <attribute name="building" value="BEAD"/>
+      <attribute name="room" value="N300"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0660"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Research Resp-Inst Animal Care  Prog"/>
+      <attribute name="org_unit" value="50004250"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Center for Energy Sciences Research"/>
+      <attribute name="org_unit" value="50005075"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Institute of Ag &amp; Natural Resources"/>
+     <attribute name="org_unit" value="50000087"/>
+     <attribute name="building" value="Agricultural Hall"/>
+     <attribute name="room" value="202"/>
+     <attribute name="city" value="Lincoln"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68583-0708"/>
+     <branch>
+      <attribute name="name" value="Office of Vice Pres/Vice Chancellor"/>
+      <attribute name="org_unit" value="50000775"/>
+      <attribute name="building" value="202 AGH"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0708"/>
+      <branch>
+       <attribute name="name" value="IANR Finance &amp; Personnel Office"/>
+       <attribute name="org_unit" value="50000785"/>
+       <attribute name="building" value="313 AGH"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0705"/>
+       <branch>
+        <attribute name="name" value="Filley Hall Business Center"/>
+        <attribute name="org_unit" value="50000913"/>
+        <attribute name="building" value="221 FYH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0756"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Natural Resources Business Center"/>
+        <attribute name="org_unit" value="50000914"/>
+        <attribute name="building" value="237 HARH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0972"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Beadle Business Center"/>
+        <attribute name="org_unit" value="50001188"/>
+        <attribute name="building" value="N300B BEAD"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0665"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="ASSIST Business Center"/>
+        <attribute name="org_unit" value="50003025"/>
+        <attribute name="building" value="1071 County Rd G"/>
+        <attribute name="city" value="Ithaca"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68033-2234"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="VBI Business Center"/>
+        <attribute name="org_unit" value="50003028"/>
+        <attribute name="building" value="120 VBS"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0905"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="IANR Vacant Positions"/>
+        <attribute name="org_unit" value="50003029"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Deans/Directors"/>
+       <attribute name="org_unit" value="50000790"/>
+       <attribute name="building" value="Agricultural Hall"/>
+       <attribute name="room" value="207"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0704"/>
+       <branch>
+        <attribute name="name" value="Agricultural Rsch Division"/>
+        <attribute name="org_unit" value="50000786"/>
+        <attribute name="building" value="207 AGH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0704"/>
+        <branch>
+         <attribute name="name" value="Sustain Ag Rsch &amp; Ed Program"/>
+         <attribute name="org_unit" value="50000886"/>
+         <attribute name="building" value="13A AB"/>
+         <attribute name="city" value="UNL"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0840"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Husker Genetics"/>
+         <attribute name="org_unit" value="50000915"/>
+         <attribute name="building" value="1071 County Rd G"/>
+         <attribute name="city" value="Ithaca"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68033-2234"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="USMARC"/>
+         <attribute name="org_unit" value="50000937"/>
+         <attribute name="building" value="PO Box 166"/>
+         <attribute name="city" value="Clay Center"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68933-0166"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="South Central Ag Rsch Lab"/>
+         <attribute name="org_unit" value="50000945"/>
+         <attribute name="building" value="PO Box 66"/>
+         <attribute name="city" value="Clay Center"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68933-0066"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Agricultural Rsch &amp; Dev Center"/>
+         <attribute name="org_unit" value="50001178"/>
+         <attribute name="building" value="1071 County Rd G"/>
+         <attribute name="city" value="Ithaca"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68033-2234"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="INTSORMIL - Sorghum/Millet CRSP"/>
+         <attribute name="org_unit" value="50001526"/>
+         <attribute name="building" value="113 BCH"/>
+         <attribute name="city" value="UNL"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0748"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="College of Ag Sci &amp; Nat Res"/>
+        <attribute name="org_unit" value="50000787"/>
+        <attribute name="building" value="107 AGH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0702"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Cooperative Ext Division"/>
+        <attribute name="org_unit" value="50000788"/>
+        <attribute name="building" value="211 AGH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0703"/>
+        <branch>
+         <attribute name="name" value="4-H Youth Development"/>
+         <attribute name="org_unit" value="50000940"/>
+         <attribute name="building" value="114 AGH"/>
+         <attribute name="city" value="UNL"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0700"/>
+         <branch>
+          <attribute name="name" value="4-H Youth Development Camps"/>
+          <attribute name="org_unit" value="50006400"/>
+          <attribute name="building" value="114 AGH"/>
+          <attribute name="city" value="UNL"/>
+          <attribute name="state" value="NE"/>
+          <attribute name="postal_code" value="68583-0700"/>
+         </branch>
+        </branch>
+        <branch>
+         <attribute name="name" value="e-Extension"/>
+         <attribute name="org_unit" value="50004077"/>
+         <attribute name="building" value="104 ACB"/>
+         <attribute name="city" value="UN-L"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0918"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Nebraska  LTAP"/>
+         <attribute name="org_unit" value="50004100"/>
+         <attribute name="building" value="3921 W Craw"/>
+         <attribute name="city" value="Lincoln"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68524"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="International Programs"/>
+        <attribute name="org_unit" value="50000789"/>
+        <attribute name="building" value="Agricultural Hall"/>
+        <attribute name="room" value="110"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0706"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="College of Education &amp; Human Sci"/>
+        <attribute name="org_unit" value="50000800"/>
+        <attribute name="building" value="105 HECO"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0800"/>
+        <branch>
+         <attribute name="name" value="Child, Youth &amp; Family Studies"/>
+         <attribute name="org_unit" value="50000846"/>
+         <attribute name="building" value="123 HECO"/>
+         <attribute name="city" value="UNL"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0801"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Nutrition &amp; Health Sciences"/>
+         <attribute name="org_unit" value="50000847"/>
+         <attribute name="building" value="316A LEV"/>
+         <attribute name="city" value="UNL"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0806"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Textile Clothing &amp; Design"/>
+         <attribute name="org_unit" value="50000848"/>
+         <attribute name="building" value="234D HECO"/>
+         <attribute name="city" value="UNL"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0802"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="Agronomy &amp; Horticulture"/>
+        <attribute name="org_unit" value="50000827"/>
+        <attribute name="building" value="279 PLSH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0915"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Agricultural Economics"/>
+        <attribute name="org_unit" value="50000828"/>
+        <attribute name="building" value="102 FYH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0922"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Ag Leadership Educ &amp; Comm"/>
+        <attribute name="org_unit" value="50000829"/>
+        <attribute name="building" value="300 AGH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0704"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Animal Science"/>
+        <attribute name="org_unit" value="50000830"/>
+        <attribute name="building" value="C203 ANSC"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0908"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Biochemistry"/>
+        <attribute name="org_unit" value="50000831"/>
+        <attribute name="building" value="N200 BEAD"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0664"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Statistics"/>
+        <attribute name="org_unit" value="50000832"/>
+        <attribute name="building" value="103 MILH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0712"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Biological Systems Engineering"/>
+        <attribute name="org_unit" value="50000833"/>
+        <attribute name="building" value="223 CHA"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0726"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Entomology"/>
+        <attribute name="org_unit" value="50000834"/>
+        <attribute name="building" value="202 ENTO"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0816"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Comm Information Technology"/>
+        <attribute name="org_unit" value="50000835"/>
+        <attribute name="building" value="104 ACB"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0918"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Food Science &amp; Technology"/>
+        <attribute name="org_unit" value="50000836"/>
+        <attribute name="building" value="143 FYH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0919"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Plant Pathology"/>
+        <attribute name="org_unit" value="50000843"/>
+        <attribute name="building" value="406 PLSH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0722"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="School of Natural Resources"/>
+        <attribute name="org_unit" value="50000844"/>
+        <attribute name="building" value="912 HARH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0989"/>
+        <branch>
+         <attribute name="name" value="Survey Division - School of Nat Res"/>
+         <attribute name="org_unit" value="50000887"/>
+         <attribute name="building" value="912 HARH"/>
+         <attribute name="city" value="UNL"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0989"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Nebraska Coop Fish &amp; Wildlife Rsch"/>
+         <attribute name="org_unit" value="50003954"/>
+         <attribute name="building" value="422 HARH"/>
+         <attribute name="city" value="UNL"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0984"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="Vet &amp; Biomedical Sciences"/>
+        <attribute name="org_unit" value="50000845"/>
+        <attribute name="building" value="120 VBS"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0905"/>
+        <branch>
+         <attribute name="name" value="Great Plains Vet Ed Center"/>
+         <attribute name="org_unit" value="50001179"/>
+         <attribute name="building" value="Box 187"/>
+         <attribute name="city" value="Clay Center"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68933"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="College Park/Grand Island"/>
+        <attribute name="org_unit" value="50000927"/>
+        <attribute name="building" value="3180 West Hwy 34"/>
+        <attribute name="city" value="Grand Island"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68801-7279"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Center for Applied Rural Innovation"/>
+        <attribute name="org_unit" value="50000939"/>
+        <attribute name="building" value="58 FYH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0947"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Southeast Rsch &amp; Ext Center"/>
+        <attribute name="org_unit" value="50000941"/>
+        <attribute name="building" value="211 MUSH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0714"/>
+        <branch>
+         <attribute name="name" value="Farm Business Association"/>
+         <attribute name="org_unit" value="50000947"/>
+         <attribute name="building" value="110 MUSH"/>
+         <attribute name="city" value="UNL"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68583-0719"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="Panhandle Rsch &amp; Ext Center"/>
+        <attribute name="org_unit" value="50000942"/>
+        <attribute name="building" value="4502 Ave I"/>
+        <attribute name="city" value="Scottsbluff"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="69361-4939"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Northeast Rsch &amp; Ext Center"/>
+        <attribute name="org_unit" value="50000943"/>
+        <attribute name="building" value="601 E Benjamin Ave Ste 104"/>
+        <attribute name="city" value="Norfolk"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68701-0812"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="West Central Rsch &amp; Ext Center"/>
+        <attribute name="org_unit" value="50000944"/>
+        <attribute name="building" value="461 W University Dr"/>
+        <attribute name="city" value="North Platte"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="69101-9495"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Nebraska LEAD Program"/>
+        <attribute name="org_unit" value="50000946"/>
+        <attribute name="building" value="318 BCH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0763"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Grassland Studies Center"/>
+        <attribute name="org_unit" value="50000954"/>
+        <attribute name="building" value="222 KEIM"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0953"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Food Processing Center"/>
+        <attribute name="org_unit" value="50001181"/>
+        <attribute name="building" value="143 FYH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0919"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Industrial Ag Products Center"/>
+        <attribute name="org_unit" value="50001182"/>
+        <attribute name="building" value="208 CHA"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0739"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Water Center"/>
+        <attribute name="org_unit" value="50002225"/>
+        <attribute name="building" value="103 FORS"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0844"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="ISU/UNL Coop Vet Med Education Prog"/>
+        <attribute name="org_unit" value="50005175"/>
+        <attribute name="building" value="120 VBS"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0905"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Plant Health"/>
+        <attribute name="org_unit" value="50006325"/>
+        <attribute name="building" value="271 PS"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0933"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nebraska Forest Service"/>
+       <attribute name="org_unit" value="50000889"/>
+       <attribute name="building" value="103 ENTO"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0815"/>
+       <branch>
+        <attribute name="name" value="Nebraska Statewide Arboretum - NFS"/>
+        <attribute name="org_unit" value="50001185"/>
+        <attribute name="building" value="206 BCH"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0715"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="NE College of Technical Agriculture"/>
+       <attribute name="org_unit" value="50000928"/>
+       <attribute name="building" value="RR 3 Box 23A"/>
+       <attribute name="city" value="Curtis"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="69025-9502"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Office Prof/Org Development"/>
+       <attribute name="org_unit" value="50001183"/>
+       <attribute name="building" value="Mussehl Hall"/>
+       <attribute name="room" value="102"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0760"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nebraska Network 21"/>
+       <attribute name="org_unit" value="50001184"/>
+       <attribute name="building" value="Biochemistry Hall"/>
+       <attribute name="room" value="309"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0707"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Information Services"/>
+       <attribute name="org_unit" value="50001186"/>
+       <attribute name="building" value="450 LLS"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0496"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="ADEC"/>
+       <attribute name="org_unit" value="50001187"/>
+       <attribute name="building" value="C218 ANSC"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0952"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nebraska Rural Initiative"/>
+       <attribute name="org_unit" value="50002800"/>
+       <attribute name="building" value="110 AGH"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0710"/>
+      </branch>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Student Affairs"/>
+     <attribute name="org_unit" value="50000088"/>
+     <attribute name="building" value="Administration"/>
+     <attribute name="room" value="106"/>
+     <attribute name="city" value="Lincoln"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0423"/>
+     <branch>
+      <attribute name="name" value="University Housing"/>
+      <attribute name="org_unit" value="50000955"/>
+      <attribute name="building" value="UH"/>
+      <attribute name="room" value="1115 N 16th St"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0622"/>
+      <branch>
+       <attribute name="name" value="Abel Sandoz Complex"/>
+       <attribute name="org_unit" value="50001118"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="1115 N 16th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+       <branch>
+        <attribute name="name" value="AS Residence Life"/>
+        <attribute name="org_unit" value="50001134"/>
+        <attribute name="building" value="ARH"/>
+        <attribute name="room" value="860 N 17th St/Residence Life"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0602"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="AS Dining Service"/>
+        <attribute name="org_unit" value="50001135"/>
+        <attribute name="building" value="ARH"/>
+        <attribute name="room" value="860 N 17th St/Dining Svcs"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0602"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="AS Facilities Operations"/>
+        <attribute name="org_unit" value="50001136"/>
+        <attribute name="building" value="ARH"/>
+        <attribute name="room" value="860 N 17th St/Facilities Operations"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0602"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="AS Snack Bar"/>
+        <attribute name="org_unit" value="50002305"/>
+        <attribute name="building" value="1100 N 17  / Snack Bar"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0607"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Burr Fedde Complex"/>
+       <attribute name="org_unit" value="50001119"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="1115 N 16th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+       <branch>
+        <attribute name="name" value="BF Residence Life"/>
+        <attribute name="org_unit" value="50001137"/>
+        <attribute name="building" value="BFRH"/>
+        <attribute name="room" value="1701 N 35th St/Residence Life"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0831"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="BF Facilities Operations"/>
+        <attribute name="org_unit" value="50001138"/>
+        <attribute name="building" value="BFRH"/>
+        <attribute name="room" value="1701 N 35th St/Facilites Operations"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68583-0831"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Cather Pound Neihardt Complex"/>
+       <attribute name="org_unit" value="50001120"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="1115 N 16th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+       <branch>
+        <attribute name="name" value="CPN Residence Life"/>
+        <attribute name="org_unit" value="50001139"/>
+        <attribute name="building" value="NRC"/>
+        <attribute name="room" value="540 N 16th St/Residence Life"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0626"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="CPN Dining Service"/>
+        <attribute name="org_unit" value="50001140"/>
+        <attribute name="building" value="NRC"/>
+        <attribute name="room" value="540 N 16th St/Dining Svcs"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0626"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="CPN Facilities Operations"/>
+        <attribute name="org_unit" value="50001141"/>
+        <attribute name="building" value="NRC"/>
+        <attribute name="room" value="540 N 16th St/Facilities Operations"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0629"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="CPN Snack Bar"/>
+        <attribute name="org_unit" value="50002306"/>
+        <attribute name="building" value="1100 N 17 / Snack Bar"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0607"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Harper Schramm Smith Complex"/>
+       <attribute name="org_unit" value="50001122"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="1115 N 16th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+       <branch>
+        <attribute name="name" value="HSS Residence Life"/>
+        <attribute name="org_unit" value="50001142"/>
+        <attribute name="building" value="HRH"/>
+        <attribute name="room" value="1140 N 14th St/Residence Life"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0616"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="HSS Dining Service"/>
+        <attribute name="org_unit" value="50001143"/>
+        <attribute name="building" value="HRH"/>
+        <attribute name="room" value="1140 N 14th St/Dining Svcs"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0616"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="HSS Facilities Operations"/>
+        <attribute name="org_unit" value="50001144"/>
+        <attribute name="building" value="HRH"/>
+        <attribute name="room" value="1140 N 14th St/Facilties Operations"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0616"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Husker Hall"/>
+       <attribute name="org_unit" value="50001124"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="1115 N 16th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+       <branch>
+        <attribute name="name" value="Husker Residence Life"/>
+        <attribute name="org_unit" value="50001145"/>
+        <attribute name="building" value="UH"/>
+        <attribute name="room" value="1115 N 16th St"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0621"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Love Cooperative Hall"/>
+       <attribute name="org_unit" value="50001125"/>
+       <attribute name="building" value="BFRH"/>
+       <attribute name="room" value="1701 N 35th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Selleck Quadrangle"/>
+       <attribute name="org_unit" value="50001127"/>
+       <attribute name="building" value="SELQ"/>
+       <attribute name="room" value="600 N 15th St"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+       <branch>
+        <attribute name="name" value="Selleck Residence Life"/>
+        <attribute name="org_unit" value="50001147"/>
+        <attribute name="building" value="SELQ"/>
+        <attribute name="room" value="600 N 15th St/Residence Life"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0621"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Selleck Dining Service"/>
+        <attribute name="org_unit" value="50001148"/>
+        <attribute name="building" value="SELQ"/>
+        <attribute name="room" value="600 N 15th St/Dining Svcs"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0621"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Selleck Facilities Operations"/>
+        <attribute name="org_unit" value="50001149"/>
+        <attribute name="building" value="SELQ"/>
+        <attribute name="room" value="600 N 15th St/Facilties Operations"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0621"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Selleck Snack Bar"/>
+        <attribute name="org_unit" value="50002308"/>
+        <attribute name="building" value="1100 N 17 / Snack Bar"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0607"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Housing Administration"/>
+       <attribute name="org_unit" value="50001129"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="1115 N 16th St/Administration"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+       <branch>
+        <attribute name="name" value="Educational Testing Service"/>
+        <attribute name="org_unit" value="50001130"/>
+        <attribute name="building" value="UH"/>
+        <attribute name="room" value="1115 N 16th St/ETS"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0622"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Housing Conference Services"/>
+        <attribute name="org_unit" value="50001133"/>
+        <attribute name="building" value="UH"/>
+        <attribute name="room" value="1115 N 16th St/Summer Conferences"/>
+        <attribute name="city" value="UNL"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0622"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Housing Information Systems"/>
+        <attribute name="org_unit" value="50002300"/>
+        <attribute name="building" value="1115 N 16th"/>
+        <attribute name="room" value="St. Information Systems"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0622"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Housing Marketing"/>
+        <attribute name="org_unit" value="50002301"/>
+        <attribute name="building" value="1115 N 16"/>
+        <attribute name="room" value="Marketing"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0622"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Housing Dining Service"/>
+       <attribute name="org_unit" value="50001131"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="1115 N 16th St/Dining Svcs"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Housing Facilities Operations"/>
+       <attribute name="org_unit" value="50001150"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="1115 N 16th St/Facilties Operations"/>
+       <attribute name="city" value="UNL"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0622"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Housing Business &amp; Fiscal Operations"/>
+       <attribute name="org_unit" value="50001478"/>
+       <branch>
+        <attribute name="name" value="Housing Accounting"/>
+        <attribute name="org_unit" value="50002302"/>
+        <attribute name="building" value="1115 N 16TH / Accounting"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0622"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Housing Payroll &amp; Personnel"/>
+        <attribute name="org_unit" value="50002303"/>
+        <attribute name="building" value="1115 N 16TH / Payroll &amp; Pers&#39;l"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0622"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Housing Contracts &amp; Student Accts"/>
+        <attribute name="org_unit" value="50002304"/>
+        <attribute name="building" value="1115 N 16"/>
+        <attribute name="room" value="Contracts &amp; Student Accounts"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0622"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Housing Residence Life"/>
+       <attribute name="org_unit" value="50001479"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Kauffman Center"/>
+       <attribute name="org_unit" value="50002100"/>
+       <attribute name="building" value="600 North 15th Street"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0621"/>
+       <branch>
+        <attribute name="name" value="Kauffman Residence Life"/>
+        <attribute name="org_unit" value="50002101"/>
+        <attribute name="building" value="600 North 15th Street"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0621"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Kauffman Facilities Operations"/>
+        <attribute name="org_unit" value="50002103"/>
+        <attribute name="building" value="600 North 15th Street"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0621"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Graduate House"/>
+       <attribute name="org_unit" value="50003030"/>
+       <attribute name="building" value="GH"/>
+       <attribute name="room" value="1125 N 16th St"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0639"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="The Courtyards"/>
+       <attribute name="org_unit" value="50003950"/>
+       <branch>
+        <attribute name="name" value="Courtyards Facilities Operations"/>
+        <attribute name="org_unit" value="50003951"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Courtyards Residence Life"/>
+        <attribute name="org_unit" value="50003953"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="The Village"/>
+       <attribute name="org_unit" value="50004325"/>
+       <branch>
+        <attribute name="name" value="Village Facilities Operations"/>
+        <attribute name="org_unit" value="50004326"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Village Residence Life"/>
+        <attribute name="org_unit" value="50004328"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Village Snack Bar"/>
+        <attribute name="org_unit" value="50004550"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Knoll Center"/>
+       <attribute name="org_unit" value="50006775"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="University Health Center"/>
+      <attribute name="org_unit" value="50000956"/>
+      <attribute name="building" value="15th &amp; U Street"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0618"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Nebraska Union"/>
+      <attribute name="org_unit" value="50000957"/>
+      <attribute name="building" value="Nebraska Union"/>
+      <attribute name="room" value="220"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0452"/>
+      <branch>
+       <attribute name="name" value="Child Care"/>
+       <attribute name="org_unit" value="50001112"/>
+       <attribute name="building" value="Nebraska Union"/>
+       <attribute name="room" value="220"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0452"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nebraska East Union"/>
+       <attribute name="org_unit" value="50001113"/>
+       <attribute name="building" value="East Campus Union"/>
+       <attribute name="room" value="314"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0923"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="University Dining Srvcs East"/>
+       <attribute name="org_unit" value="50001114"/>
+       <attribute name="building" value="ECU"/>
+       <attribute name="room" value="314"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68583-0923"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Student Involvement"/>
+       <attribute name="org_unit" value="50003000"/>
+       <attribute name="building" value="NU"/>
+       <attribute name="room" value="200"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0453"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="University Dining Srvcs City"/>
+       <attribute name="org_unit" value="50003001"/>
+       <attribute name="building" value="NU"/>
+       <attribute name="room" value="200"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0452"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Scholarship &amp; Financial Aid"/>
+      <attribute name="org_unit" value="50000958"/>
+      <attribute name="building" value="Administration"/>
+      <attribute name="room" value="16"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0411"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Admissions"/>
+      <attribute name="org_unit" value="50000959"/>
+      <attribute name="building" value="ALEX"/>
+      <attribute name="room" value="1410 Q St"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0417"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Career Services"/>
+      <attribute name="org_unit" value="50000960"/>
+      <attribute name="building" value="Nebraska Union"/>
+      <attribute name="room" value="230"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0451"/>
+      <branch>
+       <attribute name="name" value="Internships @ Government Agencies"/>
+       <attribute name="org_unit" value="50001116"/>
+       <attribute name="building" value="Nebraska Union"/>
+       <attribute name="room" value="230"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0451"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Off-Campus Work-Study Units"/>
+       <attribute name="org_unit" value="50001117"/>
+       <attribute name="building" value="Nebraska Union"/>
+       <attribute name="room" value="230"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0451"/>
+       <branch>
+        <attribute name="name" value="Criminal Justice (UNO Recv)"/>
+        <attribute name="org_unit" value="50001410"/>
+        <attribute name="building" value="Neihardt"/>
+        <attribute name="room" value="1100"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68588-0630"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Game &amp; Parks Commission"/>
+        <attribute name="org_unit" value="50001412"/>
+        <attribute name="building" value="2200 North 33rd Street"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68503"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="NE Historical Society"/>
+        <attribute name="org_unit" value="50001413"/>
+        <attribute name="building" value="Box 82554"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68501"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="US Attorney&#39;s Office"/>
+        <attribute name="org_unit" value="50001414"/>
+        <attribute name="building" value="100 Centennial Mall North"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68508"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Trinity Child Care"/>
+        <attribute name="org_unit" value="50001415"/>
+        <attribute name="building" value="1345 South 16th Street"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68502"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Saratoga Elementary School"/>
+        <attribute name="org_unit" value="50001600"/>
+        <attribute name="building" value="2215 S 13th St"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68502"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Calvert Elementary School"/>
+        <attribute name="org_unit" value="50001601"/>
+        <attribute name="building" value="2709 S 46th St"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68506"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Clinton Elementary School"/>
+        <attribute name="org_unit" value="50001602"/>
+        <attribute name="building" value="1520 N 29th St"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68513"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Hartley Elementary School"/>
+        <attribute name="org_unit" value="50001603"/>
+        <attribute name="building" value="730 N 33rd St"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68503"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="YMCA"/>
+        <attribute name="org_unit" value="50001675"/>
+        <attribute name="building" value="1039 P Street"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68509"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Everett Elementary"/>
+        <attribute name="org_unit" value="50001800"/>
+        <attribute name="building" value="1123 C Street"/>
+        <attribute name="city" value="68502"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="LINCOLN"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Lakeview Elementary"/>
+        <attribute name="org_unit" value="50001801"/>
+        <attribute name="building" value="300 Capital Beach Blvd"/>
+        <attribute name="city" value="68528"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="LINCOLN"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Randolph Elementary"/>
+        <attribute name="org_unit" value="50001802"/>
+        <attribute name="building" value="1024 South 37th Street"/>
+        <attribute name="city" value="68510"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="LINCOLN"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="ACLU Nebraska Foundation"/>
+        <attribute name="org_unit" value="50002625"/>
+        <attribute name="building" value="941 O St"/>
+        <attribute name="room" value="Ste 706"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68508"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Seward County Attorney&#39;s Ofc"/>
+        <attribute name="org_unit" value="50003075"/>
+        <attribute name="building" value="Seward St"/>
+        <attribute name="room" value="529"/>
+        <attribute name="city" value="Seward"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68434"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="YWCA of Lincoln"/>
+        <attribute name="org_unit" value="50003425"/>
+        <attribute name="building" value="1432 N Street"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68508"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Nebraska Pork Producers Assoc"/>
+        <attribute name="org_unit" value="50004300"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Seward County District Court"/>
+        <attribute name="org_unit" value="50004850"/>
+        <attribute name="building" value="529 Seward St, Rm 301"/>
+        <attribute name="city" value="Seward"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68434-0036"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Nebraska Appleseed Center"/>
+        <attribute name="org_unit" value="50004925"/>
+        <attribute name="building" value="941 O St, Suite 105"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68508-3626"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="United Way of Lincoln/Lancaster Cnty"/>
+        <attribute name="org_unit" value="50005250"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Northeast Family Center"/>
+        <attribute name="org_unit" value="50005875"/>
+        <attribute name="building" value="6220 Logan Ave"/>
+        <attribute name="city" value="Lincoln"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68507"/>
+       </branch>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Registration &amp; Records"/>
+      <attribute name="org_unit" value="50000961"/>
+      <attribute name="building" value="Administration"/>
+      <attribute name="room" value="59"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0416"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="TRIO Programs"/>
+      <attribute name="org_unit" value="50000962"/>
+      <attribute name="building" value="Administration"/>
+      <attribute name="room" value="220"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0498"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Office of the Dean of Students"/>
+      <attribute name="org_unit" value="50000963"/>
+      <attribute name="building" value="Administration"/>
+      <attribute name="room" value="106"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0418"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Greek Affairs"/>
+      <attribute name="org_unit" value="50000964"/>
+      <attribute name="building" value="Nebraska Union"/>
+      <attribute name="room" value="332"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0458"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Campus Recreation"/>
+      <attribute name="org_unit" value="50000965"/>
+      <attribute name="building" value="Campus Recreation"/>
+      <attribute name="room" value="55"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0232"/>
+      <branch>
+       <attribute name="name" value="Campus Rec-Admin"/>
+       <attribute name="org_unit" value="50001427"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Intramurals"/>
+       <attribute name="org_unit" value="50001428"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Fitness/Wellness"/>
+       <attribute name="org_unit" value="50001429"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Outdoor Adventure"/>
+       <attribute name="org_unit" value="50001430"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Child Care"/>
+       <attribute name="org_unit" value="50001431"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Equip Check-Out"/>
+       <attribute name="org_unit" value="50001432"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Wilderness Rental"/>
+       <attribute name="org_unit" value="50001433"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Fam Pgm/Club Spts"/>
+       <attribute name="org_unit" value="50001434"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Acad/Instruct"/>
+       <attribute name="org_unit" value="50001435"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Injury Prevent Care"/>
+       <attribute name="org_unit" value="50001436"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Grounds/Custodial"/>
+       <attribute name="org_unit" value="50001437"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-EC Activity Bldg"/>
+       <attribute name="org_unit" value="50001438"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Campus Rec-Informal"/>
+       <attribute name="org_unit" value="50001439"/>
+       <attribute name="building" value="Campus Recreation"/>
+       <attribute name="room" value="55"/>
+       <attribute name="city" value="Lincoln"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68588-0232"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Students w/ Disabilities Services"/>
+      <attribute name="org_unit" value="50000966"/>
+      <attribute name="building" value="Administration"/>
+      <attribute name="room" value="132"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0441"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="ASUN"/>
+      <attribute name="org_unit" value="50001321"/>
+      <attribute name="building" value="Nebraska Union"/>
+      <attribute name="room" value="115"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0461"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Daily Nebraskan"/>
+      <attribute name="org_unit" value="50001322"/>
+      <attribute name="building" value="Nebraska Union"/>
+      <attribute name="room" value="34"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0448"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="OASIS"/>
+      <attribute name="org_unit" value="50003126"/>
+      <attribute name="building" value="N 14th Street"/>
+      <attribute name="room" value="333"/>
+      <attribute name="city" value="Lincoln"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68508-0498"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Athletics"/>
+     <attribute name="org_unit" value="50000850"/>
+     <attribute name="building" value="SSTD"/>
+     <attribute name="room" value="116"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0122"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="Equity, Access &amp; Diversity Programs"/>
+     <attribute name="org_unit" value="50000851"/>
+     <attribute name="building" value="ADM"/>
+     <attribute name="room" value="128"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0437"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="Office of University Communications"/>
+     <attribute name="org_unit" value="50000852"/>
+     <attribute name="building" value="ADM"/>
+     <attribute name="room" value="202"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0424"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="Institutional Research &amp; Planning"/>
+     <attribute name="org_unit" value="50000853"/>
+     <attribute name="building" value="ADM"/>
+     <attribute name="room" value="332"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0435"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="Lied Center for Performing Arts"/>
+     <attribute name="org_unit" value="50000854"/>
+     <attribute name="building" value="LIED"/>
+     <attribute name="room" value="301 N 12th St"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0151"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="Sheldon Museum of Art"/>
+     <attribute name="org_unit" value="50000855"/>
+     <attribute name="building" value="SMAG"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0300"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="Lentz Center for Asian Culture"/>
+     <attribute name="org_unit" value="50000856"/>
+     <attribute name="building" value="Q"/>
+     <attribute name="room" value="1155"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0252"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="ROTC Units"/>
+     <attribute name="org_unit" value="50000857"/>
+     <attribute name="building" value="M&amp;N"/>
+     <attribute name="room" value="209"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0140"/>
+     <branch>
+      <attribute name="name" value="Aerospace Studies"/>
+      <attribute name="org_unit" value="50001155"/>
+      <attribute name="building" value="M&amp;N"/>
+      <attribute name="room" value="209"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0141"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Military Science"/>
+      <attribute name="org_unit" value="50001156"/>
+      <attribute name="building" value="M&amp;N"/>
+      <attribute name="room" value="110"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0140"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Naval Science"/>
+      <attribute name="org_unit" value="50001157"/>
+      <attribute name="building" value="M&amp;N"/>
+      <attribute name="room" value="103"/>
+      <attribute name="city" value="UNL"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0139"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Publications &amp; Photography"/>
+     <attribute name="org_unit" value="50001015"/>
+     <attribute name="building" value="NH"/>
+     <attribute name="room" value="420"/>
+     <attribute name="city" value="UNL"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0524"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="Alumni Association"/>
+     <attribute name="org_unit" value="50001411"/>
+     <attribute name="building" value="1520 R Street"/>
+     <attribute name="city" value="Lincoln"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68588-0216"/>
+    </branch>
+   </branch>
+  </branch>
+  <branch>
+   <attribute name="name" value="University of Nebraska Medical Center"/>
+   <attribute name="org_unit" value="50000004"/>
+   <branch>
+    <attribute name="name" value="Office of the Chancellor"/>
+    <attribute name="org_unit" value="50000109"/>
+    <attribute name="building" value="WH"/>
+    <attribute name="room" value="5001"/>
+    <attribute name="city" value="68198-6605"/>
+    <attribute name="state" value="NE"/>
+    <attribute name="postal_code" value="UNMC"/>
+    <branch>
+     <attribute name="name" value="Business and Finance"/>
+     <attribute name="org_unit" value="50000111"/>
+     <branch>
+      <attribute name="name" value="Human Resources"/>
+      <attribute name="org_unit" value="50000485"/>
+      <attribute name="building" value="AC"/>
+      <attribute name="room" value="2020"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5470"/>
+      <branch>
+       <attribute name="name" value="HR EE Relations &amp; Org Development"/>
+       <attribute name="org_unit" value="50000664"/>
+       <attribute name="building" value="AC"/>
+       <attribute name="room" value="2000"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5470"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="HR Staffing/Compensation/Records/IT"/>
+       <attribute name="org_unit" value="50000665"/>
+       <attribute name="building" value="AC"/>
+       <attribute name="room" value="2010"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5470"/>
+       <branch>
+        <attribute name="name" value="HR Records &amp; Information Technology"/>
+        <attribute name="org_unit" value="50001300"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="2011"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5470"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="HR Staffing &amp; Compensation"/>
+        <attribute name="org_unit" value="50006101"/>
+        <branch>
+         <attribute name="name" value="Old Org Units-Positions"/>
+         <attribute name="org_unit" value="50006102"/>
+        </branch>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="HR EE Benefits &amp; Work Life Programs"/>
+       <attribute name="org_unit" value="50006103"/>
+       <branch>
+        <attribute name="name" value="HR Benefits"/>
+        <attribute name="org_unit" value="50000666"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="2020"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5470"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="HR Child Development Center"/>
+        <attribute name="org_unit" value="50000667"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="1099C"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5570"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="HR Center for Healthy Living"/>
+        <attribute name="org_unit" value="50001227"/>
+        <attribute name="building" value="SLC"/>
+        <attribute name="room" value="1028"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5330"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="HR Faculty/Employee Assistance Prog"/>
+       <attribute name="org_unit" value="50000668"/>
+       <attribute name="building" value="SWH"/>
+       <attribute name="room" value="4019"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5205"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="HR Other Ben Eligible"/>
+       <attribute name="org_unit" value="50006300"/>
+       <branch>
+        <attribute name="name" value="Lab-Interlink"/>
+        <attribute name="org_unit" value="50000681"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="2015"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5470"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="UNMC Physicians"/>
+        <attribute name="org_unit" value="50000682"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="2015"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5470"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Specialty Retirement Cost"/>
+        <attribute name="org_unit" value="50000684"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="2015"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5470"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Retirees"/>
+        <attribute name="org_unit" value="50001352"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="2015"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5470"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Ximerex Inc."/>
+        <attribute name="org_unit" value="50001440"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="2015"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5470"/>
+       </branch>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Finance and Business Services"/>
+      <attribute name="org_unit" value="50000754"/>
+      <attribute name="building" value="AC"/>
+      <attribute name="city" value="68198-5070"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+      <branch>
+       <attribute name="name" value="Security Office"/>
+       <attribute name="org_unit" value="50000755"/>
+       <attribute name="building" value="SEC"/>
+       <attribute name="room" value="1000"/>
+       <attribute name="city" value="68198-5505"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Controller"/>
+       <attribute name="org_unit" value="50000757"/>
+       <attribute name="building" value="AC"/>
+       <attribute name="room" value="4011"/>
+       <attribute name="city" value="68198-5100"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+       <branch>
+        <attribute name="name" value="Internal Audit"/>
+        <attribute name="org_unit" value="50001229"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="5014"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5500"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="General Accounting"/>
+        <attribute name="org_unit" value="50001230"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="4006"/>
+        <attribute name="city" value="68198-5090"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Sponsored Programs Accounting"/>
+        <attribute name="org_unit" value="50001231"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="4008"/>
+        <attribute name="city" value="68198-5100"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Payroll"/>
+        <attribute name="org_unit" value="50001232"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="2033"/>
+        <attribute name="city" value="68198-5000"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Inventory Control"/>
+        <attribute name="org_unit" value="50001233"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="4006"/>
+        <attribute name="city" value="68198-5090"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="SAP Support/Cashiering"/>
+        <attribute name="org_unit" value="50001234"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="2036"/>
+        <attribute name="city" value="68198-5001"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Business Services"/>
+       <attribute name="org_unit" value="50000758"/>
+       <attribute name="building" value="AC"/>
+       <attribute name="room" value="5017"/>
+       <attribute name="city" value="68198-5060"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+       <branch>
+        <attribute name="name" value="Lions Eye Bank"/>
+        <attribute name="org_unit" value="50001235"/>
+        <attribute name="building" value="ESMA"/>
+        <attribute name="room" value="1002"/>
+        <attribute name="city" value="68198-5541"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Bookstore &amp; Parking Services"/>
+        <attribute name="org_unit" value="50006475"/>
+        <branch>
+         <attribute name="name" value="Parking Services"/>
+         <attribute name="org_unit" value="50001236"/>
+         <attribute name="building" value="AC"/>
+         <attribute name="room" value="2036"/>
+         <attribute name="city" value="68198-5001"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="UNMC"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Bookstore Services"/>
+         <attribute name="org_unit" value="50001239"/>
+         <attribute name="building" value="SLC"/>
+         <attribute name="room" value="2002"/>
+         <attribute name="city" value="68198-7025"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="UNMC"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="Printing Services"/>
+        <attribute name="org_unit" value="50001237"/>
+        <attribute name="building" value="SEB"/>
+        <attribute name="city" value="68198-7000"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Mail Services"/>
+        <attribute name="org_unit" value="50005325"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Transportation"/>
+       <attribute name="org_unit" value="50000771"/>
+       <attribute name="building" value="TRAN"/>
+       <attribute name="city" value="68198-5520"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Recycling"/>
+       <attribute name="org_unit" value="50000773"/>
+       <attribute name="building" value="SEB"/>
+       <attribute name="room" value="2019"/>
+       <attribute name="city" value="68198-7100"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Procurement"/>
+       <attribute name="org_unit" value="50001226"/>
+       <attribute name="building" value="AC"/>
+       <attribute name="room" value="3001"/>
+       <attribute name="city" value="68198-5050"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+       <branch>
+        <attribute name="name" value="Furniture Stores"/>
+        <attribute name="org_unit" value="50001240"/>
+        <attribute name="building" value="GSW"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5510"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="General Supply"/>
+        <attribute name="org_unit" value="50001241"/>
+        <attribute name="building" value="GSW"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5510"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Accounts Payable"/>
+        <attribute name="org_unit" value="50001242"/>
+        <attribute name="building" value="AC"/>
+        <attribute name="room" value="3008"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5040"/>
+       </branch>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="FMP"/>
+      <attribute name="org_unit" value="50000759"/>
+      <attribute name="building" value="SEB"/>
+      <attribute name="city" value="68198-7100"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+      <branch>
+       <attribute name="name" value="FMP-Architecture/Engineering"/>
+       <attribute name="org_unit" value="50000760"/>
+       <attribute name="building" value="SEB"/>
+       <attribute name="city" value="68198-7100"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="FMP-Administration"/>
+       <attribute name="org_unit" value="50000761"/>
+       <attribute name="building" value="SEB"/>
+       <attribute name="room" value="3002"/>
+       <attribute name="city" value="68198-7100"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="FMP-Maintenance and Utilities"/>
+       <attribute name="org_unit" value="50001246"/>
+       <attribute name="building" value="SEB"/>
+       <attribute name="city" value="68198-7100"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+       <branch>
+        <attribute name="name" value="FMP-Controls"/>
+        <attribute name="org_unit" value="50000762"/>
+        <attribute name="building" value="SEB"/>
+        <attribute name="city" value="68198-7100"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="FMP-Maintenance"/>
+        <attribute name="org_unit" value="50000764"/>
+        <attribute name="building" value="SEB"/>
+        <attribute name="city" value="68198-7100"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="FMP-Carpenters"/>
+        <attribute name="org_unit" value="50000765"/>
+        <attribute name="building" value="SEB"/>
+        <attribute name="city" value="68198-7100"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="FMP-Grounds and Labor"/>
+        <attribute name="org_unit" value="50000766"/>
+        <attribute name="building" value="SEB"/>
+        <attribute name="city" value="68198-7100"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="FMP-Electricians"/>
+        <attribute name="org_unit" value="50000767"/>
+        <attribute name="building" value="SEB"/>
+        <attribute name="city" value="68198-7100"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="FMP-Preventive/Bldg Maint"/>
+        <attribute name="org_unit" value="50000768"/>
+        <attribute name="building" value="SEB"/>
+        <attribute name="city" value="68198-7100"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="FMP-Plumbers"/>
+        <attribute name="org_unit" value="50000769"/>
+        <attribute name="building" value="SEB"/>
+        <attribute name="city" value="68198-7100"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="FMP-Central Utilities"/>
+        <attribute name="org_unit" value="50000772"/>
+        <attribute name="building" value="SEB"/>
+        <attribute name="city" value="68198-7100"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="UNMC"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="FMP-Refrigeration"/>
+        <attribute name="org_unit" value="50004800"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="FMP-Construction and Renovation"/>
+       <attribute name="org_unit" value="50001245"/>
+       <attribute name="building" value="SEB"/>
+       <attribute name="city" value="68198-7100"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Budget Analysis &amp; Financial Cmpl"/>
+      <attribute name="org_unit" value="50001228"/>
+      <attribute name="building" value="AC"/>
+      <attribute name="room" value="5008"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5080"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Computer Assisted Surgery"/>
+      <attribute name="org_unit" value="50003850"/>
+      <branch>
+       <attribute name="name" value="Advanced Clinical Application Prog"/>
+       <attribute name="org_unit" value="50006126"/>
+      </branch>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="College of Medicine"/>
+     <attribute name="org_unit" value="50000475"/>
+     <attribute name="building" value="WH"/>
+     <attribute name="room" value="5025"/>
+     <attribute name="city" value="68198-6545"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="UNMC"/>
+     <branch>
+      <attribute name="name" value="Genetics Cell Biology &amp; Anatomy"/>
+      <attribute name="org_unit" value="50000507"/>
+      <attribute name="building" value="WH"/>
+      <attribute name="room" value="3030"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-6395"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Anesthesiology"/>
+      <attribute name="org_unit" value="50000508"/>
+      <attribute name="building" value="ALBH"/>
+      <attribute name="room" value="2015"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-4455"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Biochem and Molecular Biology"/>
+      <attribute name="org_unit" value="50000510"/>
+      <attribute name="building" value="ALBH"/>
+      <attribute name="room" value="4002"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-4525"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Dean College of Medicine"/>
+      <attribute name="org_unit" value="50000511"/>
+      <attribute name="building" value="WH"/>
+      <attribute name="room" value="5025"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-6545"/>
+      <branch>
+       <attribute name="name" value="Graduate Medical Education"/>
+       <attribute name="org_unit" value="50000535"/>
+       <attribute name="building" value="SWH"/>
+       <attribute name="room" value="2009"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-4285"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Academic Affairs Office"/>
+       <attribute name="org_unit" value="50000536"/>
+       <attribute name="building" value="WH"/>
+       <attribute name="room" value="3054"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-6585"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Educational Support Office"/>
+       <attribute name="org_unit" value="50000537"/>
+       <attribute name="building" value="UGC"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5610"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="General Education"/>
+       <attribute name="org_unit" value="50000538"/>
+       <attribute name="building" value="WH"/>
+       <attribute name="room" value="5025"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-6545"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Dean&#39;s Business Office"/>
+       <attribute name="org_unit" value="50000539"/>
+       <attribute name="building" value="WH"/>
+       <attribute name="room" value="5025"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-6545"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Student Research"/>
+       <attribute name="org_unit" value="50000540"/>
+       <attribute name="building" value="WH"/>
+       <attribute name="room" value="5025"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-6545"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Primary Care Network"/>
+       <attribute name="org_unit" value="50000541"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="city" value="68198-3075"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Family Medicine"/>
+      <attribute name="org_unit" value="50000512"/>
+      <attribute name="building" value="UMA"/>
+      <attribute name="room" value="2534"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-3075"/>
+      <branch>
+       <attribute name="name" value="Lincoln Family Practice PG"/>
+       <attribute name="org_unit" value="50000561"/>
+       <attribute name="building" value="4600 VALLEY RD"/>
+       <attribute name="room" value="LINCOLN NE 68510"/>
+       <attribute name="city" value="68510"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Family Medicine Volunteer"/>
+       <attribute name="org_unit" value="50000563"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="2534"/>
+       <attribute name="city" value="68198-3075"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Family Medicine House Officers"/>
+       <attribute name="org_unit" value="50000564"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="2506"/>
+       <attribute name="city" value="68198-3075"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Internal Medicine"/>
+      <attribute name="org_unit" value="50000513"/>
+      <attribute name="building" value="UMA"/>
+      <attribute name="room" value="5508"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-3332"/>
+      <branch>
+       <attribute name="name" value="Int Med Administration"/>
+       <attribute name="org_unit" value="50000581"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="5508"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-3332"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Billing/Clinic"/>
+       <attribute name="org_unit" value="50000582"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="5508"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-3332"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Education"/>
+       <attribute name="org_unit" value="50000583"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="5508"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-3332"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Cardiology"/>
+       <attribute name="org_unit" value="50000584"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="6162"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-2265"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Dermatology"/>
+       <attribute name="org_unit" value="50000585"/>
+       <attribute name="building" value="SWH"/>
+       <attribute name="room" value="2006"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-4360"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med DEM"/>
+       <attribute name="org_unit" value="50000586"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="5508"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-3332"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med General Medicine"/>
+       <attribute name="org_unit" value="50000587"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="5546"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-3331"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Geriatrics"/>
+       <attribute name="org_unit" value="50000588"/>
+       <attribute name="building" value="UGC"/>
+       <attribute name="room" value="2096"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5620"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Infectious Diseases"/>
+       <attribute name="org_unit" value="50000589"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="5518"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5400"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Neurology"/>
+       <attribute name="org_unit" value="50000590"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="4100"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-2045"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Oncology/Hematology"/>
+       <attribute name="org_unit" value="50000591"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="3102"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-3330"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Pulmonary"/>
+       <attribute name="org_unit" value="50000592"/>
+       <attribute name="building" value="SWH"/>
+       <attribute name="room" value="4003"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5300"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Nephrology"/>
+       <attribute name="org_unit" value="50000593"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="5568B"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-3040"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Rheumatology"/>
+       <attribute name="org_unit" value="50000594"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="55107"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-3025"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Clinical Research Center"/>
+       <attribute name="org_unit" value="50000598"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="3447"/>
+       <attribute name="city" value="68198-1230"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med Occupational Health"/>
+       <attribute name="org_unit" value="50000600"/>
+       <attribute name="building" value="CH"/>
+       <attribute name="city" value="68198-7524"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Int Med GI"/>
+       <attribute name="org_unit" value="50001304"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="5530"/>
+       <attribute name="city" value="68198-2000"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Obstetrics/Gynecology"/>
+      <attribute name="org_unit" value="50000515"/>
+      <attribute name="building" value="UMA"/>
+      <attribute name="room" value="4573"/>
+      <attribute name="city" value="68198-3255"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+      <branch>
+       <attribute name="name" value="Ob/Gyn Maternal Care Prgm/Fam Plng"/>
+       <attribute name="org_unit" value="50000601"/>
+       <attribute name="building" value="5620 AMES AVE"/>
+       <attribute name="room" value="OMAHA NE 68104"/>
+       <attribute name="city" value="68104-8050"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Ob/Gyn Women, Infants &amp; Children"/>
+       <attribute name="org_unit" value="50000602"/>
+       <attribute name="building" value="412 DOVE TREE MALL"/>
+       <attribute name="room" value="42ND &amp; CENTER"/>
+       <attribute name="city" value="68198-6090"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Ob/Gyn Research Lab"/>
+       <attribute name="org_unit" value="50000603"/>
+       <attribute name="building" value="3018 SOUTH LAB"/>
+       <attribute name="room" value="OMAHA NE 68198-4515"/>
+       <attribute name="city" value="68198-4515"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Ophthalmology and Visual Sciences"/>
+      <attribute name="org_unit" value="50000516"/>
+      <attribute name="building" value="ESMA"/>
+      <attribute name="room" value="2052"/>
+      <attribute name="city" value="68198-5540"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Orthopaedic Surgery"/>
+      <attribute name="org_unit" value="50000519"/>
+      <attribute name="building" value="UMA"/>
+      <attribute name="room" value="2544"/>
+      <attribute name="city" value="68198-1080"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Otol-Head and Neck Surgery"/>
+      <attribute name="org_unit" value="50000520"/>
+      <attribute name="building" value="UH"/>
+      <attribute name="room" value="3199C"/>
+      <attribute name="city" value="68198-1225"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Pathology/Microbiology"/>
+      <attribute name="org_unit" value="50000521"/>
+      <attribute name="building" value="UMA"/>
+      <attribute name="room" value="3599"/>
+      <attribute name="city" value="68198-3135"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Pediatrics"/>
+      <attribute name="org_unit" value="50000522"/>
+      <attribute name="building" value="UH"/>
+      <attribute name="room" value="5105"/>
+      <attribute name="city" value="68198-2165"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+      <branch>
+       <attribute name="name" value="Pediatrics Administration"/>
+       <attribute name="org_unit" value="50000627"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2165"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Cardiology"/>
+       <attribute name="org_unit" value="50000628"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="2571"/>
+       <attribute name="city" value="68198-2166"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Child Health"/>
+       <attribute name="org_unit" value="50000629"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2175"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Rheumatology"/>
+       <attribute name="org_unit" value="50000630"/>
+       <attribute name="building" value="4500 AMES AVE"/>
+       <attribute name="room" value="OMAHA NE 68104-8000"/>
+       <attribute name="city" value="68104-8000"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Gastroenterology"/>
+       <attribute name="org_unit" value="50000631"/>
+       <attribute name="building" value="SWH"/>
+       <attribute name="room" value="3049"/>
+       <attribute name="city" value="68198-5160"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Hematology/Oncology"/>
+       <attribute name="org_unit" value="50000632"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2168"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Nephrology"/>
+       <attribute name="org_unit" value="50000633"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5101"/>
+       <attribute name="city" value="68198-2169"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Newborn Medicine"/>
+       <attribute name="org_unit" value="50000634"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="3135"/>
+       <attribute name="city" value="68198-1205"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Pulmonology"/>
+       <attribute name="org_unit" value="50000635"/>
+       <attribute name="building" value="SWH"/>
+       <attribute name="room" value="4025"/>
+       <attribute name="city" value="68198-5190"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Toxicology"/>
+       <attribute name="org_unit" value="50000636"/>
+       <attribute name="building" value="COP"/>
+       <attribute name="room" value="1012"/>
+       <attribute name="city" value="68198-6055"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Endocrine"/>
+       <attribute name="org_unit" value="50000637"/>
+       <attribute name="building" value="SWH"/>
+       <attribute name="room" value="4053"/>
+       <attribute name="city" value="68198-5180"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Infectious Disease"/>
+       <attribute name="org_unit" value="50000638"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2165"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Neurology"/>
+       <attribute name="org_unit" value="50000639"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2165"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Critical Care"/>
+       <attribute name="org_unit" value="50000640"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2165"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Metabolism"/>
+       <attribute name="org_unit" value="50000641"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2180"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics House Officers"/>
+       <attribute name="org_unit" value="50000642"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2185"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics General"/>
+       <attribute name="org_unit" value="50000643"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2165"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Human Molecular Genetics"/>
+       <attribute name="org_unit" value="50000644"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5105"/>
+       <attribute name="city" value="68198-2165"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Emergency Medicine"/>
+       <attribute name="org_unit" value="50000645"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5242"/>
+       <attribute name="city" value="68198-2165"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Hospitalists"/>
+       <attribute name="org_unit" value="50000646"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5242"/>
+       <attribute name="city" value="68198-2165"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Volunteer Faculty"/>
+       <attribute name="org_unit" value="50000647"/>
+       <attribute name="building" value="UH"/>
+       <attribute name="room" value="5242"/>
+       <attribute name="city" value="68198-2165"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Genetics"/>
+       <attribute name="org_unit" value="50001516"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Pediatrics Psychology"/>
+       <attribute name="org_unit" value="50001520"/>
+       <attribute name="building" value="MMI"/>
+       <attribute name="room" value="3028"/>
+       <attribute name="city" value="68198-5450"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Pharmacology/Exp Neuroscience"/>
+      <attribute name="org_unit" value="50000523"/>
+      <attribute name="building" value="PYH"/>
+      <attribute name="room" value="5011"/>
+      <attribute name="city" value="68198-6260"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Cellular/Integrative Physiology"/>
+      <attribute name="org_unit" value="50000525"/>
+      <attribute name="building" value="ALBH"/>
+      <attribute name="room" value="6010"/>
+      <attribute name="city" value="68198-4575"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Psychiatry"/>
+      <attribute name="org_unit" value="50000526"/>
+      <attribute name="building" value="UGC"/>
+      <attribute name="city" value="68198-5575"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Radiology"/>
+      <attribute name="org_unit" value="50000527"/>
+      <attribute name="building" value="UH"/>
+      <attribute name="city" value="68198-1045"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Surgery"/>
+      <attribute name="org_unit" value="50000528"/>
+      <attribute name="building" value="UMA"/>
+      <attribute name="room" value="4585"/>
+      <attribute name="city" value="68198-3280"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+      <branch>
+       <attribute name="name" value="Surgery-Billing &amp; Compliance"/>
+       <attribute name="org_unit" value="50003925"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgery-Cardiovascular&amp;Thoracic Surg"/>
+       <attribute name="org_unit" value="50003926"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgery-General Surgery"/>
+       <attribute name="org_unit" value="50003927"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgery-House Officers"/>
+       <attribute name="org_unit" value="50003928"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgery-Neurosurgery"/>
+       <attribute name="org_unit" value="50003929"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgery-Oral &amp; Maxillofacial"/>
+       <attribute name="org_unit" value="50003930"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgery-Plastic&amp;Reconstructive"/>
+       <attribute name="org_unit" value="50003931"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgery-Research"/>
+       <attribute name="org_unit" value="50003932"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgery-Transplant"/>
+       <attribute name="org_unit" value="50003933"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgery-Urologic Surgery"/>
+       <attribute name="org_unit" value="50003934"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Surgical Oncology"/>
+       <attribute name="org_unit" value="50005675"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Continuing Education"/>
+      <attribute name="org_unit" value="50000529"/>
+      <attribute name="building" value="UGC"/>
+      <attribute name="room" value="1069"/>
+      <attribute name="city" value="68198-5651"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Radiation Oncology"/>
+      <attribute name="org_unit" value="50000653"/>
+      <attribute name="building" value="ESH"/>
+      <attribute name="room" value="10025"/>
+      <attribute name="city" value="68198-1050"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Emergency Medicine"/>
+      <attribute name="org_unit" value="50000655"/>
+      <attribute name="building" value="UH"/>
+      <attribute name="room" value="2149"/>
+      <attribute name="city" value="68198-1150"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Neurological Sciences"/>
+      <attribute name="org_unit" value="50001975"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="College of Nursing"/>
+     <attribute name="org_unit" value="50000476"/>
+     <attribute name="building" value="CN"/>
+     <attribute name="room" value="2007"/>
+     <attribute name="city" value="UNMC"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68198-5330"/>
+     <branch>
+      <attribute name="name" value="CON-Omaha"/>
+      <attribute name="org_unit" value="50000658"/>
+      <attribute name="building" value="CN"/>
+      <attribute name="room" value="2007"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5330"/>
+      <branch>
+       <attribute name="name" value="CON-Rural Nursing Education"/>
+       <attribute name="org_unit" value="50001248"/>
+       <attribute name="building" value="CN"/>
+       <attribute name="room" value="4007"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5330"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Learning Resource Center"/>
+       <attribute name="org_unit" value="50001249"/>
+       <attribute name="building" value="CN"/>
+       <attribute name="room" value="3007A"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5330"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Student Services"/>
+       <attribute name="org_unit" value="50001250"/>
+       <attribute name="building" value="CN"/>
+       <attribute name="room" value="4047"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5330"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Niedfelt Nursing Research Center"/>
+       <attribute name="org_unit" value="50001251"/>
+       <attribute name="building" value="CN"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5330"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Community-Based Health"/>
+       <attribute name="org_unit" value="50001252"/>
+       <attribute name="building" value="CN"/>
+       <attribute name="room" value="4048"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5330"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Adult Health &amp; Illness Dpt"/>
+       <attribute name="org_unit" value="50001253"/>
+       <attribute name="building" value="CN"/>
+       <attribute name="room" value="5048"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5330"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Families &amp; Health Systems"/>
+       <attribute name="org_unit" value="50001254"/>
+       <attribute name="building" value="CN"/>
+       <attribute name="room" value="5035"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5330"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Continuing Education"/>
+       <attribute name="org_unit" value="50001255"/>
+       <attribute name="building" value="CN"/>
+       <attribute name="room" value="2007"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5330"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Nursing Centers"/>
+       <attribute name="org_unit" value="50001256"/>
+       <attribute name="building" value="CN"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-5330"/>
+       <branch>
+        <attribute name="name" value="CON-Family Health Center"/>
+        <attribute name="org_unit" value="50001257"/>
+        <attribute name="building" value="5211 S 31ST ST"/>
+        <attribute name="room" value="OMAHA NE 68107"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-8045"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="CON-Mobile Nursing Center"/>
+        <attribute name="org_unit" value="50001258"/>
+        <attribute name="building" value="CN"/>
+        <attribute name="room" value="4056"/>
+        <attribute name="city" value="UNMC"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68198-5330"/>
+       </branch>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="CON-Lincoln"/>
+      <attribute name="org_unit" value="50000659"/>
+      <attribute name="building" value="CON-LINCOLN"/>
+      <attribute name="room" value="FAIR 104"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68588-0620"/>
+      <branch>
+       <attribute name="name" value="CON-Lincoln GPCH"/>
+       <attribute name="org_unit" value="50002075"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Lincoln AHI"/>
+       <attribute name="org_unit" value="50002076"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CON-Lincoln PAES"/>
+       <attribute name="org_unit" value="50002077"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="CON-West Ne Division"/>
+      <attribute name="org_unit" value="50000660"/>
+      <attribute name="building" value="CON-WEST NEBDIV"/>
+      <attribute name="room" value="4502 AVE I"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="69361-4939"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="CON-Kearney"/>
+      <attribute name="org_unit" value="50000661"/>
+      <attribute name="building" value="CON-KRNY"/>
+      <attribute name="room" value="905 W 25TH ST"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="CON-Northern Division"/>
+      <attribute name="org_unit" value="50006650"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="College of Pharmacy"/>
+     <attribute name="org_unit" value="50000484"/>
+     <attribute name="building" value="COP"/>
+     <attribute name="city" value="UNMC"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68198-6000"/>
+     <branch>
+      <attribute name="name" value="COP Dean&#39;s Office"/>
+      <attribute name="org_unit" value="50000720"/>
+      <attribute name="building" value="COP"/>
+      <attribute name="room" value="2037"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-6000"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COP Pharmacy Practice"/>
+      <attribute name="org_unit" value="50000721"/>
+      <attribute name="building" value="COP"/>
+      <attribute name="room" value="4037"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-6000"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COP Pharmaceutical Science"/>
+      <attribute name="org_unit" value="50000722"/>
+      <attribute name="building" value="COP"/>
+      <attribute name="room" value="3026"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-6000"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Eppley Institute"/>
+     <attribute name="org_unit" value="50000486"/>
+     <attribute name="building" value="EI"/>
+     <attribute name="city" value="UNMC"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68198-6805"/>
+     <branch>
+      <attribute name="name" value="Eppley Inst Research"/>
+      <attribute name="org_unit" value="50000686"/>
+      <attribute name="building" value="EI"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-6805"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Eppley Inst Administration"/>
+      <attribute name="org_unit" value="50001825"/>
+      <attribute name="building" value="EI"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-6805"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Eppley Inst Faculty"/>
+      <attribute name="org_unit" value="50001826"/>
+      <attribute name="building" value="EI"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-6805"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Eppley Inst Students"/>
+      <attribute name="org_unit" value="50001900"/>
+      <attribute name="building" value="EI"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-6805"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Munroe-Meyer Institute"/>
+     <attribute name="org_unit" value="50000487"/>
+     <attribute name="building" value="MMI"/>
+     <attribute name="city" value="UNMC"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68198-5450"/>
+     <branch>
+      <attribute name="name" value="MMI Administration"/>
+      <attribute name="org_unit" value="50000687"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="3042"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Patient Information Office"/>
+      <attribute name="org_unit" value="50000688"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="2019"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Education and Child Development"/>
+      <attribute name="org_unit" value="50000689"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="2015"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Recreation Program"/>
+      <attribute name="org_unit" value="50000690"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Business Office"/>
+      <attribute name="org_unit" value="50000691"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="2016"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Health Policy and Planning"/>
+      <attribute name="org_unit" value="50000693"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Genetic Medicine"/>
+      <attribute name="org_unit" value="50000694"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="3066"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Nursing"/>
+      <attribute name="org_unit" value="50000695"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="3060"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Occupational Therapy"/>
+      <attribute name="org_unit" value="50000696"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="2023"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Physical Therapy"/>
+      <attribute name="org_unit" value="50000697"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="2023"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Psychology"/>
+      <attribute name="org_unit" value="50000698"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="3001"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Speech Pathology"/>
+      <attribute name="org_unit" value="50000699"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="3027"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Social Services"/>
+      <attribute name="org_unit" value="50000700"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="3040"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Cytogenetics"/>
+      <attribute name="org_unit" value="50000701"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="2055"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Nutrition"/>
+      <attribute name="org_unit" value="50000702"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="3060"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Media Department"/>
+      <attribute name="org_unit" value="50000703"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="1005"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Pediatric Diabetes"/>
+      <attribute name="org_unit" value="50000704"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI HBM Molecular Genetics"/>
+      <attribute name="org_unit" value="50000705"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="2055"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Brace Place"/>
+      <attribute name="org_unit" value="50000706"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="1065"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Developmental Medicine"/>
+      <attribute name="org_unit" value="50001442"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI HBM Center for Human Genetics"/>
+      <attribute name="org_unit" value="50002125"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Ctr for Autism Spec Disord"/>
+      <attribute name="org_unit" value="50004879"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="MMI Ctr for Ped Feeding Disord"/>
+      <attribute name="org_unit" value="50006125"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Information Technology Services"/>
+     <attribute name="org_unit" value="50000488"/>
+     <attribute name="building" value="CC"/>
+     <attribute name="room" value="2013"/>
+     <attribute name="city" value="UNMC"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68198-5030"/>
+     <branch>
+      <attribute name="name" value="ITS Data Center Operations"/>
+      <attribute name="org_unit" value="50000707"/>
+      <attribute name="building" value="CC"/>
+      <attribute name="room" value="2013"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5030"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="ITS Customer Support Services"/>
+      <attribute name="org_unit" value="50000709"/>
+      <attribute name="building" value="CC"/>
+      <attribute name="room" value="2013"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5030"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="ITS Application Services"/>
+      <attribute name="org_unit" value="50000710"/>
+      <attribute name="building" value="CC"/>
+      <attribute name="room" value="2013"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5030"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="ITS Telecommunications"/>
+      <attribute name="org_unit" value="50000712"/>
+      <attribute name="building" value="CC"/>
+      <attribute name="room" value="2013"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5030"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="ITS Technical Services"/>
+      <attribute name="org_unit" value="50000713"/>
+      <attribute name="building" value="CC"/>
+      <attribute name="room" value="2013"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5030"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="ITS Video Services"/>
+      <attribute name="org_unit" value="50000714"/>
+      <attribute name="building" value="SWH"/>
+      <attribute name="room" value="1021"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5170"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="ITS Learning Env/Internet Services"/>
+      <attribute name="org_unit" value="50000715"/>
+      <attribute name="building" value="CC"/>
+      <attribute name="room" value="2013"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5030"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="ITS Data Installation Services"/>
+      <attribute name="org_unit" value="50000716"/>
+      <attribute name="building" value="CC"/>
+      <attribute name="room" value="2013"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5030"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="ITS Network/Technical Services"/>
+      <attribute name="org_unit" value="50000717"/>
+      <attribute name="building" value="CC"/>
+      <attribute name="room" value="2013"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5030"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="UNMC Physicians"/>
+     <attribute name="org_unit" value="50000497"/>
+     <branch>
+      <attribute name="name" value="UNMC Physicians-Administration"/>
+      <attribute name="org_unit" value="50000718"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="UNMC Physicians-Compliance"/>
+      <attribute name="org_unit" value="50001308"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="College of Dentistry"/>
+     <attribute name="org_unit" value="50000719"/>
+     <branch>
+      <attribute name="name" value="COD-Dental Administration"/>
+      <attribute name="org_unit" value="50000735"/>
+      <attribute name="building" value="DENT"/>
+      <attribute name="room" value="110A"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0740"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COD-Adult Restorative"/>
+      <attribute name="org_unit" value="50000736"/>
+      <attribute name="building" value="DENT"/>
+      <attribute name="room" value="119"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0740"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COD-Lincoln Clinic Administration"/>
+      <attribute name="org_unit" value="50000737"/>
+      <attribute name="building" value="DENT"/>
+      <attribute name="room" value="110A"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0740"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COD-Dental Practice Management"/>
+      <attribute name="org_unit" value="50000738"/>
+      <attribute name="building" value="DENT"/>
+      <attribute name="room" value="10"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0740"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COD-Dental Hygiene"/>
+      <attribute name="org_unit" value="50000739"/>
+      <attribute name="building" value="DENT"/>
+      <attribute name="room" value="108"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0740"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COD-Oral Biology"/>
+      <attribute name="org_unit" value="50000741"/>
+      <attribute name="building" value="DENT"/>
+      <attribute name="room" value="20"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0740"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COD-University Dental Associates"/>
+      <attribute name="org_unit" value="50000744"/>
+      <attribute name="building" value="DENT"/>
+      <attribute name="room" value="110A"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0740"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COD-Surgical Specialties"/>
+      <attribute name="org_unit" value="50000750"/>
+      <attribute name="building" value="DENT"/>
+      <attribute name="room" value="131"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0740"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COD-Hospital Dentistry"/>
+      <attribute name="org_unit" value="50000752"/>
+      <attribute name="building" value="MMI"/>
+      <attribute name="room" value="1008"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5450"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COD-Growth and Development"/>
+      <attribute name="org_unit" value="50000753"/>
+      <attribute name="building" value="DENT"/>
+      <attribute name="room" value="158F"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68583-0740"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="School of Allied Health Professions"/>
+     <attribute name="org_unit" value="50000723"/>
+     <attribute name="building" value="SWH"/>
+     <attribute name="room" value="3017"/>
+     <attribute name="city" value="UNMC"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68198-5150"/>
+     <branch>
+      <attribute name="name" value="Allied Health-Hlth Serv Admin Div"/>
+      <attribute name="org_unit" value="50000724"/>
+      <attribute name="building" value="SWH"/>
+      <attribute name="room" value="3017"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5150"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Medical Nutrition Education Div"/>
+      <attribute name="org_unit" value="50000725"/>
+      <attribute name="building" value="UH"/>
+      <attribute name="room" value="3431"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-1200"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Division of Laboratory Sciences"/>
+      <attribute name="org_unit" value="50004750"/>
+      <branch>
+       <attribute name="name" value="Clinical Laboratory Science"/>
+       <attribute name="org_unit" value="50000726"/>
+       <attribute name="building" value="UMA"/>
+       <attribute name="room" value="3578"/>
+       <attribute name="city" value="UNMC"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68198-3135"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Cytotechnology"/>
+       <attribute name="org_unit" value="50004275"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Radiation Science Technology Div"/>
+      <attribute name="org_unit" value="50000727"/>
+      <attribute name="building" value="UMA"/>
+      <attribute name="room" value="1537A"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-1045"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Physician Assistant"/>
+      <attribute name="org_unit" value="50000728"/>
+      <attribute name="building" value="ANNEX I"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-4300"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Physical Therapy Education"/>
+      <attribute name="org_unit" value="50000729"/>
+      <attribute name="building" value="SLC"/>
+      <attribute name="room" value="2029"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-4420"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Radiation Therapy Technology Div"/>
+      <attribute name="org_unit" value="50000730"/>
+      <attribute name="building" value="UH"/>
+      <attribute name="room" value="1312C"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-1045"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Radiologic Technology Division"/>
+      <attribute name="org_unit" value="50000731"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Clinical Perfusion Education"/>
+      <attribute name="org_unit" value="50000732"/>
+      <attribute name="building" value="SWH"/>
+      <attribute name="room" value="3019"/>
+      <attribute name="city" value="UNMC"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68198-5155"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Diagnostic Medical Sonography"/>
+      <attribute name="org_unit" value="50004276"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Nuclear Medicine Technology"/>
+      <attribute name="org_unit" value="50004277"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Chancellor&#39;s Support Staff"/>
+     <attribute name="org_unit" value="50001203"/>
+     <attribute name="building" value="WH"/>
+     <attribute name="city" value="68198-6605"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="UNMC"/>
+     <branch>
+      <attribute name="name" value="International Health &amp; Medical Ed"/>
+      <attribute name="org_unit" value="50005501"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Vice Chancellor  External Affairs"/>
+     <attribute name="org_unit" value="50001204"/>
+     <attribute name="building" value="WH"/>
+     <attribute name="room" value="5001"/>
+     <attribute name="city" value="68198-6630"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="UNMC"/>
+     <branch>
+      <attribute name="name" value="Public Relations"/>
+      <attribute name="org_unit" value="50001206"/>
+      <attribute name="building" value="SWH"/>
+      <attribute name="room" value="5033"/>
+      <attribute name="city" value="68198-5230"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Alumni Relations"/>
+      <attribute name="org_unit" value="50001207"/>
+      <attribute name="building" value="510 S 38TH AVE"/>
+      <attribute name="city" value="68198-5200"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Academic Affairs"/>
+     <attribute name="org_unit" value="50001205"/>
+     <attribute name="building" value="ESH"/>
+     <attribute name="city" value="68198-6810"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="UNMC"/>
+     <branch>
+      <attribute name="name" value="Graduate Studies"/>
+      <attribute name="org_unit" value="50001210"/>
+      <attribute name="building" value="ESH"/>
+      <attribute name="city" value="68198-6810"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Library of Medicine"/>
+      <attribute name="org_unit" value="50001211"/>
+      <attribute name="building" value="WH"/>
+      <attribute name="city" value="68198-6705"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Student Affairs"/>
+      <attribute name="org_unit" value="50001212"/>
+      <attribute name="building" value="SLC"/>
+      <attribute name="room" value="2048"/>
+      <attribute name="city" value="68198-4250"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+      <branch>
+       <attribute name="name" value="Financial Aid"/>
+       <attribute name="org_unit" value="50001218"/>
+       <attribute name="building" value="SLC"/>
+       <attribute name="room" value="2045"/>
+       <attribute name="city" value="68198-4565"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Academic Records"/>
+       <attribute name="org_unit" value="50001219"/>
+       <attribute name="building" value="SLC"/>
+       <attribute name="room" value="2037"/>
+       <attribute name="city" value="68198-4230"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Office for Std Equity &amp; Multi-Cultrl"/>
+       <attribute name="org_unit" value="50001220"/>
+       <attribute name="building" value="SLC"/>
+       <attribute name="room" value="2069"/>
+       <attribute name="city" value="68198-4275"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Student Financial Services"/>
+       <attribute name="org_unit" value="50002675"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Youth Learning Center"/>
+       <attribute name="org_unit" value="50006225"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Office of Regulatory Affairs"/>
+      <attribute name="org_unit" value="50001214"/>
+      <attribute name="building" value="ESH"/>
+      <attribute name="city" value="68198-6810"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+      <branch>
+       <attribute name="name" value="Institutional Review Board"/>
+       <attribute name="org_unit" value="50001222"/>
+       <attribute name="building" value="ESH"/>
+       <attribute name="room" value="3018"/>
+       <attribute name="city" value="68198-6810"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Chemical and Radiation Safety"/>
+       <attribute name="org_unit" value="50001224"/>
+       <attribute name="building" value="AAIII"/>
+       <attribute name="city" value="68198-5480"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="IACUC"/>
+       <attribute name="org_unit" value="50001775"/>
+       <attribute name="building" value="ESH"/>
+       <attribute name="city" value="68198-6810"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="UNMC"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Academic Services"/>
+      <attribute name="org_unit" value="50001215"/>
+      <attribute name="building" value="ESH"/>
+      <attribute name="city" value="68198-6655"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="International Studies and Programs"/>
+      <attribute name="org_unit" value="50001221"/>
+      <attribute name="building" value="A4"/>
+      <attribute name="room" value="M001"/>
+      <attribute name="city" value="68198-5735"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="College of Public Health"/>
+     <attribute name="org_unit" value="50005229"/>
+     <branch>
+      <attribute name="name" value="COPH Health Prof Tracking Center"/>
+      <attribute name="org_unit" value="50001208"/>
+      <attribute name="building" value="A4"/>
+      <attribute name="room" value="1003"/>
+      <attribute name="city" value="68198-6690"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Rural Health Education Ntwk"/>
+      <attribute name="org_unit" value="50001209"/>
+      <attribute name="building" value="A4"/>
+      <attribute name="room" value="1001"/>
+      <attribute name="city" value="68198-6660"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Office of the Dean"/>
+      <attribute name="org_unit" value="50005230"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Biosecurity &amp; Biopreparedness"/>
+      <attribute name="org_unit" value="50005425"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Biostatistics"/>
+      <attribute name="org_unit" value="50005426"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Environ, Agri &amp; Occ Health Sci"/>
+      <attribute name="org_unit" value="50005427"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Epidemiology"/>
+      <attribute name="org_unit" value="50005428"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Health Disparities"/>
+      <attribute name="org_unit" value="50005429"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Hlth Prm, Soc, &amp; Behv Hlth Sci"/>
+      <attribute name="org_unit" value="50005431"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Health Services Res &amp; Admin"/>
+      <attribute name="org_unit" value="50005432"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Research Design and Analysis"/>
+      <attribute name="org_unit" value="50005800"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="COPH Ctr for Humanities, Ethics&amp;Soc"/>
+      <attribute name="org_unit" value="50006379"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Vice Chancellor for Research"/>
+     <attribute name="org_unit" value="50002601"/>
+     <branch>
+      <attribute name="name" value="Intellectual Property Office"/>
+      <attribute name="org_unit" value="50001213"/>
+      <attribute name="building" value="A9"/>
+      <attribute name="city" value="68198-6099"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Sponsored Programs Administration"/>
+      <attribute name="org_unit" value="50001217"/>
+      <attribute name="building" value="ESH"/>
+      <attribute name="city" value="68198-6810"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Comparative Medicine"/>
+      <attribute name="org_unit" value="50001223"/>
+      <attribute name="building" value="WH"/>
+      <attribute name="room" value="2057"/>
+      <attribute name="city" value="68198-6385"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Clinical Trials Office"/>
+      <attribute name="org_unit" value="50001225"/>
+      <attribute name="building" value="UH"/>
+      <attribute name="room" value="3447"/>
+      <attribute name="city" value="68198-1230"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="UNeMED Corporation"/>
+      <attribute name="org_unit" value="50001750"/>
+      <attribute name="building" value="A9"/>
+      <attribute name="city" value="68198-6099"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="UNMC"/>
+     </branch>
+    </branch>
+   </branch>
+  </branch>
+  <branch>
+   <attribute name="name" value="University of Nebraska at Omaha"/>
+   <attribute name="org_unit" value="50000005"/>
+   <branch>
+    <attribute name="name" value="Office of the Chancellor"/>
+    <attribute name="org_unit" value="50000089"/>
+    <attribute name="building" value="EAB"/>
+    <attribute name="room" value="201"/>
+    <attribute name="city" value="Omaha"/>
+    <attribute name="state" value="NE"/>
+    <attribute name="postal_code" value="68182"/>
+    <branch>
+     <attribute name="name" value="Business and Finance"/>
+     <attribute name="org_unit" value="50000090"/>
+     <attribute name="building" value="EAB"/>
+     <attribute name="room" value="209"/>
+     <attribute name="city" value="Omaha"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68182"/>
+     <branch>
+      <attribute name="name" value="Finance"/>
+      <attribute name="org_unit" value="50000187"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="209"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Controller"/>
+       <attribute name="org_unit" value="50000192"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="208"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Accounting Services"/>
+        <attribute name="org_unit" value="50000199"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="208"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Cashiering/Student Accounts"/>
+        <attribute name="org_unit" value="50000200"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="107"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Grants Accounting"/>
+       <attribute name="org_unit" value="50000193"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="208"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Budget"/>
+       <attribute name="org_unit" value="50000194"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="209"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Position Number Holding Area"/>
+        <attribute name="org_unit" value="50003829"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Operations Analysis &amp; Internal Audit"/>
+       <attribute name="org_unit" value="50000195"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="209"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Purchasing Department"/>
+       <attribute name="org_unit" value="50000778"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="208"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Facilities Management and Planning"/>
+      <attribute name="org_unit" value="50000188"/>
+      <attribute name="building" value="Center Location"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Environmental Services"/>
+       <attribute name="org_unit" value="50000276"/>
+       <attribute name="building" value="ENGG"/>
+       <attribute name="room" value="113"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Custodial Services"/>
+        <attribute name="org_unit" value="50000783"/>
+        <attribute name="building" value="CB"/>
+        <attribute name="room" value="139"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Grounds"/>
+        <attribute name="org_unit" value="50000784"/>
+        <attribute name="building" value="Annex"/>
+        <attribute name="room" value="16"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Maintenance and Operations"/>
+       <attribute name="org_unit" value="50000277"/>
+       <attribute name="building" value="CB"/>
+       <attribute name="room" value="139"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Construction Services"/>
+       <attribute name="org_unit" value="50000278"/>
+       <attribute name="building" value="Center Location"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Planning and Architectural Services"/>
+       <attribute name="org_unit" value="50000279"/>
+       <attribute name="building" value="Center Location"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Human Resources/Payroll Services"/>
+      <attribute name="org_unit" value="50000189"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="205"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Human Resources"/>
+       <attribute name="org_unit" value="50000190"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="205"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Retirees"/>
+        <attribute name="org_unit" value="50001353"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Volunteers"/>
+        <attribute name="org_unit" value="50001511"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Payroll"/>
+       <attribute name="org_unit" value="50000191"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="206"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Milo Bail Student Center"/>
+      <attribute name="org_unit" value="50000198"/>
+      <attribute name="building" value="Business Office"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Food Service"/>
+       <attribute name="org_unit" value="50000875"/>
+       <attribute name="building" value="MBSC"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="MBSC Business Operations"/>
+       <attribute name="org_unit" value="50000876"/>
+       <attribute name="building" value="MBSC"/>
+       <attribute name="room" value="Admin Office"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Child Care Center"/>
+       <attribute name="org_unit" value="50000878"/>
+       <attribute name="building" value="Annex"/>
+       <attribute name="room" value="47"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Bookstore"/>
+       <attribute name="org_unit" value="50000879"/>
+       <attribute name="building" value="MBSC"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Mav Card Services"/>
+       <attribute name="org_unit" value="50004050"/>
+       <attribute name="building" value="MBSC"/>
+       <attribute name="room" value="Business Office"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Support Services"/>
+      <attribute name="org_unit" value="50000275"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="100"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Security and Traffic"/>
+       <attribute name="org_unit" value="50000776"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="100"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Mail Services"/>
+       <attribute name="org_unit" value="50000777"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="106"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Environmental Health &amp; Safety"/>
+       <attribute name="org_unit" value="50000779"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="100"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Auto Pool"/>
+       <attribute name="org_unit" value="50000780"/>
+       <attribute name="building" value="Annex"/>
+       <attribute name="room" value="16"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Telecommunications"/>
+       <attribute name="org_unit" value="50000782"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="119"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Special Projects"/>
+      <attribute name="org_unit" value="50001450"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="202"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Academic and Student Affairs"/>
+     <attribute name="org_unit" value="50000092"/>
+     <attribute name="building" value="EAB"/>
+     <attribute name="room" value="202"/>
+     <attribute name="city" value="Omaha"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68182"/>
+     <branch>
+      <attribute name="name" value="Student Affairs"/>
+      <attribute name="org_unit" value="50000093"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="202"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Student Services"/>
+       <attribute name="org_unit" value="50000196"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="202"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Student Org &amp; Leadership Programs"/>
+        <attribute name="org_unit" value="50000877"/>
+        <attribute name="building" value="MBSC"/>
+        <attribute name="room" value="Business Office"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Campus Recreation"/>
+        <attribute name="org_unit" value="50000881"/>
+        <attribute name="building" value="HPER"/>
+        <attribute name="room" value="100"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+        <branch>
+         <attribute name="name" value="Aquatic Activities"/>
+         <attribute name="org_unit" value="50000882"/>
+         <attribute name="building" value="HPER"/>
+         <attribute name="room" value="100"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+         <branch>
+          <attribute name="name" value="Adult Swim Program"/>
+          <attribute name="org_unit" value="50000930"/>
+          <attribute name="building" value="HPER"/>
+          <attribute name="room" value="100"/>
+          <attribute name="city" value="Omaha"/>
+          <attribute name="state" value="NE"/>
+          <attribute name="postal_code" value="68182"/>
+         </branch>
+        </branch>
+        <branch>
+         <attribute name="name" value="Fclties, Intmrl Sprts &amp; Spcl Events"/>
+         <attribute name="org_unit" value="50000883"/>
+         <attribute name="building" value="HPER"/>
+         <attribute name="room" value="100"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Outdoor Recreation"/>
+         <attribute name="org_unit" value="50000884"/>
+         <attribute name="building" value="HPER"/>
+         <attribute name="room" value="100"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Sports Clubs &amp; Youth Programs"/>
+         <attribute name="org_unit" value="50000885"/>
+         <attribute name="building" value="HPER"/>
+         <attribute name="room" value="100"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="Counseling/University Division"/>
+        <attribute name="org_unit" value="50000891"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="115"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Health Services"/>
+        <attribute name="org_unit" value="50000919"/>
+        <attribute name="building" value="MBSC"/>
+        <attribute name="room" value="132"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+        <branch>
+         <attribute name="name" value="Achol &amp; Drug Education"/>
+         <attribute name="org_unit" value="50000921"/>
+         <attribute name="building" value="EAB"/>
+         <attribute name="room" value="115"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="Housing"/>
+        <attribute name="org_unit" value="50006375"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="202"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+        <branch>
+         <attribute name="name" value="Maverick Village"/>
+         <attribute name="org_unit" value="50006376"/>
+         <attribute name="building" value="6608 University Drive South"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+        </branch>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Academic Records and Registration"/>
+       <attribute name="org_unit" value="50000197"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="101"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Academic Support Services"/>
+        <attribute name="org_unit" value="50000923"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="105"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Enrollment Services"/>
+       <attribute name="org_unit" value="50003828"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="115"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Testing Center"/>
+        <attribute name="org_unit" value="50000893"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="113"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Orientation"/>
+        <attribute name="org_unit" value="50000918"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="111"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Recruitment Services"/>
+        <attribute name="org_unit" value="50000925"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="111"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Multicultural Affairs"/>
+       <attribute name="org_unit" value="50000894"/>
+       <attribute name="building" value="MBSC"/>
+       <attribute name="room" value="lst Floor"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Project Achieve"/>
+       <attribute name="org_unit" value="50000895"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="117"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Srvs for Students with Disabilities"/>
+       <attribute name="org_unit" value="50000920"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="204"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Undergraduate Admissions"/>
+       <attribute name="org_unit" value="50000922"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="103"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Records &amp; Registration"/>
+       <attribute name="org_unit" value="50000924"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="105"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="MavLink"/>
+        <attribute name="org_unit" value="50006850"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Financial Aid"/>
+       <attribute name="org_unit" value="50000926"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="103"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Veteran Services"/>
+        <attribute name="org_unit" value="50000929"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="103"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Career Center"/>
+       <attribute name="org_unit" value="50003827"/>
+       <attribute name="building" value="MBSC"/>
+       <attribute name="room" value="111"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Arts and Sciences"/>
+      <attribute name="org_unit" value="50000175"/>
+      <attribute name="building" value="ASH"/>
+      <attribute name="room" value="278"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Biology"/>
+       <attribute name="org_unit" value="50000801"/>
+       <attribute name="building" value="AH"/>
+       <attribute name="room" value="114"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Black Studies"/>
+       <attribute name="org_unit" value="50000802"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="184"/>
+       <attribute name="city" value="OMAHA"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Chemistry"/>
+       <attribute name="org_unit" value="50000803"/>
+       <attribute name="building" value="DSC"/>
+       <attribute name="room" value="337"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="English"/>
+       <attribute name="org_unit" value="50000804"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="192"/>
+       <attribute name="city" value="OMAHA"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Foreign Languages"/>
+       <attribute name="org_unit" value="50000806"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="301"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Geography/Geology"/>
+       <attribute name="org_unit" value="50000807"/>
+       <attribute name="building" value="DSC"/>
+       <attribute name="room" value="260"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="History"/>
+       <attribute name="org_unit" value="50000808"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="287"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Mathematics"/>
+       <attribute name="org_unit" value="50000809"/>
+       <attribute name="building" value="DSC"/>
+       <attribute name="room" value="203"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Philosophy &amp; Religion"/>
+       <attribute name="org_unit" value="50000810"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="205"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Physics"/>
+       <attribute name="org_unit" value="50000811"/>
+       <attribute name="building" value="DSC"/>
+       <attribute name="room" value="129"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Political Science"/>
+       <attribute name="org_unit" value="50000812"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="275"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Psychology"/>
+       <attribute name="org_unit" value="50000813"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="347"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Sociology"/>
+       <attribute name="org_unit" value="50000814"/>
+       <attribute name="building" value="ENGG"/>
+       <attribute name="room" value="116"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Business Administration"/>
+      <attribute name="org_unit" value="50000176"/>
+      <attribute name="building" value="RH"/>
+      <attribute name="room" value="414"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Department of Accounting"/>
+       <attribute name="org_unit" value="50000862"/>
+       <attribute name="building" value="RH"/>
+       <attribute name="room" value="408"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Economics"/>
+       <attribute name="org_unit" value="50000863"/>
+       <attribute name="building" value="RH"/>
+       <attribute name="room" value="508"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Finance, Banking and Law"/>
+       <attribute name="org_unit" value="50000864"/>
+       <attribute name="building" value="RH"/>
+       <attribute name="room" value="501"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Marketing and Management"/>
+       <attribute name="org_unit" value="50000865"/>
+       <attribute name="building" value="RH"/>
+       <attribute name="room" value="503"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Executive MBA Program"/>
+       <attribute name="org_unit" value="50000872"/>
+       <attribute name="building" value="RH"/>
+       <attribute name="room" value="414"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nebraska Business Development Center"/>
+       <attribute name="org_unit" value="50000873"/>
+       <attribute name="building" value="RH"/>
+       <attribute name="room" value="415"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="NBDC Business &amp; Technology Solutions"/>
+        <attribute name="org_unit" value="50000874"/>
+        <attribute name="building" value="ESU"/>
+        <attribute name="room" value="3"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182-0164"/>
+       </branch>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Education"/>
+      <attribute name="org_unit" value="50000177"/>
+      <attribute name="building" value="KH"/>
+      <attribute name="room" value="334"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Educational Admin/Supervision"/>
+       <attribute name="org_unit" value="50000837"/>
+       <attribute name="building" value="KH"/>
+       <attribute name="room" value="414"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Teacher Education"/>
+       <attribute name="org_unit" value="50000838"/>
+       <attribute name="building" value="KH"/>
+       <attribute name="room" value="514"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Teacher Placement"/>
+        <attribute name="org_unit" value="50000917"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="111"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Counseling"/>
+       <attribute name="org_unit" value="50000839"/>
+       <attribute name="building" value="KH"/>
+       <attribute name="room" value="421"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Health Physical Educ &amp; Recreation"/>
+       <attribute name="org_unit" value="50000840"/>
+       <attribute name="building" value="HPER"/>
+       <attribute name="room" value="207"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Special Education Comm Disorders"/>
+       <attribute name="org_unit" value="50000841"/>
+       <attribute name="building" value="KH"/>
+       <attribute name="room" value="117"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Comm,  Fine Arts &amp; Media"/>
+      <attribute name="org_unit" value="50000178"/>
+      <attribute name="building" value="FA"/>
+      <attribute name="room" value="314"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68181"/>
+      <branch>
+       <attribute name="name" value="Communication"/>
+       <attribute name="org_unit" value="50000805"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="108"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Art and Art History"/>
+       <attribute name="org_unit" value="50000815"/>
+       <attribute name="building" value="FA"/>
+       <attribute name="room" value="315B"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Music"/>
+       <attribute name="org_unit" value="50000816"/>
+       <attribute name="building" value="PAC"/>
+       <attribute name="room" value="207"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Theatre"/>
+       <attribute name="org_unit" value="50000817"/>
+       <attribute name="building" value="FA"/>
+       <attribute name="room" value="315A"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Writer&#39;s Workshop"/>
+       <attribute name="org_unit" value="50000818"/>
+       <attribute name="building" value="FA"/>
+       <attribute name="room" value="315B"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Media"/>
+       <attribute name="org_unit" value="50000968"/>
+       <attribute name="building" value="ENGG"/>
+       <attribute name="room" value="200"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Radio"/>
+        <attribute name="org_unit" value="50000971"/>
+        <attribute name="building" value="ENGG"/>
+        <attribute name="room" value="200"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Television"/>
+        <attribute name="org_unit" value="50000972"/>
+        <attribute name="building" value="ENGG"/>
+        <attribute name="room" value="200"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Info Science and Tech"/>
+      <attribute name="org_unit" value="50000179"/>
+      <attribute name="building" value="PKI"/>
+      <attribute name="room" value="280"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="ISQA"/>
+       <attribute name="org_unit" value="50000825"/>
+       <attribute name="building" value="PKI"/>
+       <attribute name="room" value="270"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Computer Science"/>
+       <attribute name="org_unit" value="50001281"/>
+       <attribute name="building" value="PKI"/>
+       <attribute name="room" value="170"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="CMIT"/>
+       <attribute name="org_unit" value="50001457"/>
+       <attribute name="building" value="PKI"/>
+       <attribute name="room" value="280"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Info Tech/Info Systems eng"/>
+       <attribute name="org_unit" value="50001458"/>
+       <attribute name="building" value="PKI"/>
+       <attribute name="room" value="172"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="College of Public Affrs &amp; Comm Svcs"/>
+      <attribute name="org_unit" value="50000180"/>
+      <attribute name="building" value="CB"/>
+      <attribute name="room" value="109"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Division of Continuing Studies"/>
+       <attribute name="org_unit" value="50000181"/>
+       <attribute name="building" value="CB"/>
+       <attribute name="room" value="207"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Off Campus Programs"/>
+        <attribute name="org_unit" value="50000866"/>
+        <attribute name="building" value="CB"/>
+        <attribute name="room" value="207"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="DCS Degree Programs"/>
+        <attribute name="org_unit" value="50000869"/>
+        <attribute name="building" value="CB"/>
+        <attribute name="room" value="207"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="NonCredit Programs"/>
+        <attribute name="org_unit" value="50000870"/>
+        <attribute name="building" value="PKCC"/>
+        <attribute name="room" value="230"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Center for Public Affairs Research"/>
+       <attribute name="org_unit" value="50000792"/>
+       <attribute name="building" value="CB"/>
+       <attribute name="room" value="108"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="School of Criminology &amp; Crim Justice"/>
+       <attribute name="org_unit" value="50000793"/>
+       <attribute name="building" value="CB"/>
+       <attribute name="room" value="218"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Public Administration"/>
+       <attribute name="org_unit" value="50000794"/>
+       <attribute name="building" value="CB"/>
+       <attribute name="room" value="111"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Aviation Institute"/>
+        <attribute name="org_unit" value="50000799"/>
+        <attribute name="building" value="CB"/>
+        <attribute name="room" value="120"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Gerontology"/>
+       <attribute name="org_unit" value="50000795"/>
+       <attribute name="building" value="CB"/>
+       <attribute name="room" value="211"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Social Work"/>
+       <attribute name="org_unit" value="50000796"/>
+       <attribute name="building" value="CB"/>
+       <attribute name="room" value="206"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Goodrich"/>
+       <attribute name="org_unit" value="50000797"/>
+       <attribute name="building" value="CB"/>
+       <attribute name="room" value="123"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Labor Studies Institute"/>
+       <attribute name="org_unit" value="50000867"/>
+       <attribute name="building" value="PKCC"/>
+       <attribute name="room" value="233"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Graduate Studies"/>
+      <attribute name="org_unit" value="50000182"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="203"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Criss Library"/>
+      <attribute name="org_unit" value="50000183"/>
+      <attribute name="building" value="Criss Library"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Academic Affairs - Technology"/>
+      <attribute name="org_unit" value="50000949"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="005"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Information Technology Services"/>
+       <attribute name="org_unit" value="50000186"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="110"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Academic Computing"/>
+        <attribute name="org_unit" value="50000202"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="110"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+        <branch>
+         <attribute name="name" value="Client Services"/>
+         <attribute name="org_unit" value="50001513"/>
+         <attribute name="building" value="EAB"/>
+         <attribute name="room" value="110"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Academic Information Systems"/>
+         <attribute name="org_unit" value="50001514"/>
+         <attribute name="building" value="EAB"/>
+         <attribute name="room" value="110"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+        </branch>
+       </branch>
+       <branch>
+        <attribute name="name" value="Administrative Computing"/>
+        <attribute name="org_unit" value="50000203"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="110"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+        <branch>
+         <attribute name="name" value="Operations"/>
+         <attribute name="org_unit" value="50000204"/>
+         <attribute name="building" value="EAB"/>
+         <attribute name="room" value="110"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+        </branch>
+        <branch>
+         <attribute name="name" value="Applications Development"/>
+         <attribute name="org_unit" value="50001515"/>
+         <attribute name="building" value="EAB"/>
+         <attribute name="room" value="110"/>
+         <attribute name="city" value="Omaha"/>
+         <attribute name="state" value="NE"/>
+         <attribute name="postal_code" value="68182"/>
+        </branch>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Multimedia Technology Services"/>
+       <attribute name="org_unit" value="50000967"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="012"/>
+       <attribute name="city" value="omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Acad Partnerships for Instruction"/>
+       <attribute name="org_unit" value="50004950"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="008"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Information Tech Infrastructure"/>
+       <attribute name="org_unit" value="50004951"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="008"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Customer Services"/>
+        <attribute name="org_unit" value="50004952"/>
+        <attribute name="building" value="EAB"/>
+        <attribute name="room" value="008"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68182"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Administrative Information Services"/>
+       <attribute name="org_unit" value="50004953"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="008"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Project Management"/>
+       <attribute name="org_unit" value="50004954"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="008"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Academic Affairs - General"/>
+      <attribute name="org_unit" value="50000948"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="202"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Assessment Office"/>
+       <attribute name="org_unit" value="50000950"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="202"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Honors Program"/>
+       <attribute name="org_unit" value="50000951"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="105"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Air Science"/>
+       <attribute name="org_unit" value="50000952"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="260"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Institutional Research"/>
+       <attribute name="org_unit" value="50000953"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="202"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Faculty Development"/>
+       <attribute name="org_unit" value="50000969"/>
+       <attribute name="building" value="AH"/>
+       <attribute name="room" value="419"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+       <branch>
+        <attribute name="name" value="Center for Faculty Development"/>
+        <attribute name="org_unit" value="50000970"/>
+        <attribute name="building" value="ASH"/>
+        <attribute name="room" value="220"/>
+        <attribute name="city" value="Omaha"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68162"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Sponsored Programs &amp; Research"/>
+       <attribute name="org_unit" value="50000973"/>
+       <attribute name="building" value="EAB"/>
+       <attribute name="room" value="203"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Srvc Learning Acad &amp; Amer Humanics"/>
+       <attribute name="org_unit" value="50004350"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="220"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Center for Collaboration Sciences"/>
+       <attribute name="org_unit" value="50006275"/>
+       <attribute name="building" value="PKI"/>
+       <attribute name="room" value="356"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Engineering"/>
+      <attribute name="org_unit" value="50001275"/>
+      <attribute name="building" value="PKI"/>
+      <attribute name="room" value="100"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="International Studies and Programs"/>
+      <attribute name="org_unit" value="50001277"/>
+      <attribute name="building" value="ASH"/>
+      <attribute name="room" value="238"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Afghanistan"/>
+       <attribute name="org_unit" value="50001278"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="241"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="International Programs"/>
+       <attribute name="org_unit" value="50001279"/>
+       <attribute name="building" value="ASH"/>
+       <attribute name="room" value="241"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="International Studies"/>
+       <attribute name="org_unit" value="50001280"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Faculty Senate"/>
+      <attribute name="org_unit" value="50001677"/>
+      <attribute name="building" value="ASH"/>
+      <attribute name="room" value="105"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Intercollegiate Athletics"/>
+     <attribute name="org_unit" value="50000184"/>
+     <attribute name="building" value="FH"/>
+     <attribute name="room" value="109"/>
+     <attribute name="city" value="Omaha"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68182"/>
+     <branch>
+      <attribute name="name" value="Combined Services"/>
+      <attribute name="org_unit" value="50000974"/>
+      <attribute name="building" value="FH"/>
+      <attribute name="room" value="109"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Sports Information"/>
+       <attribute name="org_unit" value="50000984"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="NCAA Compliance"/>
+       <attribute name="org_unit" value="50000985"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Marketing"/>
+       <attribute name="org_unit" value="50000986"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Training Room"/>
+       <attribute name="org_unit" value="50000987"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Strength and Conditioning"/>
+       <attribute name="org_unit" value="50000988"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Equipment Room"/>
+       <attribute name="org_unit" value="50000989"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Business Office"/>
+       <attribute name="org_unit" value="50000990"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Men&#39;s Athletics"/>
+      <attribute name="org_unit" value="50000975"/>
+      <attribute name="building" value="FH"/>
+      <attribute name="room" value="109"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Men&#39;s Basketball"/>
+       <attribute name="org_unit" value="50000991"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Baseball"/>
+       <attribute name="org_unit" value="50000992"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Football"/>
+       <attribute name="org_unit" value="50000993"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Wrestling"/>
+       <attribute name="org_unit" value="50000994"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Hockey"/>
+       <attribute name="org_unit" value="50000995"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Women&#39;s Athletics"/>
+      <attribute name="org_unit" value="50000976"/>
+      <attribute name="building" value="FH"/>
+      <attribute name="room" value="109"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+      <branch>
+       <attribute name="name" value="Women&#39;s Basketball"/>
+       <attribute name="org_unit" value="50000996"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Softball"/>
+       <attribute name="org_unit" value="50000997"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Women&#39;s Cross Country/Track"/>
+       <attribute name="org_unit" value="50000998"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Volleyball"/>
+       <attribute name="org_unit" value="50000999"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Women&#39;s Swimming/Diving"/>
+       <attribute name="org_unit" value="50001000"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Women&#39;s Soccer"/>
+       <attribute name="org_unit" value="50001001"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Women&#39;s Tennis"/>
+       <attribute name="org_unit" value="50001480"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68182"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Women&#39;s Golf"/>
+       <attribute name="org_unit" value="50001481"/>
+       <attribute name="building" value="FH"/>
+       <attribute name="room" value="109"/>
+       <attribute name="city" value="Omaha"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68162"/>
+      </branch>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Alumni Association"/>
+     <attribute name="org_unit" value="50000185"/>
+     <attribute name="building" value="Alumni Center"/>
+     <attribute name="city" value="Omaha"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68182"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="University Relations"/>
+     <attribute name="org_unit" value="50001451"/>
+     <attribute name="building" value="EAB"/>
+     <attribute name="room" value="108"/>
+     <attribute name="city" value="Omaha"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68182"/>
+     <branch>
+      <attribute name="name" value="Communications and Media"/>
+      <attribute name="org_unit" value="50001452"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="108"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Photography"/>
+      <attribute name="org_unit" value="50001456"/>
+      <attribute name="building" value="EAB"/>
+      <attribute name="room" value="108"/>
+      <attribute name="city" value="Omaha"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68182"/>
+     </branch>
+    </branch>
+   </branch>
+  </branch>
+  <branch>
+   <attribute name="name" value="University of Nebraska at Kearney"/>
+   <attribute name="org_unit" value="50000006"/>
+   <branch>
+    <attribute name="name" value="Office of the Chancellor"/>
+    <attribute name="org_unit" value="50000104"/>
+    <attribute name="building" value="FNDH"/>
+    <attribute name="room" value="1000"/>
+    <attribute name="city" value="Kearney"/>
+    <attribute name="state" value="NE"/>
+    <attribute name="postal_code" value="68849"/>
+    <branch>
+     <attribute name="name" value="Academic Affairs"/>
+     <attribute name="org_unit" value="50000105"/>
+     <attribute name="building" value="FNDH"/>
+     <attribute name="room" value="1000"/>
+     <attribute name="city" value="Kearney"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68849"/>
+     <branch>
+      <attribute name="name" value="Student Life Division"/>
+      <attribute name="org_unit" value="50000106"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="1000"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="Academic Success"/>
+       <attribute name="org_unit" value="50002775"/>
+       <attribute name="building" value="MSAB"/>
+       <attribute name="room" value="163"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+       <branch>
+        <attribute name="name" value="Learning Strategies"/>
+        <attribute name="org_unit" value="50000578"/>
+        <attribute name="building" value="MSAB"/>
+        <attribute name="room" value="163"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Student Support Services"/>
+        <attribute name="org_unit" value="50000626"/>
+        <attribute name="building" value="MSAB"/>
+        <attribute name="room" value="173"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Writing Center"/>
+        <attribute name="org_unit" value="50001504"/>
+        <attribute name="building" value="LIBR"/>
+        <attribute name="room" value="208"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Career Services"/>
+       <attribute name="org_unit" value="50000618"/>
+       <attribute name="building" value="MSAB"/>
+       <attribute name="room" value="140"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Counseling and Health Care"/>
+       <attribute name="org_unit" value="50004400"/>
+       <attribute name="building" value="MSAB"/>
+       <attribute name="room" value="184"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+       <branch>
+        <attribute name="name" value="Counseling"/>
+        <attribute name="org_unit" value="50000619"/>
+        <attribute name="building" value="MSAB"/>
+        <attribute name="room" value="144"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Health Care"/>
+        <attribute name="org_unit" value="50000623"/>
+        <attribute name="building" value="MSAB"/>
+        <attribute name="room" value="184"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Residential and Greek Life"/>
+       <attribute name="org_unit" value="50000621"/>
+       <attribute name="building" value="CONH"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Student Center/Union"/>
+       <attribute name="org_unit" value="50000622"/>
+       <attribute name="building" value="NSU"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Multi-Cultural"/>
+       <attribute name="org_unit" value="50000625"/>
+       <attribute name="building" value="NSU"/>
+       <attribute name="room" value="116"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Fine Arts &amp; Humanities"/>
+      <attribute name="org_unit" value="50000501"/>
+      <attribute name="building" value="FAB"/>
+      <attribute name="room" value="300"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="Museum of Nebraska Art"/>
+       <attribute name="org_unit" value="50000478"/>
+       <attribute name="building" value="MONA"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Art &amp; Art History"/>
+       <attribute name="org_unit" value="50000606"/>
+       <attribute name="building" value="FAB"/>
+       <attribute name="room" value="301"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="English"/>
+       <attribute name="org_unit" value="50000607"/>
+       <attribute name="building" value="THMH"/>
+       <attribute name="room" value="202"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Communication"/>
+       <attribute name="org_unit" value="50000608"/>
+       <attribute name="building" value="LIBR"/>
+       <attribute name="room" value="MC 149"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+       <branch>
+        <attribute name="name" value="University Newspaper"/>
+        <attribute name="org_unit" value="50001503"/>
+        <attribute name="building" value="LIBR"/>
+        <attribute name="room" value="MC 149"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Modern Languages"/>
+       <attribute name="org_unit" value="50000609"/>
+       <attribute name="building" value="THMH"/>
+       <attribute name="room" value="215"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Music &amp; Performing Arts"/>
+       <attribute name="org_unit" value="50000610"/>
+       <attribute name="building" value="FAB"/>
+       <attribute name="room" value="221"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+       <branch>
+        <attribute name="name" value="Theatre"/>
+        <attribute name="org_unit" value="50001163"/>
+        <attribute name="building" value="FAB"/>
+        <attribute name="room" value="221"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Philosophy"/>
+       <attribute name="org_unit" value="50000611"/>
+       <attribute name="building" value="THMH"/>
+       <attribute name="room" value="215"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Information Technology Services"/>
+      <attribute name="org_unit" value="50000481"/>
+      <attribute name="building" value="OTOL"/>
+      <attribute name="room" value="114"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Natural &amp; Social Sciences"/>
+      <attribute name="org_unit" value="50000498"/>
+      <attribute name="building" value="COPH"/>
+      <attribute name="room" value="101A"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="Biology"/>
+       <attribute name="org_unit" value="50000545"/>
+       <attribute name="building" value="BHS"/>
+       <attribute name="room" value="300"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Chemistry"/>
+       <attribute name="org_unit" value="50000546"/>
+       <attribute name="building" value="BHS"/>
+       <attribute name="room" value="400"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Computer Science &amp; Information Syst"/>
+       <attribute name="org_unit" value="50000547"/>
+       <attribute name="building" value="OTOL"/>
+       <attribute name="room" value="116"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68449"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Health Science Programs"/>
+       <attribute name="org_unit" value="50000550"/>
+       <attribute name="building" value="BHS"/>
+       <attribute name="room" value="170"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="History"/>
+       <attribute name="org_unit" value="50000551"/>
+       <attribute name="building" value="COPH"/>
+       <attribute name="room" value="103N"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Mathematics &amp; Statistics"/>
+       <attribute name="org_unit" value="50000552"/>
+       <attribute name="building" value="FNDH"/>
+       <attribute name="room" value="2006"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Physics &amp; Physical Science"/>
+       <attribute name="org_unit" value="50000553"/>
+       <attribute name="building" value="BHS"/>
+       <attribute name="room" value="224"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Political Science"/>
+       <attribute name="org_unit" value="50000554"/>
+       <attribute name="building" value="FNDH"/>
+       <attribute name="room" value="2200"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Psychology"/>
+       <attribute name="org_unit" value="50000555"/>
+       <attribute name="building" value="COPH"/>
+       <attribute name="room" value="320K"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Criminal Justice &amp; Social Work"/>
+       <attribute name="org_unit" value="50003201"/>
+       <attribute name="building" value="FNDH"/>
+       <attribute name="room" value="2200"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Sociology Geography &amp; Earth Sciences"/>
+       <attribute name="org_unit" value="50003202"/>
+       <attribute name="building" value="COPH"/>
+       <attribute name="room" value="120"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Business &amp; Technology"/>
+      <attribute name="org_unit" value="50000499"/>
+      <attribute name="building" value="WSTC"/>
+      <attribute name="room" value="140C"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="Accounting/Finance"/>
+       <attribute name="org_unit" value="50000566"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="300C"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Marketing &amp; MIS"/>
+       <attribute name="org_unit" value="50000567"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="400C"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Economics"/>
+       <attribute name="org_unit" value="50000568"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="108"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Family Studies and Interior Design"/>
+       <attribute name="org_unit" value="50000569"/>
+       <attribute name="building" value="OTOL"/>
+       <attribute name="room" value="206"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Industrial Technology"/>
+       <attribute name="org_unit" value="50000570"/>
+       <attribute name="building" value="OTOL"/>
+       <attribute name="room" value="134"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Management"/>
+       <attribute name="org_unit" value="50000571"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="400C"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nebraska Safety Center"/>
+       <attribute name="org_unit" value="50000572"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="E200"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Nebraska Business &amp; Development CNTR"/>
+       <attribute name="org_unit" value="50000573"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="135C"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Center for Rural Rsch Development"/>
+       <attribute name="org_unit" value="50001166"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="133C"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="MBA Program"/>
+       <attribute name="org_unit" value="50001500"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="135C"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="WC Computer Lab"/>
+       <attribute name="org_unit" value="50001501"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="254W"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Military Science"/>
+       <attribute name="org_unit" value="50005725"/>
+       <attribute name="building" value="WSTC"/>
+       <attribute name="room" value="211N"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Education"/>
+      <attribute name="org_unit" value="50000500"/>
+      <attribute name="building" value="COE"/>
+      <attribute name="room" value="C114"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="Counseling &amp; School Psychology"/>
+       <attribute name="org_unit" value="50000574"/>
+       <attribute name="building" value="COE"/>
+       <attribute name="room" value="B144"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Educational Administration"/>
+       <attribute name="org_unit" value="50000575"/>
+       <attribute name="building" value="COE"/>
+       <attribute name="room" value="B115"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Health, Physical Ed &amp; Recreation"/>
+       <attribute name="org_unit" value="50000577"/>
+       <attribute name="building" value="CUSH"/>
+       <attribute name="room" value="129"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+       <branch>
+        <attribute name="name" value="Intramurals"/>
+        <attribute name="org_unit" value="50000615"/>
+        <attribute name="building" value="CUSH"/>
+        <attribute name="room" value="119"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Teacher Education"/>
+       <attribute name="org_unit" value="50000579"/>
+       <attribute name="building" value="COE"/>
+       <attribute name="room" value="B117"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Communication Disorders"/>
+       <attribute name="org_unit" value="50001164"/>
+       <attribute name="building" value="COE"/>
+       <attribute name="room" value="A103"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="KASE"/>
+       <attribute name="org_unit" value="50001167"/>
+       <attribute name="building" value="COE"/>
+       <attribute name="room" value="C128"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="COE-CIT"/>
+       <attribute name="org_unit" value="50001502"/>
+       <attribute name="building" value="COE"/>
+       <attribute name="room" value="C106"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Graduate Studies &amp; Research"/>
+      <attribute name="org_unit" value="50000503"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="2116"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="eCampus"/>
+       <attribute name="org_unit" value="50000502"/>
+       <attribute name="building" value="CMCT"/>
+       <attribute name="room" value="308"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+       <branch>
+        <attribute name="name" value="Video Services"/>
+        <attribute name="org_unit" value="50000517"/>
+        <attribute name="building" value="CMCT"/>
+        <attribute name="room" value="216"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+       <branch>
+        <attribute name="name" value="Elderhostel"/>
+        <attribute name="org_unit" value="50001160"/>
+        <attribute name="building" value="CMCT"/>
+        <attribute name="room" value="305"/>
+        <attribute name="city" value="Kearney"/>
+        <attribute name="state" value="NE"/>
+        <attribute name="postal_code" value="68849"/>
+       </branch>
+      </branch>
+      <branch>
+       <attribute name="name" value="Sponsored Programs"/>
+       <attribute name="org_unit" value="50000524"/>
+       <attribute name="building" value="FNDH"/>
+       <attribute name="room" value="2134"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Research Service Center"/>
+       <attribute name="org_unit" value="50001505"/>
+       <attribute name="building" value="FNDH"/>
+       <attribute name="room" value="2116"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Library"/>
+      <attribute name="org_unit" value="50000504"/>
+      <attribute name="building" value="LIBR"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Institutional Research"/>
+      <attribute name="org_unit" value="50000505"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="2108"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="International Education"/>
+      <attribute name="org_unit" value="50000506"/>
+      <attribute name="building" value="OCKC"/>
+      <attribute name="room" value="100"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="World Affairs"/>
+       <attribute name="org_unit" value="50000534"/>
+       <attribute name="building" value="OCKC"/>
+       <attribute name="room" value="100"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="International Student Services"/>
+       <attribute name="org_unit" value="50001830"/>
+       <attribute name="building" value="WLCH"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Honors Program"/>
+      <attribute name="org_unit" value="50000530"/>
+      <attribute name="building" value="MSAB"/>
+      <attribute name="room" value="112"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="General Studies"/>
+      <attribute name="org_unit" value="50000531"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="2113"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Academic Advising"/>
+      <attribute name="org_unit" value="50000616"/>
+      <attribute name="building" value="MSAB"/>
+      <attribute name="room" value="180"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Admissions"/>
+      <attribute name="org_unit" value="50000617"/>
+      <attribute name="building" value="MSAB"/>
+      <attribute name="room" value="112"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="Summer Advising Enrollment"/>
+       <attribute name="org_unit" value="50000650"/>
+       <attribute name="building" value="MSAB"/>
+       <attribute name="room" value="112"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Financial Aid"/>
+      <attribute name="org_unit" value="50000620"/>
+      <attribute name="building" value="MSAB"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Student Records"/>
+      <attribute name="org_unit" value="50000624"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Women&#39;s Studies"/>
+      <attribute name="org_unit" value="50001506"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="2113"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Center for Teaching Excellence"/>
+      <attribute name="org_unit" value="50001700"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="2113"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Ethnic Studies"/>
+      <attribute name="org_unit" value="50005226"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="2152"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="1st Year Program"/>
+      <attribute name="org_unit" value="50005227"/>
+      <attribute name="building" value="THMH"/>
+      <attribute name="room" value="109B"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Assessment Office"/>
+      <attribute name="org_unit" value="50005228"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="2113"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Business and Finance"/>
+     <attribute name="org_unit" value="50000107"/>
+     <attribute name="building" value="FNDH"/>
+     <attribute name="room" value="1000"/>
+     <attribute name="city" value="Kearney"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68849"/>
+     <branch>
+      <attribute name="name" value="Finance Office"/>
+      <attribute name="org_unit" value="50000490"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Business Services"/>
+      <attribute name="org_unit" value="50000491"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="119"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Human Resources"/>
+      <attribute name="org_unit" value="50000492"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="1200"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="Retirees"/>
+       <attribute name="org_unit" value="50001354"/>
+       <attribute name="building" value="FNDH"/>
+       <attribute name="room" value="1200"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Health/Wellness Program"/>
+       <attribute name="org_unit" value="50001508"/>
+       <attribute name="building" value="FNDH"/>
+       <attribute name="room" value="1200"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Volunteers"/>
+       <attribute name="org_unit" value="50001512"/>
+       <attribute name="building" value="FNDH"/>
+       <attribute name="room" value="1200"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+      <branch>
+       <attribute name="name" value="Child Development Center"/>
+       <attribute name="org_unit" value="50002350"/>
+       <attribute name="building" value="OTOL"/>
+       <attribute name="room" value="101"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Police and Parking Services"/>
+      <attribute name="org_unit" value="50000493"/>
+      <attribute name="building" value="GSB"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Budget Office"/>
+      <attribute name="org_unit" value="50000494"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="1203"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68449"/>
+      <branch>
+       <attribute name="name" value="Budget Adjustments"/>
+       <attribute name="org_unit" value="50002025"/>
+       <attribute name="building" value="FNDH"/>
+       <attribute name="room" value="2138"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Facilities Mgt &amp; Planning"/>
+      <attribute name="org_unit" value="50000495"/>
+      <attribute name="building" value="GSB"/>
+      <attribute name="room" value="101"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+      <branch>
+       <attribute name="name" value="Facilities-Rev Bond Operations"/>
+       <attribute name="org_unit" value="50002756"/>
+       <attribute name="building" value="GSB"/>
+       <attribute name="room" value="101"/>
+       <attribute name="city" value="Kearney"/>
+       <attribute name="state" value="NE"/>
+       <attribute name="postal_code" value="68849"/>
+      </branch>
+     </branch>
+     <branch>
+      <attribute name="name" value="Antelope Bookstore"/>
+      <attribute name="org_unit" value="50006652"/>
+      <attribute name="building" value="NSU"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Unassigned Pos #"/>
+      <attribute name="org_unit" value="50006801"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="2138"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="University Relations"/>
+     <attribute name="org_unit" value="50000108"/>
+     <attribute name="building" value="FNDH"/>
+     <attribute name="room" value="1000"/>
+     <attribute name="city" value="Kearney"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68849"/>
+     <branch>
+      <attribute name="name" value="Frank House"/>
+      <attribute name="org_unit" value="50001159"/>
+      <attribute name="building" value="FNDH"/>
+      <attribute name="room" value="1000"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Advertising &amp; Creative Serv"/>
+      <attribute name="org_unit" value="50002375"/>
+      <attribute name="building" value="CMCT"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+     <branch>
+      <attribute name="name" value="Media Communications"/>
+      <attribute name="org_unit" value="50006800"/>
+      <attribute name="building" value="CMCT"/>
+      <attribute name="room" value="304"/>
+      <attribute name="city" value="Kearney"/>
+      <attribute name="state" value="NE"/>
+      <attribute name="postal_code" value="68849"/>
+     </branch>
+    </branch>
+    <branch>
+     <attribute name="name" value="Intercollegiate Athletics"/>
+     <attribute name="org_unit" value="50000477"/>
+     <attribute name="building" value="HSC"/>
+     <attribute name="room" value="102"/>
+     <attribute name="city" value="Kearney"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68849"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="Alumni Association"/>
+     <attribute name="org_unit" value="50000479"/>
+     <attribute name="building" value="ALUM"/>
+     <attribute name="city" value="Kearney"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68849"/>
+    </branch>
+    <branch>
+     <attribute name="name" value="EO/Affirmative Action"/>
+     <attribute name="org_unit" value="50000480"/>
+     <attribute name="building" value="FNDH"/>
+     <attribute name="room" value="1203"/>
+     <attribute name="city" value="Kearney"/>
+     <attribute name="state" value="NE"/>
+     <attribute name="postal_code" value="68849"/>
+    </branch>
+   </branch>
+  </branch>
+ </branch>
+</branch>
+<branch>
+ <attribute name="name" value="Enrollment Mgmt &amp; Student Affrs      PSC"/>
+ <attribute name="org_unit" value="50006625"/>
+</branch>
+</tree>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version2/Document.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version2/Document.tpl
new file mode 100644
index 00000000..caccfd68
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version2/Document.tpl
@@ -0,0 +1,111 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" ><!-- InstanceBegin template="/Templates/document.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Document Template</title>
+<!-- InstanceEndEditable -->
+<!-- Codebase:UNLFramework 20070105 -->
+<link rel="stylesheet" type="text/css" media="screen" href="/ucomm/templatedependents/templatecss/layouts/main.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/ucomm/templatedependents/templatecss/layouts/print.css"/>
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/all_compressed.js"></script>
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/ie.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/comments/developersnote.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/metanfavico/metanfavico.html" -->
+
+<!-- InstanceBeginEditable name="head" -->
+<script type="text/javascript">
+var navl2Links = 0; //Default navline2 links to display (zero based counting)
+</script>
+<!-- InstanceEndEditable -->
+
+</head>
+<body id="doc">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/siteheader/siteheader.shtml" -->
+
+<div id="red-header">
+	<div class="clear">
+		<h1>University of Nebraska&ndash;Lincoln</h1>
+		<div id="breadcrumbs"> 
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+<!-- InstanceEndEditable -->
+ </div>
+	</div>
+</div>
+<!-- close red-header -->
+
+<div id="container">
+	<div class="clear">
+		<div id="title"> 
+<!-- InstanceBeginEditable name="collegenavigationlist" -->
+ 
+<!-- InstanceEndEditable -->
+			<div id="titlegraphic">
+				<!-- WDN: see glossary item 'title graphics' -->
+				
+<!-- InstanceBeginEditable name="titlegraphic" -->
+				<h1>Department</h1>
+				<h2>Taglines - We Do The Heavy Lifting</h2>
+				
+<!-- InstanceEndEditable -->
+</div>
+			<!-- maintitle -->
+		</div>
+		<!-- close title -->
+		
+		<div id="navigation">
+			<h4 id="sec_nav">Navigation</h4>
+			
+
+			<div id="nav_end"></div>
+			
+			<!-- WDN: see glossary item 'sidebar links' -->
+			<div id="leftcollinks"> 
+				<!-- WDN: see glossary item 'sidebar links' -->
+				
+ </div>
+		</div>
+		<!-- close navigation -->
+		
+		<div id="main_right" class="mainwrapper">
+			<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+			
+			<div id="maincontent"> 
+
+				<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/noscript.html" -->
+				<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+				
+<!-- InstanceBeginEditable name="maincontentarea" -->
+				<p style="margin:20px; border:3px solid #CC0000;padding:10px; text-align:center"> <strong>Delete this box and place your content here.</strong><br />
+					Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://www.unl.edu/webdevnet/">Web Developer Network</a>. <br />
+					<a href="http://validator.unl.edu/check/referer">Click here to check Validation</a> </p>
+				
+<!-- InstanceEndEditable -->
+				<!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+				
+ </div>
+			 </div>
+		<!-- close main right -->
+	</div>
+</div>
+<!-- close container -->
+<div id="footer">
+	<div id="footer_floater"> 
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+		<div id="copyright"> 
+<!-- InstanceBeginEditable name="footercontent" -->
+			<!--#include virtual="../sharedcode/footer.html" -->
+			
+<!-- InstanceEndEditable -->
+ <span><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> <a href="http://validator.unl.edu/check/referer">W3C</a> <a href="http://www1.unl.edu/feeds/">RSS</a> </span><a href="http://www.unl.edu/" title="UNL Home"><img src="/ucomm/templatedependents/templatecss/images/wordmark.png" alt="UNL's wordmark" id="wordmark" /></a></div>
+	</div>
+</div>
+<!-- close footer -->
+<!-- sifr -->
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/sifr_replacements.js"></script>
+</body>
+<!-- InstanceEnd --></html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version2/Fixed.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version2/Fixed.tpl
new file mode 100644
index 00000000..44626d93
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version2/Fixed.tpl
@@ -0,0 +1,137 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" ><!-- InstanceBegin template="/Templates/fixed.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- Codebase:UNLFramework 20070105 -->
+<link rel="stylesheet" type="text/css" media="screen" href="/ucomm/templatedependents/templatecss/layouts/main.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/ucomm/templatedependents/templatecss/layouts/print.css"/>
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/all_compressed.js"></script>
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/ie.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/comments/developersnote.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/metanfavico/metanfavico.html" -->
+
+<!-- InstanceBeginEditable name="head" -->
+<script type="text/javascript">
+var navl2Links = 0; //Default navline2 links to display (zero based counting)
+</script>
+<!-- InstanceEndEditable -->
+
+</head>
+<body id="fixed">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/siteheader/siteheader.shtml" -->
+
+<div id="red-header">
+	<div class="clear">
+		<h1>University of Nebraska&ndash;Lincoln</h1>
+		<div id="breadcrumbs"> 
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+			<!-- WDN: see glossary item 'breadcrumbs' -->
+			<ul>
+				<li class="first"><a href="http://www.unl.edu/">UNL</a></li>
+				<li><a href="http://www.unl.edu/">Department</a></li>
+				<li>New Page</li>
+			</ul>
+			
+<!-- InstanceEndEditable -->
+ </div>
+	</div>
+</div>
+<!-- close red-header -->
+
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/shelf/shelf.shtml" -->
+
+<div id="container">
+	<div class="clear">
+		<div id="title"> 
+<!-- InstanceBeginEditable name="collegenavigationlist" -->
+ 
+<!-- InstanceEndEditable -->
+			<div id="titlegraphic">
+				<!-- WDN: see glossary item 'title graphics' -->
+				
+<!-- InstanceBeginEditable name="titlegraphic" -->
+				<h1>Department</h1>
+				<h2>Taglines - We Do The Heavy Lifting</h2>
+				
+<!-- InstanceEndEditable -->
+</div>
+			<!-- maintitle -->
+		</div>
+		<!-- close title -->
+		
+		<div id="navigation">
+			<h4 id="sec_nav">Navigation</h4>
+			
+
+			<div id="navlinks"> 
+<!-- InstanceBeginEditable name="navlinks" -->
+				<!--#include virtual="../sharedcode/navigation.html" -->
+				
+<!-- InstanceEndEditable -->
+</div>
+			
+
+			<div id="nav_end"></div>
+			
+<!-- InstanceBeginEditable name="leftRandomPromo" -->
+			<div class="image_small_short" id="leftRandomPromo"> <a href="#" id="leftRandomPromoAnchor"><img id="leftRandomPromoImage" alt="" src="/ucomm/templatedependents/templatecss/images/transpixel.gif" /></a>
+				<script type="text/javascript" src="../sharedcode/leftRandomPromo.js"></script>
+			</div>
+			
+<!-- InstanceEndEditable -->
+			<!-- WDN: see glossary item 'sidebar links' -->
+			<div id="leftcollinks"> 
+<!-- InstanceBeginEditable name="leftcollinks" -->
+				<!-- WDN: see glossary item 'sidebar links' -->
+				<!--#include virtual="../sharedcode/relatedLinks.html" -->
+				
+<!-- InstanceEndEditable -->
+ </div>
+		</div>
+		<!-- close navigation -->
+		
+		<div id="main_right" class="mainwrapper">
+			<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+			
+			<div id="maincontent"> 
+
+				<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/noscript.html" -->
+				<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+				
+<!-- InstanceBeginEditable name="maincontentarea" -->
+				<p style="margin:20px; border:3px solid #CC0000;padding:10px; text-align:center"> <strong>Delete this box and place your content here.</strong><br />
+					Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://www.unl.edu/webdevnet/">Web Developer Network</a>. <br />
+					<a href="http://validator.unl.edu/check/referer">Click here to check Validation</a> </p>
+				
+<!-- InstanceEndEditable -->
+				<!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+				
+ </div>
+			 </div>
+		<!-- close main right -->
+	</div>
+</div>
+<!-- close container -->
+<div id="footer">
+	<div id="footer_floater"> 
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+		<div id="copyright"> 
+<!-- InstanceBeginEditable name="footercontent" -->
+			<!--#include virtual="../sharedcode/footer.html" -->
+			
+<!-- InstanceEndEditable -->
+ <span><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> <a href="http://validator.unl.edu/check/referer">W3C</a> <a href="http://www1.unl.edu/feeds/">RSS</a> </span><a href="http://www.unl.edu/" title="UNL Home"><img src="/ucomm/templatedependents/templatecss/images/wordmark.png" alt="UNL's wordmark" id="wordmark" /></a></div>
+	</div>
+</div>
+<!-- close footer -->
+<!-- sifr -->
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/sifr_replacements.js"></script>
+</body>
+<!-- InstanceEnd --></html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version2/Liquid.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version2/Liquid.tpl
new file mode 100644
index 00000000..bcbe8718
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version2/Liquid.tpl
@@ -0,0 +1,137 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" ><!-- InstanceBegin template="/Templates/liquid.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- Codebase:UNLFramework 20070105 -->
+<link rel="stylesheet" type="text/css" media="screen" href="/ucomm/templatedependents/templatecss/layouts/main.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/ucomm/templatedependents/templatecss/layouts/print.css"/>
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/all_compressed.js"></script>
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/ie.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/comments/developersnote.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/metanfavico/metanfavico.html" -->
+
+<!-- InstanceBeginEditable name="head" -->
+<script type="text/javascript">
+var navl2Links = 0; //Default navline2 links to display (zero based counting)
+</script>
+<!-- InstanceEndEditable -->
+
+</head>
+<body id="liquid">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/siteheader/siteheader.shtml" -->
+
+<div id="red-header">
+	<div class="clear">
+		<h1>University of Nebraska&ndash;Lincoln</h1>
+		<div id="breadcrumbs"> 
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+			<!-- WDN: see glossary item 'breadcrumbs' -->
+			<ul>
+				<li class="first"><a href="http://www.unl.edu/">UNL</a></li>
+				<li><a href="http://www.unl.edu/">Department</a></li>
+				<li>New Page</li>
+			</ul>
+			
+<!-- InstanceEndEditable -->
+ </div>
+	</div>
+</div>
+<!-- close red-header -->
+
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/shelf/shelf.shtml" -->
+
+<div id="container">
+	<div class="clear">
+		<div id="title"> 
+<!-- InstanceBeginEditable name="collegenavigationlist" -->
+ 
+<!-- InstanceEndEditable -->
+			<div id="titlegraphic">
+				<!-- WDN: see glossary item 'title graphics' -->
+				
+<!-- InstanceBeginEditable name="titlegraphic" -->
+				<h1>Department</h1>
+				<h2>Taglines - We Do The Heavy Lifting</h2>
+				
+<!-- InstanceEndEditable -->
+</div>
+			<!-- maintitle -->
+		</div>
+		<!-- close title -->
+		
+		<div id="navigation">
+			<h4 id="sec_nav">Navigation</h4>
+			
+
+			<div id="navlinks"> 
+<!-- InstanceBeginEditable name="navlinks" -->
+				<!--#include virtual="../sharedcode/navigation.html" -->
+				
+<!-- InstanceEndEditable -->
+</div>
+			
+
+			<div id="nav_end"></div>
+			
+<!-- InstanceBeginEditable name="leftRandomPromo" -->
+			<div class="image_small_short" id="leftRandomPromo"> <a href="#" id="leftRandomPromoAnchor"><img id="leftRandomPromoImage" alt="" src="/ucomm/templatedependents/templatecss/images/transpixel.gif" /></a>
+				<script type="text/javascript" src="../sharedcode/leftRandomPromo.js"></script>
+			</div>
+			
+<!-- InstanceEndEditable -->
+			<!-- WDN: see glossary item 'sidebar links' -->
+			<div id="leftcollinks"> 
+<!-- InstanceBeginEditable name="leftcollinks" -->
+				<!-- WDN: see glossary item 'sidebar links' -->
+				<!--#include virtual="../sharedcode/relatedLinks.html" -->
+				
+<!-- InstanceEndEditable -->
+ </div>
+		</div>
+		<!-- close navigation -->
+		
+		<div id="main_right" class="mainwrapper">
+			<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+			
+			<div id="maincontent"> 
+
+				<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/noscript.html" -->
+				<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+				
+<!-- InstanceBeginEditable name="maincontentarea" -->
+				<p style="margin:20px; border:3px solid #CC0000;padding:10px; text-align:center"> <strong>Delete this box and place your content here.</strong><br />
+					Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://www.unl.edu/webdevnet/">Web Developer Network</a>. <br />
+					<a href="http://validator.unl.edu/check/referer">Click here to check Validation</a> </p>
+				
+<!-- InstanceEndEditable -->
+				<!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+				
+ </div>
+			 </div>
+		<!-- close main right -->
+	</div>
+</div>
+<!-- close container -->
+<div id="footer">
+	<div id="footer_floater"> 
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+		<div id="copyright"> 
+<!-- InstanceBeginEditable name="footercontent" -->
+			<!--#include virtual="../sharedcode/footer.html" -->
+			
+<!-- InstanceEndEditable -->
+ <span><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> <a href="http://validator.unl.edu/check/referer">W3C</a> <a href="http://www1.unl.edu/feeds/">RSS</a> </span><a href="http://www.unl.edu/" title="UNL Home"><img src="/ucomm/templatedependents/templatecss/images/wordmark.png" alt="UNL's wordmark" id="wordmark" /></a></div>
+	</div>
+</div>
+<!-- close footer -->
+<!-- sifr -->
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/sifr_replacements.js"></script>
+</body>
+<!-- InstanceEnd --></html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version2/Popup.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version2/Popup.tpl
new file mode 100644
index 00000000..cc3bcb33
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version2/Popup.tpl
@@ -0,0 +1,109 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" ><!-- InstanceBegin template="/Templates/popup.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- Codebase:UNLFramework 20070105 -->
+<link rel="stylesheet" type="text/css" media="screen" href="/ucomm/templatedependents/templatecss/layouts/main.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/ucomm/templatedependents/templatecss/layouts/print.css"/>
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/all_compressed.js"></script>
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/ie.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/comments/developersnote.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/metanfavico/metanfavico.html" -->
+
+<!-- InstanceBeginEditable name="head" -->
+<script type="text/javascript">
+var navl2Links = 0; //Default navline2 links to display (zero based counting)
+</script>
+<!-- InstanceEndEditable -->
+
+</head>
+<body id="popup">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/siteheader/siteheader.shtml" -->
+
+<div id="red-header">
+	<div class="clear">
+		<h1>University of Nebraska&ndash;Lincoln</h1>
+		<div id="breadcrumbs"> 
+
+ </div>
+	</div>
+</div>
+<!-- close red-header -->
+
+<div id="container">
+	<div class="clear">
+		<div id="title"> 
+<!-- InstanceBeginEditable name="collegenavigationlist" -->
+ 
+<!-- InstanceEndEditable -->
+			<div id="titlegraphic">
+				<!-- WDN: see glossary item 'title graphics' -->
+				
+<!-- InstanceBeginEditable name="titlegraphic" -->
+				<h1>Department</h1>
+				<h2>Taglines - We Do The Heavy Lifting</h2>
+				
+<!-- InstanceEndEditable -->
+</div>
+			<!-- maintitle -->
+		</div>
+		<!-- close title -->
+		
+		<div id="navigation">
+			<h4 id="sec_nav">Navigation</h4>
+			
+
+			<div id="nav_end"></div>
+			
+			<!-- WDN: see glossary item 'sidebar links' -->
+			<div id="leftcollinks"> 
+
+ </div>
+		</div>
+		<!-- close navigation -->
+		
+		<div id="main_right" class="mainwrapper">
+			<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+			
+			<div id="maincontent"> 
+
+				<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/noscript.html" -->
+				<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+				
+<!-- InstanceBeginEditable name="maincontentarea" -->
+				<p style="margin:20px; border:3px solid #CC0000;padding:10px; text-align:center"> <strong>Delete this box and place your content here.</strong><br />
+					Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://www.unl.edu/webdevnet/">Web Developer Network</a>. <br />
+					<a href="http://validator.unl.edu/check/referer">Click here to check Validation</a> </p>
+				
+<!-- InstanceEndEditable -->
+				<!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+				
+ </div>
+			 </div>
+		<!-- close main right -->
+	</div>
+</div>
+<!-- close container -->
+<div id="footer">
+	<div id="footer_floater"> 
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+		<div id="copyright"> 
+<!-- InstanceBeginEditable name="footercontent" -->
+			<!--#include virtual="../sharedcode/footer.html" -->
+			
+<!-- InstanceEndEditable -->
+ <span><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> <a href="http://validator.unl.edu/check/referer">W3C</a> <a href="http://www1.unl.edu/feeds/">RSS</a> </span><a href="http://www.unl.edu/" title="UNL Home"><img src="/ucomm/templatedependents/templatecss/images/wordmark.png" alt="UNL's wordmark" id="wordmark" /></a></div>
+	</div>
+</div>
+<!-- close footer -->
+<!-- sifr -->
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/sifr_replacements.js"></script>
+</body>
+<!-- InstanceEnd --></html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version2/Secure.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version2/Secure.tpl
new file mode 100644
index 00000000..53bb949f
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version2/Secure.tpl
@@ -0,0 +1,131 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" ><!-- InstanceBegin template="/Templates/secure.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- Codebase:UNLFramework 20070105 -->
+<link rel="stylesheet" type="text/css" media="screen" href="/ucomm/templatedependents/templatecss/layouts/main.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/ucomm/templatedependents/templatecss/layouts/print.css"/>
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/all_compressed.js"></script>
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/ie.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/comments/developersnote.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/metanfavico/metanfavico.html" -->
+
+<link rel="stylesheet" type="text/css" media="screen" href="/ucomm/templatedependents/templatecss/layouts/secure.css"/>
+<!-- InstanceBeginEditable name="head" -->
+<script type="text/javascript">
+var navl2Links = 0; //Default navline2 links to display (zero based counting)
+</script>
+<!-- InstanceEndEditable -->
+
+</head>
+<body id="secure">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/siteheader/siteheader_secure.shtml" -->
+
+<div id="red-header">
+	<div class="clear">
+		<h1>University of Nebraska&ndash;Lincoln</h1>
+		<div id="breadcrumbs"> 
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+			<!-- WDN: see glossary item 'breadcrumbs' -->
+			<ul>
+				<li class="first"><a href="http://www.unl.edu/">UNL</a></li>
+				<li><a href="http://www.unl.edu/">Department</a></li>
+				<li>New Page</li>
+			</ul>
+			<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/badges/secure.html" -->
+			
+<!-- InstanceEndEditable -->
+ </div>
+	</div>
+</div>
+<!-- close red-header -->
+
+<div id="container">
+	<div class="clear">
+		<div id="title"> 
+<!-- InstanceBeginEditable name="collegenavigationlist" -->
+ 
+<!-- InstanceEndEditable -->
+			<div id="titlegraphic">
+				<!-- WDN: see glossary item 'title graphics' -->
+				
+<!-- InstanceBeginEditable name="titlegraphic" -->
+				<h1>Department</h1>
+				<h2>Taglines - We Do The Heavy Lifting</h2>
+				
+<!-- InstanceEndEditable -->
+</div>
+			<!-- maintitle -->
+		</div>
+		<!-- close title -->
+		
+		<div id="navigation">
+			<h4 id="sec_nav">Navigation</h4>
+			
+
+			<div id="navlinks"> 
+<!-- InstanceBeginEditable name="navlinks" -->
+				<!--#include virtual="../sharedcode/navigation.html" -->
+				
+<!-- InstanceEndEditable -->
+</div>
+			
+
+			<div id="nav_end"></div>
+			
+			<!-- WDN: see glossary item 'sidebar links' -->
+			<div id="leftcollinks"> 
+<!-- InstanceBeginEditable name="leftcollinks" -->
+				<!-- WDN: see glossary item 'sidebar links' -->
+				<!--#include virtual="../sharedcode/relatedLinks.html" -->
+				
+<!-- InstanceEndEditable -->
+ </div>
+		</div>
+		<!-- close navigation -->
+		
+		<div id="main_right" class="mainwrapper">
+			<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+			
+			<div id="maincontent"> 
+
+				<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/noscript.html" -->
+				<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+				
+<!-- InstanceBeginEditable name="maincontentarea" -->
+				<p style="margin:20px; border:3px solid #CC0000;padding:10px; text-align:center"> <strong>Delete this box and place your content here.</strong><br />
+					Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://www.unl.edu/webdevnet/">Web Developer Network</a>. <br />
+					<a href="http://validator.unl.edu/check/referer">Click here to check Validation</a> </p>
+				
+<!-- InstanceEndEditable -->
+				<!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+				
+ </div>
+			 </div>
+		<!-- close main right -->
+	</div>
+</div>
+<!-- close container -->
+<div id="footer">
+	<div id="footer_floater"> 
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+		<div id="copyright"> 
+<!-- InstanceBeginEditable name="footercontent" -->
+			<!--#include virtual="../sharedcode/footer.html" -->
+			
+<!-- InstanceEndEditable -->
+ <span><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> <a href="http://validator.unl.edu/check/referer">W3C</a> <a href="http://www1.unl.edu/feeds/">RSS</a> </span><a href="http://www.unl.edu/" title="UNL Home"><img src="/ucomm/templatedependents/templatecss/images/wordmark.png" alt="UNL's wordmark" id="wordmark" /></a></div>
+	</div>
+</div>
+<!-- close footer -->
+<!-- sifr -->
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/sifr_replacements.js"></script>
+</body>
+<!-- InstanceEnd --></html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version2/Unlaffiliate.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version2/Unlaffiliate.tpl
new file mode 100644
index 00000000..dfa57e84
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version2/Unlaffiliate.tpl
@@ -0,0 +1,125 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" ><!-- InstanceBegin template="/Templates/unlaffiliate.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL Redesign</title>
+<!-- InstanceEndEditable -->
+<!-- Codebase:UNLFramework 20061013 -->
+<link rel="stylesheet" type="text/css" media="screen" href="/ucomm/templatedependents/templatecss/layouts/main.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/ucomm/templatedependents/templatecss/layouts/print.css"/>
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/all_compressed.js"></script>
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/ie.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/comments/developersnote.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/metanfavico/metanfavico.html" -->
+<!-- InstanceBeginEditable name="head" -->
+<link rel="stylesheet" type="text/css" media="all" href="/ucomm/templatedependents/templatecss/layouts/affiliate.css" />
+<!-- InstanceEndEditable -->
+<!-- TemplateParam name="leftRandomPromo" type="boolean" value="true" -->
+</head>
+<body id="affiliate">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<!-- InstanceBeginEditable name="siteheader" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/siteheader/affiliate.shtml" -->
+<!-- InstanceEndEditable -->
+<div id="red-header">
+	<div class="clear"><!-- InstanceBeginEditable name="affiliate_name" -->
+		<h1>Affiliated Organization Name</h1>
+		
+<!-- InstanceEndEditable -->
+		<div id="breadcrumbs"> 
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+			<!-- WDN: see glossary item 'breadcrumbs' -->
+			<ul>
+				<li class="first"><a href="http://www.unl.edu/">UNL</a></li>
+				<li>UNL Framework</li>
+			</ul>
+			
+<!-- InstanceEndEditable -->
+ </div>
+	</div>
+</div>
+<!-- close red-header -->
+<!-- InstanceBeginEditable name="shelf" -->
+
+<!-- InstanceEndEditable -->
+<div id="container">
+	<div class="clear">
+		<div id="title">
+			<div id="titlegraphic">
+				<!-- WDN: see glossary item 'title graphics' -->
+				
+<!-- InstanceBeginEditable name="titlegraphic" -->
+				<h1>Affiliate</h1>
+				<h2>Taglines - We Do The Heavy Lifting</h2>
+				
+<!-- InstanceEndEditable -->
+</div>
+			<!-- maintitle -->
+		</div>
+		<!-- close title -->
+		<div id="navigation">
+			<h4 id="sec_nav">Navigation</h4>
+			<div id="navlinks"> 
+<!-- InstanceBeginEditable name="navlinks" -->
+				<!--#include virtual="../sharedcode/navigation.html" -->
+				
+<!-- InstanceEndEditable -->
+</div>
+			<div id="nav_end"></div>
+			<!-- TemplateBeginIf cond="_document['leftRandomPromo']" -->
+<!-- InstanceBeginEditable name="leftRandomPromo" -->
+			<div class="image_small_short" id="leftRandomPromo"> <a href="#" id="leftRandomPromoAnchor"><img id="leftRandomPromoImage" alt="" src="/ucomm/templatedependents/templatecss/images/transpixel.gif" /></a>
+				<script type="text/javascript" src="../sharedcode/leftRandomPromo.js"></script>
+			</div>
+			
+<!-- InstanceEndEditable -->
+<!-- TemplateEndIf -->
+			<!-- WDN: see glossary item 'sidebar links' -->
+			<div id="leftcollinks"> 
+<!-- InstanceBeginEditable name="leftcollinks" -->
+				<!--#include virtual="../sharedcode/relatedLinks.html" -->
+				
+<!-- InstanceEndEditable -->
+ </div>
+		</div>
+		<!-- close navigation -->
+		<div id="main_right" class="mainwrapper">
+			<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+			
+			<div id="maincontent">
+			<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/noscript.html" -->
+			<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+			
+<!-- InstanceBeginEditable name="maincontentarea" -->
+			<h2 class="sec_main">This template is only for affiliates of UNL, or units that have been granted a marketing exemption from the university. Confirm your use of this template before using it!</h2>
+			<p style="margin:20px; border:3px solid #CC0000;padding:10px; text-align:center"> <strong>Delete this box and place your content here.</strong><br />
+				Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://www.unl.edu/webdevnet/">Web Developer Network</a>. <br />
+				<a href="http://validator.unl.edu/check/referer">Click here to check Validation</a> </p>
+			<!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+			
+<!-- InstanceEndEditable -->
+			</div>
+		</div>
+		<!-- close main right -->
+	</div>
+</div>
+<!-- close container -->
+<div id="footer">
+	<div id="footer_floater"> 
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+		<div id="copyright"> 
+<!-- InstanceBeginEditable name="footercontent" -->
+			<!--#include virtual="../sharedcode/footer.html" -->
+			
+<!-- InstanceEndEditable -->
+ <span><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> <a href="http://validator.unl.edu/check/referer">W3C</a> <a href="http://www1.unl.edu/feeds/">RSS</a> </span><a href="http://www.unl.edu/" title="UNL Home"><img src="/ucomm/templatedependents/templatecss/images/wordmark.png" alt="UNL's wordmark" id="wordmark" /></a></div>
+	</div>
+</div>
+<!-- close footer -->
+<!-- sifr -->
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/sifr_replacements.js"></script>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version2/Unlframework.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version2/Unlframework.tpl
new file mode 100644
index 00000000..bfd6a5ac
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version2/Unlframework.tpl
@@ -0,0 +1,112 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" ><!-- InstanceBegin template="/Templates/unlframework.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL Redesign</title>
+<!-- InstanceEndEditable -->
+<!-- Codebase:UNLFramework 20070105 -->
+<link rel="stylesheet" type="text/css" media="screen" href="/ucomm/templatedependents/templatecss/layouts/main.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/ucomm/templatedependents/templatecss/layouts/print.css"/>
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/all_compressed.js"></script>
+<!-- InstanceBeginEditable name="head" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/ie.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/comments/developersnote.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/metanfavico/metanfavico.html" -->
+<!-- InstanceEndEditable -->
+<!-- TemplateParam name="collegenavigation" type="boolean" value="true" --><!-- TemplateParam name="bodyid" type="text" value="" -->
+</head>
+<body id="@@(bodyid)@@">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<!-- InstanceBeginEditable name="siteheader" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/siteheader/siteheader.shtml" -->
+<!-- InstanceEndEditable -->
+<div id="red-header">
+	<div class="clear">
+		<h1>University of Nebraska&ndash;Lincoln</h1>
+		<div id="breadcrumbs"> 
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+			<!-- WDN: see glossary item 'breadcrumbs' -->
+			<ul>
+				<li class="first"><a href="http://www.unl.edu/">UNL</a></li>
+				<li>UNL Framework</li>
+			</ul>
+			
+<!-- InstanceEndEditable -->
+ </div>
+	</div>
+</div>
+<!-- close red-header -->
+<!-- InstanceBeginEditable name="shelf" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/shelf/shelf.shtml" -->
+<!-- InstanceEndEditable -->
+<div id="container">
+	<div class="clear">
+		<div id="title"> <!-- TemplateBeginIf cond="collegenavigation" -->
+<!-- InstanceBeginEditable name="collegenavigationlist" -->
+ 
+<!-- InstanceEndEditable -->
+<!-- TemplateEndIf -->
+			<div id="titlegraphic">
+				<!-- WDN: see glossary item 'title graphics' -->
+				
+<!-- InstanceBeginEditable name="titlegraphic" -->
+				<h1>Department</h1>
+				<h2>Taglines - We Do The Heavy Lifting</h2>
+				
+<!-- InstanceEndEditable -->
+</div>
+			<!-- maintitle -->
+		</div>
+		<!-- close title -->
+		
+<!-- InstanceBeginEditable name="leftcolcontent" -->
+		<div id="navigation">
+			<h4 id="sec_nav">Navigation</h4>
+			<div id="navlinks">
+				<!--#include virtual="../sharedcode/navigation.html" -->
+			</div>
+			<div id="nav_end"></div>
+			<div class="image_small_short" id="leftRandomPromo"> <a href="#" id="leftRandomPromoAnchor"><img id="leftRandomPromoImage" alt="" src="/ucomm/templatedependents/templatecss/images/transpixel.gif" /></a>
+				<script type="text/javascript" src="../sharedcode/leftRandomPromo.js"></script>
+			</div>
+			<!-- WDN: see glossary item 'sidebar links' -->
+			<div id="leftcollinks">
+				<!--#include virtual="../sharedcode/relatedLinks.html" -->
+			</div>
+		</div>
+		<!-- close navigation -->
+		
+<!-- InstanceEndEditable -->
+		<div id="main_right" class="mainwrapper">
+			<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+			
+<!-- InstanceBeginEditable name="maincolcontent" -->
+			<!-- optional main big content image -->
+			<div id="maincontent">
+				<p style="margin:20px; border:3px solid #CC0000;padding:10px; text-align:center"> <strong>Delete this box and place your content here.</strong><br />
+					Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://www.unl.edu/webdevnet/">Web Developer Network</a>. <br />
+					<a href="http://validator.unl.edu/check/referer">Click here to check Validation</a> </p>
+			</div>
+			<!-- close right-area -->
+			
+<!-- InstanceEndEditable -->
+ </div>
+		<!-- close main right -->
+	</div>
+</div>
+<!-- close container -->
+<!-- InstanceBeginEditable name="bigfooter" -->
+<div id="footer">
+	<div id="footer_floater">
+		<div id="copyright">
+			<!--#include virtual="../sharedcode/footer.html" -->
+			<span><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> <a href="http://validator.unl.edu/check/referer">W3C</a> <a href="http://www1.unl.edu/feeds/">RSS</a> </span><a href="http://www.unl.edu/" title="UNL Home"><img src="/ucomm/templatedependents/templatecss/images/wordmark.png" alt="UNL's wordmark" id="wordmark" /></a></div>
+	</div>
+</div>
+<!-- InstanceEndEditable -->
+<!-- close footer -->
+<!-- sifr -->
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/sifr_replacements.js"></script>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version2/Unlstandardtemplate.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version2/Unlstandardtemplate.tpl
new file mode 100644
index 00000000..bff353a1
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version2/Unlstandardtemplate.tpl
@@ -0,0 +1,131 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" ><!-- InstanceBegin template="/Templates/unlstandardtemplate.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL Redesign</title>
+<!-- InstanceEndEditable -->
+<!-- Codebase:UNLFramework 20070105 -->
+<link rel="stylesheet" type="text/css" media="screen" href="/ucomm/templatedependents/templatecss/layouts/main.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/ucomm/templatedependents/templatecss/layouts/print.css"/>
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/all_compressed.js"></script>
+
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/ie.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/comments/developersnote.html" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/metanfavico/metanfavico.html" -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- InstanceEndEditable -->
+<!-- TemplateParam name="leftRandomPromo" type="boolean" value="true" -->
+<!-- InstanceParam name="bodyid" type="text" value="" passthrough="true" -->
+</head>
+<body id="@@@(bodyid)@@@">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<!-- InstanceBeginEditable name="siteheader" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/siteheader/siteheader.shtml" -->
+<!-- InstanceEndEditable -->
+<div id="red-header">
+	<div class="clear">
+		<h1>University of Nebraska&ndash;Lincoln</h1>
+		<div id="breadcrumbs"> 
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+			<ul>
+				<li class="first"><a href="http://www.unl.edu/">UNL</a></li>
+				<li>UNL Standard Template</li>
+			</ul>
+			
+<!-- InstanceEndEditable -->
+ </div>
+	</div>
+</div>
+<!-- close red-header -->
+<!-- InstanceBeginEditable name="shelf" -->
+<!--#include virtual="/ucomm/templatedependents/templatesharedcode/includes/shelf/shelf.shtml" -->
+<!-- InstanceEndEditable -->
+<div id="container">
+	<div class="clear">
+		<div id="title"> 
+<!-- InstanceBeginEditable name="collegenavigationlist" -->
+ 
+<!-- InstanceEndEditable -->
+			<div id="titlegraphic">
+				<!-- WDN: see glossary item 'title graphics' -->
+				
+<!-- InstanceBeginEditable name="titlegraphic" -->
+				<h1>Department</h1>
+				<h2>Taglines - We Do The Heavy Lifting</h2>
+				
+<!-- InstanceEndEditable -->
+</div>
+			<!-- maintitle -->
+		</div>
+		<!-- close title -->
+		
+
+		<div id="navigation">
+			<h4 id="sec_nav">Navigation</h4>
+			
+<!-- InstanceBeginEditable name="navcontent" -->
+			<div id="navlinks">
+				<!--#include virtual="../sharedcode/navigation.html" -->
+			</div>
+			
+<!-- InstanceEndEditable -->
+			<div id="nav_end"></div>
+			<!-- TemplateBeginIf cond="_document['leftRandomPromo']" -->
+<!-- InstanceBeginEditable name="leftRandomPromo" -->
+			<div class="image_small_short" id="leftRandomPromo"> <a href="#" id="leftRandomPromoAnchor"><img id="leftRandomPromoImage" alt="" src="/ucomm/templatedependents/templatecss/images/transpixel.gif" /></a>
+				<script type="text/javascript" src="../sharedcode/leftRandomPromo.js"></script>
+			</div>
+			
+<!-- InstanceEndEditable -->
+<!-- TemplateEndIf -->
+			<!-- WDN: see glossary item 'sidebar links' -->
+			<div id="leftcollinks"> 
+<!-- InstanceBeginEditable name="leftcollinks" -->
+				<h3>Related Links</h3>
+				<!--#include virtual="../sharedcode/relatedLinks.html" -->
+				
+<!-- InstanceEndEditable -->
+ </div>
+		</div>
+		<!-- close navigation -->
+		
+
+		<div id="main_right" class="mainwrapper">
+			<!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+			
+
+			<div id="maincontent"> 
+<!-- InstanceBeginEditable name="maincontent" -->
+				<p style="margin:20px; border:3px solid #CC0000;padding:10px; text-align:center"> <strong>Delete this box and place your content here.</strong><br />
+					Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://www.unl.edu/webdevnet/">Web Developer Network</a>. <br />
+					<a href="http://validator.unl.edu/check/referer">Click here to check Validation</a> </p>
+				
+<!-- InstanceEndEditable -->
+ </div>
+			
+ </div>
+		<!-- close main right -->
+	</div>
+</div>
+<!-- close container -->
+
+<div id="footer">
+	<div id="footer_floater"> 
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+		<div id="copyright"> 
+<!-- InstanceBeginEditable name="footercontent" -->
+			<!--#include virtual="../sharedcode/footer.html" -->
+			
+<!-- InstanceEndEditable -->
+ <span><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> <a href="http://validator.unl.edu/check/referer">W3C</a> <a href="http://www1.unl.edu/feeds/">RSS</a> </span><a href="http://www.unl.edu/" title="UNL Home"><img src="/ucomm/templatedependents/templatecss/images/wordmark.png" alt="UNL's wordmark" id="wordmark" /></a></div>
+	</div>
+</div>
+
+<!-- close footer -->
+<!-- sifr -->
+<script type="text/javascript" src="/ucomm/templatedependents/templatesharedcode/scripts/sifr_replacements.js"></script>
+</body>
+<!-- InstanceEnd --></html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version3/Absolute.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version3/Absolute.tpl
new file mode 100644
index 00000000..3b2d5388
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version3/Absolute.tpl
@@ -0,0 +1,119 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><!-- InstanceBegin template="/Templates/absolute.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!--
+    Membership and regular participation in the UNL Web Developer Network
+    is required to use the UNL templates. Visit the WDN site at 
+    http://wdn.unl.edu/. Click the WDN Registry link to log in and
+    register your unl.edu site.
+    All UNL template code is the property of the UNL Web Developer Network.
+    The code seen in a source code view is not, and may not be used as, a 
+    template. You may not use this code, a reverse-engineered version of 
+    this code, or its associated visual presentation in whole or in part to
+    create a derivative work.
+    This message may not be removed from any pages based on the UNL site template.
+    
+    $Id: absolute.dwt 536 2009-07-23 15:47:30Z bbieber2 $
+-->
+<link rel="stylesheet" type="text/css" media="screen" href="http://www.unl.edu/wdn/templates_3.0/css/all.css" />
+<link rel="stylesheet" type="text/css" media="print" href="http://www.unl.edu/wdn/templates_3.0/css/print.css" />
+<script type="text/javascript" src="http://www.unl.edu/wdn/templates_3.0/scripts/all.js"></script>
+<!--#include virtual="/wdn/templates_3.0/includes/browserspecifics.html" -->
+<!--#include virtual="/wdn/templates_3.0/includes/metanfavico.html" -->
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- Place optional header elements here -->
+<!-- InstanceEndEditable -->
+</head>
+<body class="fixed">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<div id="wdn_wrapper">
+    <div id="header"> <a href="http://www.unl.edu/" title="UNL website"><img src="http://www.unl.edu/wdn/templates_3.0/images/logo.png" alt="UNL graphic identifier" id="logo" /></a>
+        <h1>University of Nebraska&ndash;Lincoln</h1>
+        <!--#include virtual="/wdn/templates_3.0/includes/wdnTools.html" -->
+    </div>
+    <div id="wdn_navigation_bar">
+        <div id="breadcrumbs">
+            <!-- WDN: see glossary item 'breadcrumbs' -->
+            
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+            <ul>
+                <li><a href="http://www.unl.edu/" title="University of Nebraska&ndash;Lincoln">UNL</a></li>
+                <li>Department</li>
+            </ul>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="wdn_navigation_wrapper">
+            <div id="navigation">
+<!-- InstanceBeginEditable name="navlinks" -->
+                <!--#include virtual="../sharedcode/navigation.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+        </div>
+    </div>
+    <div id="wdn_content_wrapper">
+        <div id="titlegraphic">
+<!-- InstanceBeginEditable name="titlegraphic" -->
+            <h1>Department</h1>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="pagetitle">
+<!-- InstanceBeginEditable name="pagetitle" -->
+ 
+<!-- InstanceEndEditable -->
+</div>
+        <div id="maincontent">
+            <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+            
+<!-- InstanceBeginEditable name="maincontentarea" -->
+            <p>Place your content here.<br />
+                Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://wdn.unl.edu//">Web Developer Network</a>. <br />
+                <a href="http://validator.unl.edu/check/referer">Check this page</a> </p>
+            
+<!-- InstanceEndEditable -->
+            <div class="clear"></div>
+            <!--#include virtual="/wdn/templates_3.0/includes/noscript.html" -->
+            <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+        </div>
+        <div id="footer">
+            <div id="footer_floater"></div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/feedback.html" -->
+            </div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="leftcollinks" -->
+                <!--#include virtual="../sharedcode/relatedLinks.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="contactinfo" -->
+                <!--#include virtual="../sharedcode/footerContactInfo.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/socialmediashare.html" -->
+            </div>
+            
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+            <div id="wdn_copyright">
+<!-- InstanceBeginEditable name="footercontent" -->
+                <!--#include virtual="../sharedcode/footer.html" -->
+                
+<!-- InstanceEndEditable -->
+                <!--#include virtual="/wdn/templates_3.0/includes/wdn.html" -->
+                | <a href="http://validator.unl.edu/check/referer">W3C</a> | <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS</a> <a href="http://www.unl.edu/" title="UNL Home" id="wdn_unl_wordmark"><img src="http://www.unl.edu/wdn/templates_3.0/css/footer/images/wordmark.png" alt="UNL's wordmark" /></a> </div>
+        </div>
+    </div>
+    <div id="wdn_wrapper_footer"> </div>
+</div>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version3/Debug.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version3/Debug.tpl
new file mode 100644
index 00000000..29b65bd1
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version3/Debug.tpl
@@ -0,0 +1,119 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><!-- InstanceBegin template="/Templates/debug.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!--
+    Membership and regular participation in the UNL Web Developer Network
+    is required to use the UNL templates. Visit the WDN site at 
+    http://wdn.unl.edu/. Click the WDN Registry link to log in and
+    register your unl.edu site.
+    All UNL template code is the property of the UNL Web Developer Network.
+    The code seen in a source code view is not, and may not be used as, a 
+    template. You may not use this code, a reverse-engineered version of 
+    this code, or its associated visual presentation in whole or in part to
+    create a derivative work.
+    This message may not be removed from any pages based on the UNL site template.
+    
+    $Id: debug.dwt 728 2009-09-08 16:53:28Z bbieber2 $
+-->
+<link rel="stylesheet" type="text/css" media="screen" href="/wdn/templates_3.0/css/debug.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/wdn/templates_3.0/css/print.css" />
+<script type="text/javascript" src="/wdn/templates_3.0/scripts/debug.js"></script>
+<!--#include virtual="/wdn/templates_3.0/includes/browserspecifics.html" -->
+<!--#include virtual="/wdn/templates_3.0/includes/metanfavico.html" -->
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- Place optional header elements here -->
+<!-- InstanceEndEditable -->
+</head>
+<body class="fixed debug">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<div id="wdn_wrapper">
+    <div id="header"> <a href="http://www.unl.edu/" title="UNL website"><img src="/wdn/templates_3.0/images/logo.png" alt="UNL graphic identifier" id="logo" /></a>
+        <h1>University of Nebraska&ndash;Lincoln</h1>
+        <!--#include virtual="/wdn/templates_3.0/includes/wdnTools.html" -->
+    </div>
+    <div id="wdn_navigation_bar">
+        <div id="breadcrumbs">
+            <!-- WDN: see glossary item 'breadcrumbs' -->
+            
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+            <ul>
+                <li><a href="http://www.unl.edu/" title="University of Nebraska&ndash;Lincoln">UNL</a></li>
+                <li>Department</li>
+            </ul>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="wdn_navigation_wrapper">
+            <div id="navigation">
+<!-- InstanceBeginEditable name="navlinks" -->
+                <!--#include virtual="../sharedcode/navigation.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+        </div>
+    </div>
+    <div id="wdn_content_wrapper">
+        <div id="titlegraphic">
+<!-- InstanceBeginEditable name="titlegraphic" -->
+            <h1>Department</h1>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="pagetitle">
+<!-- InstanceBeginEditable name="pagetitle" -->
+ 
+<!-- InstanceEndEditable -->
+</div>
+        <div id="maincontent">
+            <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+            
+<!-- InstanceBeginEditable name="maincontentarea" -->
+            <p>Place your content here.<br />
+                Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://wdn.unl.edu//">Web Developer Network</a>. <br />
+                <a href="http://validator.unl.edu/check/referer">Check this page</a> </p>
+            
+<!-- InstanceEndEditable -->
+            <div class="clear"></div>
+            <!--#include virtual="/wdn/templates_3.0/includes/noscript.html" -->
+            <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+        </div>
+        <div id="footer">
+            <div id="footer_floater"></div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/feedback.html" -->
+            </div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="leftcollinks" -->
+                <!--#include virtual="../sharedcode/relatedLinks.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="contactinfo" -->
+                <!--#include virtual="../sharedcode/footerContactInfo.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/socialmediashare.html" -->
+            </div>
+            
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+            <div id="wdn_copyright">
+<!-- InstanceBeginEditable name="footercontent" -->
+                <!--#include virtual="../sharedcode/footer.html" -->
+                
+<!-- InstanceEndEditable -->
+                <!--#include virtual="/wdn/templates_3.0/includes/wdn.html" -->
+                | <a href="http://validator.unl.edu/check/referer">W3C</a> | <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS</a> <a href="http://www.unl.edu/" title="UNL Home" id="wdn_unl_wordmark"><img src="/wdn/templates_3.0/css/footer/images/wordmark.png" alt="UNL's wordmark" /></a> </div>
+        </div>
+    </div>
+    <div id="wdn_wrapper_footer"> </div>
+</div>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version3/Document.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version3/Document.tpl
new file mode 100644
index 00000000..7c0daa28
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version3/Document.tpl
@@ -0,0 +1,91 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><!-- InstanceBegin template="/Templates/document.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!--
+    Membership and regular participation in the UNL Web Developer Network
+    is required to use the UNL templates. Visit the WDN site at 
+    http://wdn.unl.edu/. Click the WDN Registry link to log in and
+    register your unl.edu site.
+    All UNL template code is the property of the UNL Web Developer Network.
+    The code seen in a source code view is not, and may not be used as, a 
+    template. You may not use this code, a reverse-engineered version of 
+    this code, or its associated visual presentation in whole or in part to
+    create a derivative work.
+    This message may not be removed from any pages based on the UNL site template.
+    
+    $Id: document.dwt 536 2009-07-23 15:47:30Z bbieber2 $
+-->
+<link rel="stylesheet" type="text/css" media="screen" href="/wdn/templates_3.0/css/all.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/wdn/templates_3.0/css/print.css" />
+<script type="text/javascript" src="/wdn/templates_3.0/scripts/all.js"></script>
+<!--#include virtual="/wdn/templates_3.0/includes/browserspecifics.html" -->
+<!--#include virtual="/wdn/templates_3.0/includes/metanfavico.html" -->
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- Place optional header elements here -->
+<!-- InstanceEndEditable -->
+</head>
+<body class="document">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<div id="wdn_wrapper">
+    <div id="header"> <a href="http://www.unl.edu/" title="UNL website"><img src="/wdn/templates_3.0/images/logo.png" alt="UNL graphic identifier" id="logo" /></a>
+        <h1>University of Nebraska&ndash;Lincoln</h1>
+    </div>
+    <div id="wdn_navigation_bar">
+        <div id="breadcrumbs">
+            <!-- WDN: see glossary item 'breadcrumbs' -->
+            
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+            <ul>
+                <li><a href="http://www.unl.edu/" title="University of Nebraska&ndash;Lincoln">UNL</a></li>
+                <li>Department</li>
+            </ul>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="wdn_navigation_wrapper">
+            <div id="navigation"></div>
+        </div>
+    </div>
+    <div id="wdn_content_wrapper">
+        <div id="titlegraphic">
+<!-- InstanceBeginEditable name="titlegraphic" -->
+            <h1>Department</h1>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="pagetitle">
+<!-- InstanceBeginEditable name="pagetitle" -->
+ 
+<!-- InstanceEndEditable -->
+</div>
+        <div id="maincontent">
+            <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+            
+<!-- InstanceBeginEditable name="maincontentarea" -->
+            <p>Place your content here.<br />
+                Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://wdn.unl.edu//">Web Developer Network</a>. <br />
+                <a href="http://validator.unl.edu/check/referer">Check this page</a> </p>
+            
+<!-- InstanceEndEditable -->
+            <div class="clear"></div>
+            <!--#include virtual="/wdn/templates_3.0/includes/noscript.html" -->
+            <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+        </div>
+        <div id="footer">
+            <div id="footer_floater"></div>
+            <div id="wdn_copyright">
+<!-- InstanceBeginEditable name="footercontent" -->
+                <!--#include virtual="../sharedcode/footer.html" -->
+                
+<!-- InstanceEndEditable -->
+                <!--#include virtual="/wdn/templates_3.0/includes/wdn.html" -->
+                | <a href="http://validator.unl.edu/check/referer">W3C</a> | <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS</a> <a href="http://www.unl.edu/" title="UNL Home" id="wdn_unl_wordmark"><img src="/wdn/templates_3.0/css/footer/images/wordmark.png" alt="UNL's wordmark" /></a> </div>
+        </div>
+    </div>
+    <div id="wdn_wrapper_footer"> </div>
+</div>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version3/Fixed.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version3/Fixed.tpl
new file mode 100644
index 00000000..bc1710dd
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version3/Fixed.tpl
@@ -0,0 +1,119 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><!-- InstanceBegin template="/Templates/fixed.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!--
+    Membership and regular participation in the UNL Web Developer Network
+    is required to use the UNL templates. Visit the WDN site at 
+    http://wdn.unl.edu/. Click the WDN Registry link to log in and
+    register your unl.edu site.
+    All UNL template code is the property of the UNL Web Developer Network.
+    The code seen in a source code view is not, and may not be used as, a 
+    template. You may not use this code, a reverse-engineered version of 
+    this code, or its associated visual presentation in whole or in part to
+    create a derivative work.
+    This message may not be removed from any pages based on the UNL site template.
+    
+    $Id: fixed.dwt 536 2009-07-23 15:47:30Z bbieber2 $
+-->
+<link rel="stylesheet" type="text/css" media="screen" href="/wdn/templates_3.0/css/all.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/wdn/templates_3.0/css/print.css" />
+<script type="text/javascript" src="/wdn/templates_3.0/scripts/all.js"></script>
+<!--#include virtual="/wdn/templates_3.0/includes/browserspecifics.html" -->
+<!--#include virtual="/wdn/templates_3.0/includes/metanfavico.html" -->
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- Place optional header elements here -->
+<!-- InstanceEndEditable -->
+</head>
+<body class="fixed">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<div id="wdn_wrapper">
+    <div id="header"> <a href="http://www.unl.edu/" title="UNL website"><img src="/wdn/templates_3.0/images/logo.png" alt="UNL graphic identifier" id="logo" /></a>
+        <h1>University of Nebraska&ndash;Lincoln</h1>
+        <!--#include virtual="/wdn/templates_3.0/includes/wdnTools.html" -->
+    </div>
+    <div id="wdn_navigation_bar">
+        <div id="breadcrumbs">
+            <!-- WDN: see glossary item 'breadcrumbs' -->
+            
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+            <ul>
+                <li><a href="http://www.unl.edu/" title="University of Nebraska&ndash;Lincoln">UNL</a></li>
+                <li>Department</li>
+            </ul>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="wdn_navigation_wrapper">
+            <div id="navigation">
+<!-- InstanceBeginEditable name="navlinks" -->
+                <!--#include virtual="../sharedcode/navigation.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+        </div>
+    </div>
+    <div id="wdn_content_wrapper">
+        <div id="titlegraphic">
+<!-- InstanceBeginEditable name="titlegraphic" -->
+            <h1>Department</h1>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="pagetitle">
+<!-- InstanceBeginEditable name="pagetitle" -->
+ 
+<!-- InstanceEndEditable -->
+</div>
+        <div id="maincontent">
+            <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+            
+<!-- InstanceBeginEditable name="maincontentarea" -->
+            <p>Place your content here.<br />
+                Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://wdn.unl.edu//">Web Developer Network</a>. <br />
+                <a href="http://validator.unl.edu/check/referer">Check this page</a> </p>
+            
+<!-- InstanceEndEditable -->
+            <div class="clear"></div>
+            <!--#include virtual="/wdn/templates_3.0/includes/noscript.html" -->
+            <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+        </div>
+        <div id="footer">
+            <div id="footer_floater"></div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/feedback.html" -->
+            </div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="leftcollinks" -->
+                <!--#include virtual="../sharedcode/relatedLinks.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="contactinfo" -->
+                <!--#include virtual="../sharedcode/footerContactInfo.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/socialmediashare.html" -->
+            </div>
+            
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+            <div id="wdn_copyright">
+<!-- InstanceBeginEditable name="footercontent" -->
+                <!--#include virtual="../sharedcode/footer.html" -->
+                
+<!-- InstanceEndEditable -->
+                <!--#include virtual="/wdn/templates_3.0/includes/wdn.html" -->
+                | <a href="http://validator.unl.edu/check/referer">W3C</a> | <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS</a> <a href="http://www.unl.edu/" title="UNL Home" id="wdn_unl_wordmark"><img src="/wdn/templates_3.0/css/footer/images/wordmark.png" alt="UNL's wordmark" /></a> </div>
+        </div>
+    </div>
+    <div id="wdn_wrapper_footer"> </div>
+</div>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version3/Liquid.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version3/Liquid.tpl
new file mode 100644
index 00000000..0b127201
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version3/Liquid.tpl
@@ -0,0 +1,119 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><!-- InstanceBegin template="/Templates/liquid.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!--
+    Membership and regular participation in the UNL Web Developer Network
+    is required to use the UNL templates. Visit the WDN site at 
+    http://wdn.unl.edu/. Click the WDN Registry link to log in and
+    register your unl.edu site.
+    All UNL template code is the property of the UNL Web Developer Network.
+    The code seen in a source code view is not, and may not be used as, a 
+    template. You may not use this code, a reverse-engineered version of 
+    this code, or its associated visual presentation in whole or in part to
+    create a derivative work.
+    This message may not be removed from any pages based on the UNL site template.
+    
+    $Id: liquid.dwt 536 2009-07-23 15:47:30Z bbieber2 $
+-->
+<link rel="stylesheet" type="text/css" media="screen" href="/wdn/templates_3.0/css/all.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/wdn/templates_3.0/css/print.css" />
+<script type="text/javascript" src="/wdn/templates_3.0/scripts/all.js"></script>
+<!--#include virtual="/wdn/templates_3.0/includes/browserspecifics.html" -->
+<!--#include virtual="/wdn/templates_3.0/includes/metanfavico.html" -->
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- Place optional header elements here -->
+<!-- InstanceEndEditable -->
+</head>
+<body class="liquid">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<div id="wdn_wrapper">
+    <div id="header"> <a href="http://www.unl.edu/" title="UNL website"><img src="/wdn/templates_3.0/images/logo.png" alt="UNL graphic identifier" id="logo" /></a>
+        <h1>University of Nebraska&ndash;Lincoln</h1>
+        <!--#include virtual="/wdn/templates_3.0/includes/wdnTools.html" -->
+    </div>
+    <div id="wdn_navigation_bar">
+        <div id="breadcrumbs">
+            <!-- WDN: see glossary item 'breadcrumbs' -->
+            
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+            <ul>
+                <li><a href="http://www.unl.edu/" title="University of Nebraska&ndash;Lincoln">UNL</a></li>
+                <li>Department</li>
+            </ul>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="wdn_navigation_wrapper">
+            <div id="navigation">
+<!-- InstanceBeginEditable name="navlinks" -->
+                <!--#include virtual="../sharedcode/navigation.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+        </div>
+    </div>
+    <div id="wdn_content_wrapper">
+        <div id="titlegraphic">
+<!-- InstanceBeginEditable name="titlegraphic" -->
+            <h1>Department</h1>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="pagetitle">
+<!-- InstanceBeginEditable name="pagetitle" -->
+ 
+<!-- InstanceEndEditable -->
+</div>
+        <div id="maincontent">
+            <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+            
+<!-- InstanceBeginEditable name="maincontentarea" -->
+            <p>Place your content here.<br />
+                Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://wdn.unl.edu//">Web Developer Network</a>. <br />
+                <a href="http://validator.unl.edu/check/referer">Check this page</a> </p>
+            
+<!-- InstanceEndEditable -->
+            <div class="clear"></div>
+            <!--#include virtual="/wdn/templates_3.0/includes/noscript.html" -->
+            <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+        </div>
+        <div id="footer">
+            <div id="footer_floater"></div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/feedback.html" -->
+            </div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="leftcollinks" -->
+                <!--#include virtual="../sharedcode/relatedLinks.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="contactinfo" -->
+                <!--#include virtual="../sharedcode/footerContactInfo.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/socialmediashare.html" -->
+            </div>
+            
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+            <div id="wdn_copyright">
+<!-- InstanceBeginEditable name="footercontent" -->
+                <!--#include virtual="../sharedcode/footer.html" -->
+                
+<!-- InstanceEndEditable -->
+                <!--#include virtual="/wdn/templates_3.0/includes/wdn.html" -->
+                | <a href="http://validator.unl.edu/check/referer">W3C</a> | <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS</a> <a href="http://www.unl.edu/" title="UNL Home" id="wdn_unl_wordmark"><img src="/wdn/templates_3.0/css/footer/images/wordmark.png" alt="UNL's wordmark" /></a> </div>
+        </div>
+    </div>
+    <div id="wdn_wrapper_footer"> </div>
+</div>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version3/Popup.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version3/Popup.tpl
new file mode 100644
index 00000000..6c7b1370
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version3/Popup.tpl
@@ -0,0 +1,79 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><!-- InstanceBegin template="/Templates/popup.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!--
+    Membership and regular participation in the UNL Web Developer Network
+    is required to use the UNL templates. Visit the WDN site at 
+    http://wdn.unl.edu/. Click the WDN Registry link to log in and
+    register your unl.edu site.
+    All UNL template code is the property of the UNL Web Developer Network.
+    The code seen in a source code view is not, and may not be used as, a 
+    template. You may not use this code, a reverse-engineered version of 
+    this code, or its associated visual presentation in whole or in part to
+    create a derivative work.
+    This message may not be removed from any pages based on the UNL site template.
+    
+    $Id: popup.dwt 536 2009-07-23 15:47:30Z bbieber2 $
+-->
+<link rel="stylesheet" type="text/css" media="screen" href="/wdn/templates_3.0/css/all.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/wdn/templates_3.0/css/print.css" />
+<script type="text/javascript" src="/wdn/templates_3.0/scripts/all.js"></script>
+<!--#include virtual="/wdn/templates_3.0/includes/browserspecifics.html" -->
+<!--#include virtual="/wdn/templates_3.0/includes/metanfavico.html" -->
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- Place optional header elements here -->
+<!-- InstanceEndEditable -->
+</head>
+<body class="popup">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<div id="wdn_wrapper">
+    <div id="header"> <a href="http://www.unl.edu/" title="UNL website"><img src="/wdn/templates_3.0/images/logo.png" alt="UNL graphic identifier" id="logo" /></a>
+        <h1>University of Nebraska&ndash;Lincoln</h1>
+    </div>
+    <div id="wdn_content_wrapper">
+        <div id="titlegraphic">
+<!-- InstanceBeginEditable name="titlegraphic" -->
+            <h1>Department</h1>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="pagetitle">
+<!-- InstanceBeginEditable name="pagetitle" -->
+ 
+<!-- InstanceEndEditable -->
+</div>
+        <div id="maincontent">
+            <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+            
+<!-- InstanceBeginEditable name="maincontentarea" -->
+            <p>Place your content here.<br />
+                Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://wdn.unl.edu//">Web Developer Network</a>. <br />
+                <a href="http://validator.unl.edu/check/referer">Check this page</a> </p>
+            
+<!-- InstanceEndEditable -->
+            <div class="clear"></div>
+            <!--#include virtual="/wdn/templates_3.0/includes/noscript.html" -->
+            <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+        </div>
+        <div id="footer">
+            <div id="footer_floater"></div>
+            <div id="wdn_copyright">
+<!-- InstanceBeginEditable name="footercontent" -->
+                <!--#include virtual="../sharedcode/footer.html" -->
+                
+<!-- InstanceEndEditable -->
+                <ul>
+                    <li><a href="http://validator.unl.edu/check/referer">W3C</a></li>
+                    <li><a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS</a></li>
+                </ul>
+                <!--#include virtual="/wdn/templates_3.0/includes/wdn.html" -->
+                <a href="http://www.unl.edu/" title="UNL Home" id="wdn_unl_wordmark"><img src="/wdn/templates_3.0/css/footer/images/wordmark.png" alt="UNL's wordmark" /></a> </div>
+        </div>
+    </div>
+    <div id="wdn_wrapper_footer"> </div>
+</div>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version3/Secure.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version3/Secure.tpl
new file mode 100644
index 00000000..e16e1afd
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version3/Secure.tpl
@@ -0,0 +1,101 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><!-- InstanceBegin template="/Templates/secure.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!--
+    Membership and regular participation in the UNL Web Developer Network
+    is required to use the UNL templates. Visit the WDN site at 
+    http://wdn.unl.edu/. Click the WDN Registry link to log in and
+    register your unl.edu site.
+    All UNL template code is the property of the UNL Web Developer Network.
+    The code seen in a source code view is not, and may not be used as, a 
+    template. You may not use this code, a reverse-engineered version of 
+    this code, or its associated visual presentation in whole or in part to
+    create a derivative work.
+    This message may not be removed from any pages based on the UNL site template.
+    
+    $Id: secure.dwt 562 2009-07-28 19:58:23Z bbieber2 $
+-->
+<link rel="stylesheet" type="text/css" media="screen" href="/wdn/templates_3.0/css/debug.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/wdn/templates_3.0/css/print.css" />
+<script type="text/javascript" src="/wdn/templates_3.0/scripts/all.js"></script>
+<!--#include virtual="/wdn/templates_3.0/includes/browserspecifics.html" -->
+<!--#include virtual="/wdn/templates_3.0/includes/metanfavico.html" -->
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- Place optional header elements here -->
+<!-- InstanceEndEditable -->
+</head>
+<body class="secure fixed">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<div id="wdn_wrapper">
+    <div id="header"> <a href="http://www.unl.edu/" title="UNL website"><img src="/wdn/templates_3.0/images/logo.png" alt="UNL graphic identifier" id="logo" /></a>
+        <h1>University of Nebraska&ndash;Lincoln</h1>
+        <div id="wdn_identity_management"> 
+<!-- InstanceBeginEditable name="identitymanagement" -->
+<a href="https://login.unl.edu/cas/logout">Logout</a>
+<!-- InstanceEndEditable -->
+ </div>
+    </div>
+    <div id="wdn_navigation_bar">
+        <div id="breadcrumbs">
+            <!-- WDN: see glossary item 'breadcrumbs' -->
+            
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+            <ul>
+                <li><a href="http://www.unl.edu/" title="University of Nebraska&ndash;Lincoln">UNL</a></li>
+                <li>Department</li>
+            </ul>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="wdn_navigation_wrapper">
+            <div id="navigation">
+<!-- InstanceBeginEditable name="navlinks" -->
+                <!--#include virtual="../sharedcode/navigation.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+        </div>
+    </div>
+    <div id="wdn_content_wrapper">
+        <div id="titlegraphic">
+<!-- InstanceBeginEditable name="titlegraphic" -->
+            <h1>Department</h1>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="pagetitle">
+<!-- InstanceBeginEditable name="pagetitle" -->
+ 
+<!-- InstanceEndEditable -->
+</div>
+        <div id="maincontent">
+            <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+            
+<!-- InstanceBeginEditable name="maincontentarea" -->
+            <p>Place your content here.<br />
+                Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://wdn.unl.edu//">Web Developer Network</a>. <br />
+                <a href="http://validator.unl.edu/check/referer">Check this page</a> </p>
+            
+<!-- InstanceEndEditable -->
+            <div class="clear"></div>
+            <!--#include virtual="/wdn/templates_3.0/includes/noscript.html" -->
+            <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+        </div>
+        <div id="footer">
+            <div id="footer_floater"></div>
+            <div id="wdn_copyright">
+<!-- InstanceBeginEditable name="footercontent" -->
+                <!--#include virtual="../sharedcode/footer.html" -->
+                
+<!-- InstanceEndEditable -->
+                <!--#include virtual="/wdn/templates_3.0/includes/wdn.html" -->
+                | <a href="http://validator.unl.edu/check/referer">W3C</a> | <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS</a> <a href="http://www.unl.edu/" title="UNL Home" id="wdn_unl_wordmark"><img src="/wdn/templates_3.0/css/footer/images/wordmark.png" alt="UNL's wordmark" /></a> </div>
+        </div>
+    </div>
+    <div id="wdn_wrapper_footer"> </div>
+</div>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version3/Shared_column_left.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version3/Shared_column_left.tpl
new file mode 100644
index 00000000..378c147c
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version3/Shared_column_left.tpl
@@ -0,0 +1,131 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><!-- InstanceBegin template="/Templates/shared_column_left.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!--
+    Membership and regular participation in the UNL Web Developer Network
+    is required to use the UNL templates. Visit the WDN site at 
+    http://wdn.unl.edu/. Click the WDN Registry link to log in and
+    register your unl.edu site.
+    All UNL template code is the property of the UNL Web Developer Network.
+    The code seen in a source code view is not, and may not be used as, a 
+    template. You may not use this code, a reverse-engineered version of 
+    this code, or its associated visual presentation in whole or in part to
+    create a derivative work.
+    This message may not be removed from any pages based on the UNL site template.
+    
+    $Id: shared_column_left.dwt 536 2009-07-23 15:47:30Z bbieber2 $
+-->
+<link rel="stylesheet" type="text/css" media="screen" href="/wdn/templates_3.0/css/all.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/wdn/templates_3.0/css/print.css" />
+<script type="text/javascript" src="/wdn/templates_3.0/scripts/all.js"></script>
+<!--#include virtual="/wdn/templates_3.0/includes/browserspecifics.html" -->
+<!--#include virtual="/wdn/templates_3.0/includes/metanfavico.html" -->
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- Place optional header elements here -->
+<!-- InstanceEndEditable -->
+</head>
+<body class="fixed">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<div id="wdn_wrapper">
+    <div id="header"> <a href="http://www.unl.edu/" title="UNL website"><img src="/wdn/templates_3.0/images/logo.png" alt="UNL graphic identifier" id="logo" /></a>
+        <h1>University of Nebraska&ndash;Lincoln</h1>
+        <!--#include virtual="/wdn/templates_3.0/includes/wdnTools.html" -->
+    </div>
+    <div id="wdn_navigation_bar">
+        <div id="breadcrumbs">
+            <!-- WDN: see glossary item 'breadcrumbs' -->
+            
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+            <ul>
+                <li><a href="http://www.unl.edu/" title="University of Nebraska&ndash;Lincoln">UNL</a></li>
+                <li>Department</li>
+            </ul>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="wdn_navigation_wrapper">
+            <div id="navigation">
+<!-- InstanceBeginEditable name="navlinks" -->
+                <!--#include virtual="../sharedcode/navigation.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+        </div>
+    </div>
+    <div id="wdn_content_wrapper">
+        <div id="titlegraphic">
+<!-- InstanceBeginEditable name="titlegraphic" -->
+            <h1>Department</h1>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="pagetitle">
+<!-- InstanceBeginEditable name="pagetitle" -->
+ 
+<!-- InstanceEndEditable -->
+</div>
+        <div id="maincontent">
+            <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+            
+<!-- InstanceBeginEditable name="sharedcolumn" -->
+            <div class="col left">
+                <!--#include virtual="../sharedcode/sharedColumn.html" -->
+            </div>
+            
+<!-- InstanceEndEditable -->
+            <div class="three_col right"> 
+<!-- InstanceBeginEditable name="maincontentarea" -->
+                <p>Place your content here.<br />
+                    Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://wdn.unl.edu//">Web Developer Network</a>. <br />
+                    <a href="http://validator.unl.edu/check/referer">Check this page</a> </p>
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="clear"></div>
+            <!--#include virtual="/wdn/templates_3.0/includes/noscript.html" -->
+            <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+        </div>
+        <div id="footer">
+            <div id="footer_floater"></div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/feedback.html" -->
+            </div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="leftcollinks" -->
+                <!--#include virtual="../sharedcode/relatedLinks.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="contactinfo" -->
+                <!--#include virtual="../sharedcode/footerContactInfo.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/socialmediashare.html" -->
+            </div>
+            
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+            <div id="wdn_copyright">
+<!-- InstanceBeginEditable name="footercontent" -->
+                <!--#include virtual="../sharedcode/footer.html" -->
+                
+<!-- InstanceEndEditable -->
+                <ul>
+                    <li><a href="http://validator.unl.edu/check/referer">W3C</a></li>
+                    <li><a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS</a></li>
+                </ul>
+                <!--#include virtual="/wdn/templates_3.0/includes/wdn.html" -->
+                <a href="http://www.unl.edu/" title="UNL Home" id="wdn_unl_wordmark"><img src="/wdn/templates_3.0/css/footer/images/wordmark.png" alt="UNL's wordmark" /></a> </div>
+        </div>
+    </div>
+    <div id="wdn_wrapper_footer"> </div>
+</div>
+</body>
+</html>
diff --git a/lib/data/UNL_Templates/data/tpl_cache/Version3/Shared_column_right.tpl b/lib/data/UNL_Templates/data/tpl_cache/Version3/Shared_column_right.tpl
new file mode 100644
index 00000000..9e07cc61
--- /dev/null
+++ b/lib/data/UNL_Templates/data/tpl_cache/Version3/Shared_column_right.tpl
@@ -0,0 +1,131 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><!-- InstanceBegin template="/Templates/shared_column_right.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<!--
+    Membership and regular participation in the UNL Web Developer Network
+    is required to use the UNL templates. Visit the WDN site at 
+    http://wdn.unl.edu/. Click the WDN Registry link to log in and
+    register your unl.edu site.
+    All UNL template code is the property of the UNL Web Developer Network.
+    The code seen in a source code view is not, and may not be used as, a 
+    template. You may not use this code, a reverse-engineered version of 
+    this code, or its associated visual presentation in whole or in part to
+    create a derivative work.
+    This message may not be removed from any pages based on the UNL site template.
+    
+    $Id: shared_column_right.dwt 536 2009-07-23 15:47:30Z bbieber2 $
+-->
+<link rel="stylesheet" type="text/css" media="screen" href="/wdn/templates_3.0/css/all.css" />
+<link rel="stylesheet" type="text/css" media="print" href="/wdn/templates_3.0/css/print.css" />
+<script type="text/javascript" src="/wdn/templates_3.0/scripts/all.js"></script>
+<!--#include virtual="/wdn/templates_3.0/includes/browserspecifics.html" -->
+<!--#include virtual="/wdn/templates_3.0/includes/metanfavico.html" -->
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>UNL | Department | New Page</title>
+<!-- InstanceEndEditable -->
+<!-- InstanceBeginEditable name="head" -->
+<!-- Place optional header elements here -->
+<!-- InstanceEndEditable -->
+</head>
+<body class="fixed">
+<p class="skipnav"> <a class="skipnav" href="#maincontent">Skip Navigation</a> </p>
+<div id="wdn_wrapper">
+    <div id="header"> <a href="http://www.unl.edu/" title="UNL website"><img src="/wdn/templates_3.0/images/logo.png" alt="UNL graphic identifier" id="logo" /></a>
+        <h1>University of Nebraska&ndash;Lincoln</h1>
+        <!--#include virtual="/wdn/templates_3.0/includes/wdnTools.html" -->
+    </div>
+    <div id="wdn_navigation_bar">
+        <div id="breadcrumbs">
+            <!-- WDN: see glossary item 'breadcrumbs' -->
+            
+<!-- InstanceBeginEditable name="breadcrumbs" -->
+            <ul>
+                <li><a href="http://www.unl.edu/" title="University of Nebraska&ndash;Lincoln">UNL</a></li>
+                <li>Department</li>
+            </ul>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="wdn_navigation_wrapper">
+            <div id="navigation">
+<!-- InstanceBeginEditable name="navlinks" -->
+                <!--#include virtual="../sharedcode/navigation.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+        </div>
+    </div>
+    <div id="wdn_content_wrapper">
+        <div id="titlegraphic">
+<!-- InstanceBeginEditable name="titlegraphic" -->
+            <h1>Department</h1>
+            
+<!-- InstanceEndEditable -->
+</div>
+        <div id="pagetitle">
+<!-- InstanceBeginEditable name="pagetitle" -->
+ 
+<!-- InstanceEndEditable -->
+</div>
+        <div id="maincontent">
+            <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' -->
+            <div class="three_col left"> 
+<!-- InstanceBeginEditable name="maincontentarea" -->
+                <p>Place your content here.<br />
+                    Remember to validate your pages before publishing! Sample layouts are available through the <a href="http://wdn.unl.edu//">Web Developer Network</a>. <br />
+                    <a href="http://validator.unl.edu/check/referer">Check this page</a> </p>
+                
+<!-- InstanceEndEditable -->
+</div>
+            
+<!-- InstanceBeginEditable name="sharedcolumn" -->
+            <div class="col right">
+                <!--#include virtual="../sharedcode/sharedColumn.html" -->
+            </div>
+            
+<!-- InstanceEndEditable -->
+            <div class="clear"></div>
+            <!--#include virtual="/wdn/templates_3.0/includes/noscript.html" -->
+            <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->
+        </div>
+        <div id="footer">
+            <div id="footer_floater"></div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/feedback.html" -->
+            </div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="leftcollinks" -->
+                <!--#include virtual="../sharedcode/relatedLinks.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+<!-- InstanceBeginEditable name="contactinfo" -->
+                <!--#include virtual="../sharedcode/footerContactInfo.html" -->
+                
+<!-- InstanceEndEditable -->
+</div>
+            <div class="footer_col">
+                <!--#include virtual="/wdn/templates_3.0/includes/socialmediashare.html" -->
+            </div>
+            
+<!-- InstanceBeginEditable name="optionalfooter" -->
+ 
+<!-- InstanceEndEditable -->
+            <div id="wdn_copyright">
+<!-- InstanceBeginEditable name="footercontent" -->
+                <!--#include virtual="../sharedcode/footer.html" -->
+                
+<!-- InstanceEndEditable -->
+                <ul>
+                    <li><a href="http://validator.unl.edu/check/referer">W3C</a></li>
+                    <li><a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS</a></li>
+                </ul>
+                <!--#include virtual="/wdn/templates_3.0/includes/wdn.html" -->
+                <a href="http://www.unl.edu/" title="UNL Home" id="wdn_unl_wordmark"><img src="/wdn/templates_3.0/css/footer/images/wordmark.png" alt="UNL's wordmark" /></a> </div>
+        </div>
+    </div>
+    <div id="wdn_wrapper_footer"> </div>
+</div>
+</body>
+</html>
diff --git a/lib/docs/Archive_Tar/docs/Archive_Tar.txt b/lib/docs/Archive_Tar/docs/Archive_Tar.txt
new file mode 100644
index 00000000..623cafe6
--- /dev/null
+++ b/lib/docs/Archive_Tar/docs/Archive_Tar.txt
@@ -0,0 +1,461 @@
+Documentation for class Archive_Tar
+===================================
+Last update : 2001-08-15
+
+
+
+Overview :
+----------
+
+  The Archive_Tar class helps in creating and managing GNU TAR format
+  files compressed by GNU ZIP or not. 
+  The class offers basic functions like creating an archive, adding
+  files in the archive, extracting files from the archive and listing
+  the archive content. 
+  It also provide advanced functions that allow the adding and
+  extraction of files with path manipulation. 
+
+
+Sample :
+--------
+
+  // ----- Creating the object (uncompressed archive)
+  $tar_object = new Archive_Tar("tarname.tar");
+  $tar_object->setErrorHandling(PEAR_ERROR_PRINT);
+
+  // ----- Creating the archive
+  $v_list[0]="file.txt";
+  $v_list[1]="data/";
+  $v_list[2]="file.log";
+  $tar_object->create($v_list);
+
+  // ----- Adding files
+  $v_list[0]="dev/file.txt";
+  $v_list[1]="dev/data/";
+  $v_list[2]="log/file.log";
+  $tar_object->add($v_list);
+
+  // ----- Adding more files
+  $tar_object->add("release/newfile.log release/readme.txt");
+
+  // ----- Listing the content
+  if (($v_list  =  $tar_object->listContent()) != 0)
+    for ($i=0; $i<sizeof($v_list); $i++)
+    {
+      echo "Filename :'".$v_list[$i][filename]."'<br>";
+      echo " .size :'".$v_list[$i][size]."'<br>";
+      echo " .mtime :'".$v_list[$i][mtime]."' (".date("l dS of F Y h:i:s A", $v_list[$i][mtime]).")<br>";
+      echo " .mode :'".$v_list[$i][mode]."'<br>";
+      echo " .uid :'".$v_list[$i][uid]."'<br>";
+      echo " .gid :'".$v_list[$i][gid]."'<br>";
+      echo " .typeflag :'".$v_list[$i][typeflag]."'<br>";
+    }
+
+  // ----- Extracting the archive in directory "install"
+  $tar_object->extract("install");
+
+
+Public arguments :
+------------------
+
+None
+
+
+Public Methods :
+----------------
+
+Method : Archive_Tar($p_tarname, $compress = null)
+Description :
+  Archive_Tar Class constructor. This flavour of the constructor only
+  declare a new Archive_Tar object, identifying it by the name of the
+  tar file.
+  If the compress argument is set the tar will be read or created as a
+  gzip or bz2 compressed TAR file. 
+Arguments :
+  $p_tarname : A valid filename for the tar archive file.
+  $p_compress : can be null, 'gz' or 'bz2'. For
+                compatibility reason it can also be true. This
+                parameter indicates if gzip or bz2 compression
+                is required. 
+Return value :
+  The Archive_Tar object.
+Sample :
+  $tar_object = new Archive_Tar("tarname.tar");
+  $tar_object_compressed = new Archive_Tar("tarname.tgz", true);
+How it works :
+  Initialize the object.
+
+Method : create($p_filelist)
+Description :
+  This method creates the archive file and add the files / directories
+  that are listed in $p_filelist. 
+  If the file already exists and is writable, it is replaced by the
+  new tar. It is a create and not an add. If the file exists and is
+  read-only or is a directory it is not replaced. The method return
+  false and a PEAR error text. 
+  The $p_filelist parameter can be an array of string, each string
+  representing a filename or a directory name with their path if
+  needed. It can also be a single string with names separated by a
+  single blank. 
+  See also createModify() method for more details.
+Arguments :
+  $p_filelist : An array of filenames and directory names, or a single
+  string with names separated by a single blank space. 
+Return value :
+  true on success, false on error.
+Sample 1 :
+  $tar_object = new Archive_Tar("tarname.tar");
+  $tar_object->setErrorHandling(PEAR_ERROR_PRINT);  // Optional error handling
+  $v_list[0]="file.txt";
+  $v_list[1]="data/"; (Optional '/' at the end)
+  $v_list[2]="file.log";
+  $tar_object->create($v_list);
+Sample 2 :
+  $tar_object = new Archive_Tar("tarname.tar");
+  $tar_object->setErrorHandling(PEAR_ERROR_PRINT);  // Optional error handling
+  $tar_object->create("file.txt data/ file.log");
+How it works :
+  Just calling the createModify() method with the right parameters.
+
+Method : createModify($p_filelist, $p_add_dir, $p_remove_dir = "")
+Description :
+  This method creates the archive file and add the files / directories
+  that are listed in $p_filelist. 
+  If the file already exists and is writable, it is replaced by the
+  new tar. It is a create and not an add. If the file exists and is
+  read-only or is a directory it is not replaced. The method return
+  false and a PEAR error text. 
+  The $p_filelist parameter can be an array of string, each string
+  representing a filename or a directory name with their path if
+  needed. It can also be a single string with names separated by a
+  single blank. 
+  The path indicated in $p_remove_dir will be removed from the
+  memorized path of each file / directory listed when this path
+  exists. By default nothing is removed (empty path "") 
+  The path indicated in $p_add_dir will be added at the beginning of
+  the memorized path of each file / directory listed. However it can
+  be set to empty "". The adding of a path is done after the removing
+  of path. 
+  The path add/remove ability enables the user to prepare an archive
+  for extraction in a different path than the origin files are. 
+  See also addModify() method for file adding properties.
+Arguments :
+  $p_filelist : An array of filenames and directory names, or a single
+                string with names separated by a single blank space.
+  $p_add_dir : A string which contains a path to be added to the
+               memorized path of each element in the list. 
+  $p_remove_dir : A string which contains a path to be removed from
+                  the memorized path of each element in the list, when
+		  relevant.
+Return value :
+  true on success, false on error.
+Sample 1 :
+  $tar_object = new Archive_Tar("tarname.tar");
+  $tar_object->setErrorHandling(PEAR_ERROR_PRINT);  // Optional error handling
+  $v_list[0]="file.txt";
+  $v_list[1]="data/"; (Optional '/' at the end)
+  $v_list[2]="file.log";
+  $tar_object->createModify($v_list, "install");
+  // files are stored in the archive as :
+  //   install/file.txt
+  //   install/data
+  //   install/data/file1.txt
+  //   install/data/... all the files and sub-dirs of data/
+  //   install/file.log
+Sample 2 :
+  $tar_object = new Archive_Tar("tarname.tar");
+  $tar_object->setErrorHandling(PEAR_ERROR_PRINT);  // Optional error handling
+  $v_list[0]="dev/file.txt";
+  $v_list[1]="dev/data/"; (Optional '/' at the end)
+  $v_list[2]="log/file.log";
+  $tar_object->createModify($v_list, "install", "dev");
+  // files are stored in the archive as :
+  //   install/file.txt
+  //   install/data
+  //   install/data/file1.txt
+  //   install/data/... all the files and sub-dirs of data/
+  //   install/log/file.log
+How it works :
+  Open the file in write mode (erasing the existing one if one),
+  call the _addList() method for adding the files in an empty archive,
+  add the tar footer (512 bytes block), close the tar file.
+
+
+Method : addModify($p_filelist, $p_add_dir, $p_remove_dir="")
+Description :
+  This method add the files / directories listed in $p_filelist at the
+  end of the existing archive. If the archive does not yet exists it
+  is created.
+  The $p_filelist parameter can be an array of string, each string
+  representing a filename or a directory name with their path if
+  needed. It can also be a single string with names separated by a
+  single blank. 
+  The path indicated in $p_remove_dir will be removed from the
+  memorized path of each file / directory listed when this path
+  exists. By default nothing is removed (empty path "") 
+  The path indicated in $p_add_dir will be added at the beginning of
+  the memorized path of each file / directory listed. However it can
+  be set to empty "". The adding of a path is done after the removing
+  of path. 
+  The path add/remove ability enables the user to prepare an archive
+  for extraction in a different path than the origin files are. 
+  If a file/dir is already in the archive it will only be added at the
+  end of the archive. There is no update of the existing archived
+  file/dir. However while extracting the archive, the last file will
+  replace the first one. This results in a none optimization of the
+  archive size. 
+  If a file/dir does not exist the file/dir is ignored. However an
+  error text is send to PEAR error. 
+  If a file/dir is not readable the file/dir is ignored. However an
+  error text is send to PEAR error. 
+  If the resulting filename/dirname (after the add/remove option or
+  not) string is greater than 99 char, the file/dir is
+  ignored. However an error text is send to PEAR error. 
+Arguments :
+  $p_filelist : An array of filenames and directory names, or a single
+                string with names separated by a single blank space. 
+  $p_add_dir : A string which contains a path to be added to the
+               memorized path of each element in the list. 
+  $p_remove_dir : A string which contains a path to be removed from
+                  the memorized path of each element in the list, when
+		  relevant.
+Return value :
+  true on success, false on error.
+Sample 1 :
+  $tar_object = new Archive_Tar("tarname.tar");
+  [...]
+  $v_list[0]="dev/file.txt";
+  $v_list[1]="dev/data/"; (Optional '/' at the end)
+  $v_list[2]="log/file.log";
+  $tar_object->addModify($v_list, "install");
+  // files are stored in the archive as :
+  //   install/file.txt
+  //   install/data
+  //   install/data/file1.txt
+  //   install/data/... all the files and sub-dirs of data/
+  //   install/file.log
+Sample 2 :
+  $tar_object = new Archive_Tar("tarname.tar");
+  [...]
+  $v_list[0]="dev/file.txt";
+  $v_list[1]="dev/data/"; (Optional '/' at the end)
+  $v_list[2]="log/file.log";
+  $tar_object->addModify($v_list, "install", "dev");
+  // files are stored in the archive as :
+  //   install/file.txt
+  //   install/data
+  //   install/data/file1.txt
+  //   install/data/... all the files and sub-dirs of data/
+  //   install/log/file.log
+How it works :
+  If the archive does not exists it create it and add the files.
+  If the archive does exists and is not compressed, it open it, jump
+  before the last empty 512 bytes block (tar footer) and add the files
+  at this point.
+  If the archive does exists and is compressed, a temporary copy file
+  is created. This temporary file is then 'gzip' read block by block
+  until the last empty block. The new files are then added in the
+  compressed file.
+  The adding of files is done by going through the file/dir list,
+  adding files per files, in a recursive way through the
+  directory. Each time a path need to be added/removed it is done
+  before writing the file header in the archive.
+
+Method : add($p_filelist)
+Description :
+  This method add the files / directories listed in $p_filelist at the
+  end of the existing archive. If the archive does not yet exists it
+  is created. 
+  The $p_filelist parameter can be an array of string, each string
+  representing a filename or a directory name with their path if
+  needed. It can also be a single string with names separated by a
+  single blank. 
+  See addModify() method for details and limitations.
+Arguments :
+  $p_filelist : An array of filenames and directory names, or a single
+  string with names separated by a single blank space. 
+Return value :
+  true on success, false on error.
+Sample 1 :
+  $tar_object = new Archive_Tar("tarname.tar");
+  [...]
+  $v_list[0]="dev/file.txt";
+  $v_list[1]="dev/data/"; (Optional '/' at the end)
+  $v_list[2]="log/file.log";
+  $tar_object->add($v_list);
+Sample 2 :
+  $tar_object = new Archive_Tar("tarname.tgz", true);
+  [...]
+  $v_list[0]="dev/file.txt";
+  $v_list[1]="dev/data/"; (Optional '/' at the end)
+  $v_list[2]="log/file.log";
+  $tar_object->add($v_list);
+How it works :
+  Simply call the addModify() method with the right parameters.
+
+Method : addString($p_filename, $p_string)
+Description :
+  This method add a single string as a file at the
+  end of the existing archive. If the archive does not yet exists it
+  is created.
+Arguments :
+  $p_filename : A string which contains the full filename path
+                that will be associated with the string.
+  $p_string :   The content of the file added in the archive.
+Return value :
+  true on success, false on error.
+Sample 1 :
+  $v_archive = & new Archive_Tar($p_filename);
+  $v_archive->setErrorHandling(PEAR_ERROR_PRINT);
+  $v_result = $v_archive->addString('data/test.txt', 'This is the text of the string');
+
+
+Method : extract($p_path = "")
+Description :
+  This method extract all the content of the archive in the directory
+  indicated by $p_path.If $p_path is optional, if not set the archive
+  is extracted in the current directory. 
+  While extracting a file, if the directory path does not exists it is
+  created. 
+  See extractModify() for details and limitations.
+Arguments :
+  $p_path : Optional path where the files/dir need to by extracted.
+Return value :
+  true on success, false on error.
+Sample :
+  $tar_object = new Archive_Tar("tarname.tar");
+  $tar_object->extract();
+How it works :
+  Simply call the extractModify() method with appropriate parameters.
+
+Method : extractModify($p_path, $p_remove_path)
+Description :
+  This method extract all the content of the archive in the directory
+  indicated by $p_path. When relevant the memorized path of the
+  files/dir can be modified by removing the $p_remove_path path at the
+  beginning of the file/dir path. 
+  While extracting a file, if the directory path does not exists it is
+  created. 
+  While extracting a file, if the file already exists it is replaced
+  without looking for last modification date. 
+  While extracting a file, if the file already exists and is write
+  protected, the extraction is aborted. 
+  While extracting a file, if a directory with the same name already
+  exists, the extraction is aborted. 
+  While extracting a directory, if a file with the same name already
+  exists, the extraction is aborted. 
+  While extracting a file/directory if the destination directory exist
+  and is write protected, or does not exist but can not be created,
+  the extraction is aborted. 
+  If after extraction an extracted file does not show the correct
+  stored file size, the extraction is aborted. 
+  When the extraction is aborted, a PEAR error text is set and false
+  is returned. However the result can be a partial extraction that may
+  need to be manually cleaned. 
+Arguments :
+  $p_path : The path of the directory where the files/dir need to by
+            extracted. 
+  $p_remove_path : Part of the memorized path that can be removed if
+                   present at the beginning of the file/dir path. 
+Return value :
+  true on success, false on error.
+Sample :
+  // Imagine tarname.tar with files :
+  //   dev/data/file.txt
+  //   dev/data/log.txt
+  //   readme.txt
+  $tar_object = new Archive_Tar("tarname.tar");
+  $tar_object->extractModify("install", "dev");
+  // Files will be extracted there :
+  //   install/data/file.txt
+  //   install/data/log.txt
+  //   install/readme.txt
+How it works :
+  Open the archive and call a more generic function that can extract
+  only a part of the archive or all the archive. 
+  See extractList() method for more details.
+
+Method : extractInString($p_filename)
+Description :
+  This method extract from the archive one file identified by $p_filename.
+  The return value is a string with the file content, or NULL on error. 
+Arguments :
+  $p_filename : The path of the file to extract in a string. 
+Return value :
+  a string with the file content or NULL.
+Sample :
+  // Imagine tarname.tar with files :
+  //   dev/data/file.txt
+  //   dev/data/log.txt
+  //   dev/readme.txt
+  $v_archive = & new Archive_Tar('tarname.tar');
+  $v_archive->setErrorHandling(PEAR_ERROR_PRINT);
+  $v_string = $v_archive->extractInString('dev/readme.txt');
+  echo $v_string;
+
+Method : listContent()
+Description :
+  This method returns an array of arrays that describe each
+  file/directory present in the archive. 
+  The array is not sorted, so it show the position of the file in the
+  archive. 
+  The file informations are :
+    $file[filename] : Name and path of the file/dir.
+    $file[mode] : File permissions (result of fileperms())
+    $file[uid] : user id
+    $file[gid] : group id
+    $file[size] : filesize
+    $file[mtime] : Last modification time (result of filemtime())
+    $file[typeflag] : "" for file, "5" for directory
+Arguments :
+Return value :
+  An array of arrays or 0 on error.
+Sample :
+  $tar_object = new Archive_Tar("tarname.tar");
+  if (($v_list  =  $tar_object->listContent()) != 0)
+    for ($i=0; $i<sizeof($v_list); $i++)
+    {
+      echo "Filename :'".$v_list[$i][filename]."'<br>";
+      echo " .size :'".$v_list[$i][size]."'<br>";
+      echo " .mtime :'".$v_list[$i][mtime]."' (".
+           date("l dS of F Y h:i:s A", $v_list[$i][mtime]).")<br>";
+      echo " .mode :'".$v_list[$i][mode]."'<br>";
+      echo " .uid :'".$v_list[$i][uid]."'<br>";
+      echo " .gid :'".$v_list[$i][gid]."'<br>";
+      echo " .typeflag :'".$v_list[$i][typeflag]."'<br>";
+    }
+How it works :
+  Call the same function as an extract however with a flag to only go
+  through the archive without extracting the files. 
+
+Method : extractList($p_filelist, $p_path = "", $p_remove_path = "")
+Description :
+  This method extract from the archive only the files indicated in the
+  $p_filelist. These files are extracted in the current directory or
+  in the directory indicated by the optional $p_path parameter. 
+  If indicated the $p_remove_path can be used in the same way as it is
+  used in extractModify() method. 
+Arguments :
+  $p_filelist : An array of filenames and directory names, or a single
+                string with names separated by a single blank space. 
+  $p_path : The path of the directory where the files/dir need to by
+            extracted. 
+  $p_remove_path : Part of the memorized path that can be removed if
+                   present at the beginning of the file/dir path. 
+Return value :
+  true on success, false on error.
+Sample :
+  // Imagine tarname.tar with files :
+  //   dev/data/file.txt
+  //   dev/data/log.txt
+  //   readme.txt
+  $tar_object = new Archive_Tar("tarname.tar");
+  $tar_object->extractList("dev/data/file.txt readme.txt", "install",
+                           "dev");
+  // Files will be extracted there :
+  //   install/data/file.txt
+  //   install/readme.txt
+How it works :
+  Go through the archive and extract only the files present in the
+  list. 
+
diff --git a/lib/docs/Cache_Lite/Cache/LICENSE b/lib/docs/Cache_Lite/Cache/LICENSE
new file mode 100644
index 00000000..27950e8d
--- /dev/null
+++ b/lib/docs/Cache_Lite/Cache/LICENSE
@@ -0,0 +1,458 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
diff --git a/lib/docs/Cache_Lite/Cache/TODO b/lib/docs/Cache_Lite/Cache/TODO
new file mode 100644
index 00000000..e51a0481
--- /dev/null
+++ b/lib/docs/Cache_Lite/Cache/TODO
@@ -0,0 +1,46 @@
+
+Patrick O'Lone suggests the following idea which sounds interesting to
+add as an optional mode of Cache_Lite class. 
+(still not tested in the Cache_Lite context)
+
+-------------------------------------------------------------------------
+If you use the flags:
+
+ignore_user_abort(true);
+
+$fd = dio_open($szFilename, O_CREATE | O_EXCL | O_TRUNC | O_WRONLY,
+0644);
+if (is_resource($fd)) {
+
+   dio_fcntl($fd, F_SETLKW, array('type' => F_WRLCK));
+   dio_write($fd, $szBuffer);
+   dio_fcntl($fd, F_SETLK, array('type' => F_UNLCK));
+   dio_close($fd);
+
+}
+
+ignore_user_abort(false);
+
+Only the first process will attempt to create a file. Additional
+processes will see that a file already exists (at the system level), and
+will fail. Another thing to note is that the file descriptor must be
+opened using dio_open(), and certain features, like fgets() won't work
+with it. If your just doing a raw write, dio_write() should be just
+fine. The dio_read() function should be used like:
+
+$fd = dio_open($szFilename, O_RDONLY|O_NONBLOCK, 0644);
+if (is_resource($fd)) {
+
+   dio_fcntl($fd, F_SETLKW, array('type' => F_RDLCK));
+   $szBuffer = dio_read($fd, filesize($szFilename));
+   dio_fcntl($fd, F_SETLK, array('type' => F_UNLCK));
+   dio_close($fd);
+
+}
+
+You still use locking to ensure that a write process can finish before
+another attempts to read the file. We also set non-blocking mode in read
+mode so that multiple readers can access the same resource at the same
+time. NOTE: Direct I/O support must be compiled into PHP for these
+features to work (--enable-dio).
+-------------------------------------------------------------------------
diff --git a/lib/docs/Cache_Lite/Cache/docs/examples b/lib/docs/Cache_Lite/Cache/docs/examples
new file mode 100644
index 00000000..ad98c6b3
--- /dev/null
+++ b/lib/docs/Cache_Lite/Cache/docs/examples
@@ -0,0 +1,254 @@
+A few examples of Cache_Lite using :
+------------------------------------
+
+>>> Basic one :
+
+<?php
+
+// Include the package
+require_once('Cache/Lite.php');
+
+// Set a id for this cache
+$id = '123';
+
+// Set a few options
+$options = array(
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 3600
+);
+
+// Create a Cache_Lite object
+$Cache_Lite = new Cache_Lite($options);
+
+// Test if thereis a valide cache for this id
+if ($data = $Cache_Lite->get($id)) {
+
+    // Cache hit !
+    // Content is in $data
+    // (...)
+
+} else { // No valid cache found (you have to make the page)
+
+    // Cache miss !
+    // Put in $data datas to put in cache
+    // (...)
+    $Cache_Lite->save($data);
+
+}
+
+?>
+
+
+>>> Usage with blocks
+(You can use Cache_Lite for caching blocks and not the whole page)
+
+<?php
+
+require_once('Cache/Lite.php');
+
+$options = array(
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 3600
+);
+
+// Create a Cache_Lite object
+$Cache_Lite = new Cache_Lite($options);
+
+if ($data = $Cache_Lite->get('block1')) {
+    echo($data);
+} else { 
+    $data = 'Data of the block 1';
+    $Cache_Lite->save($data);
+}
+
+echo('<br><br>Non cached line !<br><br>');
+
+if ($data = $Cache_Lite->get('block2')) {
+    echo($data);
+} else { 
+    $data = 'Data of the block 2';
+    $Cache_Lite->save($data);
+}
+
+?>
+
+
+A few examples of Cache_Lite_Output using :
+-------------------------------------------
+
+>>> Basic one :
+
+<?php
+
+require_once('Cache/Lite/Output.php');
+
+$options = array(
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 10
+);
+
+$cache = new Cache_Lite_Output($options);
+
+if (!($cache->start('123'))) {
+    // Cache missed...
+    for($i=0;$i<1000;$i++) { // Making of the page...
+        echo('0123456789');
+    }
+    $cache->end();
+}
+
+?>
+
+>>> Usage with blocks :
+(You can use Cache_Lite_Output for caching blocks and not the whole page)
+
+<?php
+
+require_once('Cache/Lite/Output.php');
+
+$options = array(
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 10
+);
+
+$cache = new Cache_Lite_Output($options);
+
+if (!($cache->start('block1'))) {
+    // Cache missed...
+    echo('Data of the block 1 !<br>');
+    $cache->end();
+}
+
+echo('<br><br>Non cached line !<br><br>');
+
+if (!($cache->start('block2'))) {
+    // Cache missed...
+    echo('Data of the block 2 !<br>');
+    $cache->end();
+}
+
+
+A few examples of Cache_Lite_Function using :
+---------------------------------------------
+
+>>> With function :
+
+<?php
+
+require_once('Cache/Lite/Function.php');
+
+$options = array(
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 10
+);
+
+$cache = new Cache_Lite_Function($options);
+
+$cache->call('function_to_bench', 12, 45);
+
+function function_to_bench($arg1, $arg2) 
+{
+    echo "This is the output of the function function_to_bench($arg1, $arg2) !<br>";
+    return "This is the result of the function function_to_bench($arg1, $arg2) !<br>";
+}
+
+?>
+
+>>> With method :
+
+<?php
+
+require_once('Cache/Lite/Function.php');
+
+$options = array(
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 10
+);
+
+$cache = new Cache_Lite_Function($options);
+
+$obj = new bench();
+$obj->test = 666;
+
+$cache->call('obj->method_to_bench', 12, 45);
+
+class bench
+{
+    var $test;
+
+    function method_to_bench($arg1, $arg2)
+    {
+        echo "\$obj->test = $this->test and this is the output of the method \$obj->method_to_bench($arg1, $arg2) !<br>";
+        return "\$obj->test = $this->test and this is the result of the method \$obj->method_to_bench($arg1, $arg2) !<br>";        
+    }
+    
+}
+
+?>
+
+>>> With static method :
+
+<?php
+
+require_once('Cache/Lite/Function.php');
+
+$options = array(
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 10
+);
+
+$cache = new Cache_Lite_Function($options);
+
+$cache->call('bench::static_method_to_bench', 12, 45);
+
+class bench
+{
+    var $test;
+
+    function static_method_to_bench($arg1, $arg2) {
+        echo "This is the output of the function static_method_to_bench($arg1, $arg2) !<br>";
+        return "This is the result of the function static_method_to_bench($arg1, $arg2) !<br>";
+    }
+}
+
+?>
+
+>>> IMPORTANT :
+
+If you try to use Cache_Lite_Function with $this object ($cache->call('this->method',...) 
+for example), have a look first at :
+
+http://pear.php.net/bugs/bug.php?id=660
+
+
+A few examples of Cache_Lite_File using :
+-----------------------------------------
+
+<?php
+
+$options = array(
+    'cacheDir' => '/tmp/',
+    'masterFile' => '/home/web/config.xml'
+);
+$cache = new Cache_Lite_File($options);
+
+// Set a id for this cache
+$id = '123';
+
+if ($data = $cache->get($id)) {
+
+    // Cache hit !
+    // Content is in $data
+    // (...)
+
+} else { // No valid cache found (you have to make the page)
+
+    // Cache miss !
+    // Put in $data datas to put in cache
+    // (...)
+    $cache->save($data);
+
+}
+
+
+?>
diff --git a/lib/docs/Cache_Lite/Cache/docs/technical b/lib/docs/Cache_Lite/Cache/docs/technical
new file mode 100644
index 00000000..790696c8
--- /dev/null
+++ b/lib/docs/Cache_Lite/Cache/docs/technical
@@ -0,0 +1,28 @@
+Technical choices for Cache_Lite...
+-----------------------------------
+
+To begin, the main goals of Cache_Lite :
+- performances
+- safe use (even on very high traffic or with NFS (file locking doesn't work
+            with NFS))
+- flexibility (can be used by the end user or as a part of a larger script)
+
+
+For speed reasons, it has been decided to focus on the file container (the 
+faster one). So, cache is only stored in files. The class is optimized for that. 
+If you want to use a different cache container, have a look to PEAR/Cache.
+
+For speed reasons too, the class 'Cache_Lite' has do be independant (so no 
+'require_once' at all in 'Cache_Lite.php'). But, a conditional include_once
+is allowed. For example, when an error is detected, the class include dynamicaly
+the PEAR base class 'PEAR.php' to be able to use PEAR::raiseError(). But, in
+most cases, PEAR.php isn't included.
+
+For the second goal (safe use), there is three (optional) mecanisms :
+- File Locking : seems to work fine (but not with distributed file system
+                 like NFS...)
+- WriteControl : the cache is read and compared just after being stored
+                 (efficient but not perfect)
+- ReadControl : a control key (crc32(), md5() ou strlen()) is embeded is the 
+                cache file and compared just after reading (the most efficient
+                but the slowest)
diff --git a/lib/docs/Cache_Lite/Cache/tests/readme b/lib/docs/Cache_Lite/Cache/tests/readme
new file mode 100644
index 00000000..6160fe2b
--- /dev/null
+++ b/lib/docs/Cache_Lite/Cache/tests/readme
@@ -0,0 +1,17 @@
+Cache_Lite is perfs oriented. So before commiting, please bench your patch !
+
+To bench Cache_Lite, I use the tool 'ab' (distributed with apache).
+
+(for example)
+/usr/sbin/ab -c 10 -n 1000 http://127.0.0.1/ [...] /Cache_Lite/tests/bench.php
+
+In the output of 'ab', most important things are :
+- Failed requests: (must be 0 ! If not, don't commit !)
+- Requests per second:    XXX [#/sec] (mean)
+
+
+For testing if the cache is ok or not, you can use the script 'test.php', it 
+will write if the cache has been hit or missed...
+
+
+Fabien (fab@php.net)
\ No newline at end of file
diff --git a/lib/docs/HTTP_Request2/HTTP/docs/examples/upload-rapidshare.php b/lib/docs/HTTP_Request2/HTTP/docs/examples/upload-rapidshare.php
new file mode 100644
index 00000000..9773a94c
--- /dev/null
+++ b/lib/docs/HTTP_Request2/HTTP/docs/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 00000000..104de896
--- /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 00000000..d2725ba5
--- /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/PEAR/INSTALL b/lib/docs/PEAR/INSTALL
new file mode 100644
index 00000000..1c60b75b
--- /dev/null
+++ b/lib/docs/PEAR/INSTALL
@@ -0,0 +1,53 @@
+PEAR - The PEAR Installer
+=========================
+Installing the PEAR Installer.
+
+You should install PEAR on a local development machine first.  Installing
+PEAR on a remote production machine should only be done after you are
+familiar with PEAR and have tested code using PEAR on your development
+machine.
+
+There are two methods of installing PEAR
+ - PEAR bundled in PHP
+ - go-pear
+
+We will first examine how to install PEAR that is bundled with PHP.
+
+Microsoft Windows
+=================
+If you are running PHP 5.2.0 or newer, simply download and
+run the windows installer (.msi) and PEAR can be automatically
+installed.
+
+Otherwise, for older PHP versions, download the .zip of windows,
+there is a script included with your PHP distribution that is called
+"go-pear".  You must open a command box in order to run it.  Click
+"start" then click "Run..." and type "cmd.exe" to open a command box.
+Use "cd" to change directory to the location of PHP where you unzipped it,
+and run the go-pear command.
+
+Unix
+====
+make sure you have enabled default extensions, and if you want faster
+downloads, enable the zlib extension.  You must also enable the CLI
+SAPI with the --enable-cli extension directive.  After this, simply run:
+
+make install-pear
+
+and PEAR will be automatically configured for you.
+
+go-pear
+=======
+For users who cannot perform the above steps, or who wish to obtain the
+latest PEAR with a slightly higher risk of failure, use go-pear.  go-pear
+is obtained by downloading http://go-pear.org and saving it as go-pear.php.
+After downloading, simply run "php go-pear.php" or open it in a web browser
+(windows only) to download and install PEAR.
+
+You can always ask general installation questions on pear-general@lists.php.net,
+a public mailing list devoted to support for PEAR packages and installation-
+related issues.
+
+Happy PHPing, we hope PEAR will be a great tool for your development work!
+
+$Id: INSTALL 220345 2006-09-22 03:31:36Z cellog $
\ No newline at end of file
diff --git a/lib/docs/PEAR/LICENSE b/lib/docs/PEAR/LICENSE
new file mode 100644
index 00000000..a00a2421
--- /dev/null
+++ b/lib/docs/PEAR/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 1997-2009,
+ Stig Bakken <ssb@php.net>,
+ Gregory Beaver <cellog@php.net>,
+ Helgi Þormar Þorbjörnsson <helgi@php.net>,
+ Tomas V.V.Cox <cox@idecnet.com>,
+ Martin Jansen <mj@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.
+
+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.
diff --git a/lib/docs/PEAR/README b/lib/docs/PEAR/README
new file mode 100644
index 00000000..59ead1d0
--- /dev/null
+++ b/lib/docs/PEAR/README
@@ -0,0 +1,32 @@
+PEAR - The PEAR Installer
+=========================
+
+What is the PEAR Installer?  What is PEAR?
+
+PEAR is the PHP Extension and Application Repository, found at
+http://pear.php.net.  The PEAR Installer is this software, which
+contains executable files and PHP code that is used to download
+and install PEAR code from pear.php.net.
+
+PEAR contains useful software libraries and applications such as
+MDB2 (database abstraction), HTML_QuickForm (HTML forms management),
+PhpDocumentor (auto-documentation generator), DB_DataObject
+(Data Access Abstraction), and many hundreds more.  Browse all
+available packages at http://pear.php.net, the list is constantly
+growing and updating to reflect improvements in the PHP language.
+
+DOCUMENTATION
+=============
+
+Documentation for PEAR can be found at http://pear.php.net/manual/.
+Installation documentation can be found in the INSTALL file included
+in this tarball.
+
+WARNING: DO NOT RUN PEAR WITHOUT INSTALLING IT - if you downloaded this
+tarball manually, you MUST install it.  Read the instructions in INSTALL
+prior to use.
+
+
+Happy PHPing, we hope PEAR will be a great tool for your development work!
+
+$Id: README 220345 2006-09-22 03:31:36Z cellog $
\ No newline at end of file
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 00000000..921d1a08
--- /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 00000000..02f768b8
--- /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/Structures_Graph/docs/generate.sh b/lib/docs/Structures_Graph/docs/generate.sh
new file mode 100644
index 00000000..173d87c1
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/generate.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+(cd ..; tar czf docs/arch.tgz "{arch}")
+rm -Rf "../{arch}"
+rm -Rf ./html
+mkdir -p ./html
+phpdoc --directory ../Structures,./tutorials --target ./html --title "Structures_Graph Documentation" --output "HTML:frames" --defaultpackagename structures_graph --defaultcategoryname structures --pear 
+(cd ..; tar --absolute-names -xzf docs/arch.tgz)
+#rm arch.tgz
diff --git a/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph.html b/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph.html
new file mode 100644
index 00000000..f73bb6cf
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph.html
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Docs For Class Structures_Graph</title>
+			<link rel="stylesheet" href="../media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="page-body">			
+<h2 class="class-name">Class Structures_Graph</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+	<div class="info-box-title">Description</div>
+	<div class="nav-bar">
+					<span class="disabled">Description</span> |
+															<a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+						
+			</div>
+	<div class="info-box-body">
+		<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The Structures_Graph class represents a graph data structure.</p>
+<p class="description"><p>A Graph is a data structure composed by a set of nodes, connected by arcs.  Graphs may either be directed or undirected. In a directed graph, arcs are  directional, and can be traveled only one way. In an undirected graph, arcs  are bidirectional, and can be traveled both ways.</p></p>
+	<ul class="tags">
+				<li><span class="field">copyright:</span> (c) 2004 by S�rgio Carvalho</li>
+				<li><span class="field">author:</span> S�rgio Carvalho &lt;<a href="mailto:sergio.carvalho@portugalmail.com">mailto:sergio.carvalho@portugalmail.com</a>&gt;</li>
+			</ul>
+		<p class="notes">
+			Located in <a class="field" href="_Structures_Graph_php.html">/Structures/Graph.php</a> (line <span class="field">56</span>)
+		</p>
+		
+				
+		<pre></pre>
+	
+			</div>
+</div>
+
+
+
+	<a name="sec-method-summary"></a>
+	<div class="info-box">
+		<div class="info-box-title">Method Summary</span></div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+									<span class="disabled">Methods</span> (<a href="#sec-methods">details</a>)
+		</div>
+		<div class="info-box-body">			
+			<div class="method-summary">
+								
+				<div class="method-definition">
+											<span class="method-result">Structures_Graph</span>
+										<a href="#Structures_Graph" title="details" class="method-name">Structures_Graph</a>
+											([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$directed</span> = <span class="var-default">true</span>])
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">void</span>
+										<a href="#addNode" title="details" class="method-name">addNode</a>
+											(<span class="var-type"><a href="../Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a></span>&nbsp;<span class="var-name">&$newNode</span>)
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">array</span>
+										<a href="#getNodes" title="details" class="method-name">&amp;getNodes</a>
+										()
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">boolean</span>
+										<a href="#isDirected" title="details" class="method-name">isDirected</a>
+										()
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">void</span>
+										<a href="#removeNode" title="details" class="method-name">removeNode</a>
+											(<span class="var-type"><a href="../Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a></span>&nbsp;<span class="var-name">&$node</span>)
+									</div>
+							</div>
+		</div>
+	</div>		
+
+	
+	<a name="sec-methods"></a>
+	<div class="info-box">
+		<div class="info-box-title">Methods</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+													<a href="#sec-method-summary">Methods</a> (<span class="disabled">details</span>)
+						
+		</div>
+		<div class="info-box-body">
+			<A NAME='method_detail'></A>
+<a name="methodStructures_Graph" id="Structures_Graph"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">Constructor Structures_Graph</span> (line <span class="line-number">76</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Constructor</p>
+	<ul class="tags">
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">Structures_Graph</span>
+		<span class="method-name">
+			Structures_Graph
+		</span>
+					([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$directed</span> = <span class="var-default">true</span>])
+			</div>
+	
+			<ul class="parameters">
+					<li>
+				<span class="var-type">boolean</span>
+				<span class="var-name">$directed</span><span class="var-description">: Set to true if the graph is directed. Set to false if it is not directed. (Optional, defaults to true)</span>			</li>
+				</ul>
+		
+		
+	</div>
+<a name="methodaddNode" id="addNode"><!-- --></a>
+<div class="oddrow">
+	
+	<div class="method-header">
+		<span class="method-title">addNode</span> (line <span class="line-number">102</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Add a Node to the Graph</p>
+	<ul class="tags">
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">void</span>
+		<span class="method-name">
+			addNode
+		</span>
+					(<span class="var-type"><a href="../Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a></span>&nbsp;<span class="var-name">&$newNode</span>)
+			</div>
+	
+			<ul class="parameters">
+					<li>
+				<span class="var-type"><a href="../Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a></span>
+				<span class="var-name">&$newNode</span><span class="var-description">: The node to be added.</span>			</li>
+				</ul>
+		
+		
+	</div>
+<a name="methodgetNodes" id="getNodes"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">getNodes</span> (line <span class="line-number">151</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Return the node set, in no particular order. For ordered node sets, use a Graph Manipulator insted.</p>
+	<ul class="tags">
+				<li><span class="field">return:</span> The set of nodes in this graph</li>
+				<li><span class="field">see:</span> <a href="../Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html">Structures_Graph_Manipulator_TopologicalSorter</a></li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">array</span>
+		<span class="method-name">
+			&amp;getNodes
+		</span>
+				()
+			</div>
+	
+		
+		
+	</div>
+<a name="methodisDirected" id="isDirected"><!-- --></a>
+<div class="oddrow">
+	
+	<div class="method-header">
+		<span class="method-title">isDirected</span> (line <span class="line-number">89</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Return true if a graph is directed</p>
+	<ul class="tags">
+				<li><span class="field">return:</span> true if the graph is directed</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">boolean</span>
+		<span class="method-name">
+			isDirected
+		</span>
+				()
+			</div>
+	
+		
+		
+	</div>
+<a name="methodremoveNode" id="removeNode"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">removeNode</span> (line <span class="line-number">138</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Remove a Node from the Graph</p>
+	<ul class="tags">
+				<li><span class="field">access:</span> public</li>
+				<li><span class="field">todo:</span> This is unimplemented</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">void</span>
+		<span class="method-name">
+			removeNode
+		</span>
+					(<span class="var-type"><a href="../Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a></span>&nbsp;<span class="var-name">&$node</span>)
+			</div>
+	
+			<ul class="parameters">
+					<li>
+				<span class="var-type"><a href="../Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a></span>
+				<span class="var-name">&$node</span><span class="var-description">: The node to be removed from the graph</span>			</li>
+				</ul>
+		
+		
+	</div>
+						
+		</div>
+	</div>
+	
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:28 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</div></body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html b/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html
new file mode 100644
index 00000000..85e5054b
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Docs For Class Structures_Graph_Manipulator_AcyclicTest</title>
+			<link rel="stylesheet" href="../media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="page-body">			
+<h2 class="class-name">Class Structures_Graph_Manipulator_AcyclicTest</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+	<div class="info-box-title">Description</div>
+	<div class="nav-bar">
+					<span class="disabled">Description</span> |
+															<a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+						
+			</div>
+	<div class="info-box-body">
+		<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The Structures_Graph_Manipulator_AcyclicTest is a graph manipulator  which tests whether a graph contains a cycle.</p>
+<p class="description"><p>The definition of an acyclic graph used in this manipulator is that of a  DAG. The graph must be directed, or else it is considered cyclic, even when  there are no arcs.</p></p>
+	<ul class="tags">
+				<li><span class="field">copyright:</span> (c) 2004 by S�rgio Carvalho</li>
+				<li><span class="field">author:</span> S�rgio Carvalho &lt;<a href="mailto:sergio.carvalho@portugalmail.com">mailto:sergio.carvalho@portugalmail.com</a>&gt;</li>
+			</ul>
+		<p class="notes">
+			Located in <a class="field" href="_Structures_Graph_Manipulator_AcyclicTest_php.html">/Structures/Graph/Manipulator/AcyclicTest.php</a> (line <span class="field">55</span>)
+		</p>
+		
+				
+		<pre></pre>
+	
+			</div>
+</div>
+
+
+
+	<a name="sec-method-summary"></a>
+	<div class="info-box">
+		<div class="info-box-title">Method Summary</span></div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+									<span class="disabled">Methods</span> (<a href="#sec-methods">details</a>)
+		</div>
+		<div class="info-box-body">			
+			<div class="method-summary">
+								
+				<div class="method-definition">
+											<span class="method-result">boolean</span>
+										<a href="#isAcyclic" title="details" class="method-name">isAcyclic</a>
+											(<span class="var-type">mixed</span>&nbsp;<span class="var-name">&$graph</span>)
+									</div>
+							</div>
+		</div>
+	</div>		
+
+	
+	<a name="sec-methods"></a>
+	<div class="info-box">
+		<div class="info-box-title">Methods</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+													<a href="#sec-method-summary">Methods</a> (<span class="disabled">details</span>)
+						
+		</div>
+		<div class="info-box-body">
+			<A NAME='method_detail'></A>
+<a name="methodisAcyclic" id="isAcyclic"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">isAcyclic</span> (line <span class="line-number">126</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">isAcyclic returns true if a graph contains no cycles, false otherwise.</p>
+	<ul class="tags">
+				<li><span class="field">return:</span> true iff graph is acyclic</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">boolean</span>
+		<span class="method-name">
+			isAcyclic
+		</span>
+					(<span class="var-type">mixed</span>&nbsp;<span class="var-name">&$graph</span>)
+			</div>
+	
+		
+		
+	</div>
+						
+		</div>
+	</div>
+	
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:28 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</div></body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html b/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html
new file mode 100644
index 00000000..e13f4957
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Docs For Class Structures_Graph_Manipulator_TopologicalSorter</title>
+			<link rel="stylesheet" href="../media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="page-body">			
+<h2 class="class-name">Class Structures_Graph_Manipulator_TopologicalSorter</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+	<div class="info-box-title">Description</div>
+	<div class="nav-bar">
+					<span class="disabled">Description</span> |
+															<a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+						
+			</div>
+	<div class="info-box-body">
+		<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The Structures_Graph_Manipulator_TopologicalSorter is a manipulator  which is able to return the set of nodes in a graph, sorted by topological  order.</p>
+<p class="description"><p>A graph may only be sorted topologically iff it's a DAG. You can test it  with the Structures_Graph_Manipulator_AcyclicTest.</p></p>
+	<ul class="tags">
+				<li><span class="field">see:</span> <a href="../Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html">Structures_Graph_Manipulator_AcyclicTest</a></li>
+				<li><span class="field">copyright:</span> (c) 2004 by S�rgio Carvalho</li>
+				<li><span class="field">author:</span> S�rgio Carvalho &lt;<a href="mailto:sergio.carvalho@portugalmail.com">mailto:sergio.carvalho@portugalmail.com</a>&gt;</li>
+			</ul>
+		<p class="notes">
+			Located in <a class="field" href="_Structures_Graph_Manipulator_TopologicalSorter_php.html">/Structures/Graph/Manipulator/TopologicalSorter.php</a> (line <span class="field">58</span>)
+		</p>
+		
+				
+		<pre></pre>
+	
+			</div>
+</div>
+
+
+
+	<a name="sec-method-summary"></a>
+	<div class="info-box">
+		<div class="info-box-title">Method Summary</span></div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+									<span class="disabled">Methods</span> (<a href="#sec-methods">details</a>)
+		</div>
+		<div class="info-box-body">			
+			<div class="method-summary">
+								
+				<div class="method-definition">
+											<span class="method-result">array</span>
+										<a href="#sort" title="details" class="method-name">sort</a>
+											(<span class="var-type">mixed</span>&nbsp;<span class="var-name">&$graph</span>)
+									</div>
+							</div>
+		</div>
+	</div>		
+
+	
+	<a name="sec-methods"></a>
+	<div class="info-box">
+		<div class="info-box-title">Methods</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+													<a href="#sec-method-summary">Methods</a> (<span class="disabled">details</span>)
+						
+		</div>
+		<div class="info-box-body">
+			<A NAME='method_detail'></A>
+<a name="methodsort" id="sort"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">sort</span> (line <span class="line-number">133</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">sort returns the graph's nodes, sorted by topological order.</p>
+<p class="description"><p>The result is an array with  as many entries as topological levels. Each entry in this array is an array of nodes within  the given topological level.</p></p>
+	<ul class="tags">
+				<li><span class="field">return:</span> The graph's nodes, sorted by topological order.</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">array</span>
+		<span class="method-name">
+			sort
+		</span>
+					(<span class="var-type">mixed</span>&nbsp;<span class="var-name">&$graph</span>)
+			</div>
+	
+		
+		
+	</div>
+						
+		</div>
+	</div>
+	
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:29 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</div></body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Node.html b/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Node.html
new file mode 100644
index 00000000..eabc923a
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/Structures_Graph/Structures_Graph_Node.html
@@ -0,0 +1,549 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Docs For Class Structures_Graph_Node</title>
+			<link rel="stylesheet" href="../media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="page-body">			
+<h2 class="class-name">Class Structures_Graph_Node</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+	<div class="info-box-title">Description</div>
+	<div class="nav-bar">
+					<span class="disabled">Description</span> |
+															<a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+						
+			</div>
+	<div class="info-box-body">
+		<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The Structures_Graph_Node class represents a Node that can be member of a  graph node set.</p>
+<p class="description"><p>A graph node can contain data. Under this API, the node contains default data,  and key index data. It behaves, thus, both as a regular data node, and as a  dictionary (or associative array) node.</p><p>Regular data is accessed via getData and setData. Key indexed data is accessed  via getMetadata and setMetadata.</p></p>
+	<ul class="tags">
+				<li><span class="field">copyright:</span> (c) 2004 by S�rgio Carvalho</li>
+				<li><span class="field">author:</span> S�rgio Carvalho &lt;<a href="mailto:sergio.carvalho@portugalmail.com">mailto:sergio.carvalho@portugalmail.com</a>&gt;</li>
+			</ul>
+		<p class="notes">
+			Located in <a class="field" href="_Structures_Graph_Node_php.html">/Structures/Graph/Node.php</a> (line <span class="field">57</span>)
+		</p>
+		
+				
+		<pre></pre>
+	
+			</div>
+</div>
+
+
+
+	<a name="sec-method-summary"></a>
+	<div class="info-box">
+		<div class="info-box-title">Method Summary</span></div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+									<span class="disabled">Methods</span> (<a href="#sec-methods">details</a>)
+		</div>
+		<div class="info-box-body">			
+			<div class="method-summary">
+								
+				<div class="method-definition">
+											<span class="method-result">Structures_Graph_Node</span>
+										<a href="#Structures_Graph_Node" title="details" class="method-name">Structures_Graph_Node</a>
+										()
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">boolean</span>
+										<a href="#connectsTo" title="details" class="method-name">connectsTo</a>
+											(<span class="var-type">mixed</span>&nbsp;<span class="var-name">&$target</span>)
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">void</span>
+										<a href="#connectTo" title="details" class="method-name">connectTo</a>
+											(<span class="var-type"><a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a></span>&nbsp;<span class="var-name">&$destinationNode</span>)
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">mixed</span>
+										<a href="#getData" title="details" class="method-name">&amp;getData</a>
+										()
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result"><a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a></span>
+										<a href="#getGraph" title="details" class="method-name">&amp;getGraph</a>
+										()
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">mixed</span>
+										<a href="#getMetadata" title="details" class="method-name">&amp;getMetadata</a>
+											(<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$nullIfNonexistent</span> = <span class="var-default">false</span>])
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">array</span>
+										<a href="#getNeighbours" title="details" class="method-name">getNeighbours</a>
+										()
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">integer</span>
+										<a href="#inDegree" title="details" class="method-name">inDegree</a>
+										()
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">boolean</span>
+										<a href="#metadataKeyExists" title="details" class="method-name">metadataKeyExists</a>
+											(<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>)
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">integer</span>
+										<a href="#outDegree" title="details" class="method-name">outDegree</a>
+										()
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">mixed</span>
+										<a href="#setData" title="details" class="method-name">setData</a>
+											(<span class="var-type">mixed</span>&nbsp;<span class="var-name">$data</span>)
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">void</span>
+										<a href="#setGraph" title="details" class="method-name">setGraph</a>
+											(<span class="var-type"><a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a></span>&nbsp;<span class="var-name">&$graph</span>)
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">void</span>
+										<a href="#setMetadata" title="details" class="method-name">setMetadata</a>
+											(<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">mixed</span>&nbsp;<span class="var-name">$data</span>)
+									</div>
+								
+				<div class="method-definition">
+											<span class="method-result">void</span>
+										<a href="#unsetMetadata" title="details" class="method-name">unsetMetadata</a>
+											(<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>)
+									</div>
+							</div>
+		</div>
+	</div>		
+
+	
+	<a name="sec-methods"></a>
+	<div class="info-box">
+		<div class="info-box-title">Methods</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+													<a href="#sec-method-summary">Methods</a> (<span class="disabled">details</span>)
+						
+		</div>
+		<div class="info-box-body">
+			<A NAME='method_detail'></A>
+<a name="methodStructures_Graph_Node" id="Structures_Graph_Node"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">Constructor Structures_Graph_Node</span> (line <span class="line-number">78</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Constructor</p>
+	<ul class="tags">
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">Structures_Graph_Node</span>
+		<span class="method-name">
+			Structures_Graph_Node
+		</span>
+				()
+			</div>
+	
+		
+		
+	</div>
+<a name="methodconnectsTo" id="connectsTo"><!-- --></a>
+<div class="oddrow">
+	
+	<div class="method-header">
+		<span class="method-title">connectsTo</span> (line <span class="line-number">275</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Test wether this node has an arc to the target node</p>
+	<ul class="tags">
+				<li><span class="field">return:</span> True if the two nodes are connected</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">boolean</span>
+		<span class="method-name">
+			connectsTo
+		</span>
+					(<span class="var-type">mixed</span>&nbsp;<span class="var-name">&$target</span>)
+			</div>
+	
+		
+		
+	</div>
+<a name="methodconnectTo" id="connectTo"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">connectTo</span> (line <span class="line-number">236</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Connect this node to another one.</p>
+<p class="description"><p>If the graph is not directed, the reverse arc, connecting $destinationNode to $this is also created.</p></p>
+	<ul class="tags">
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">void</span>
+		<span class="method-name">
+			connectTo
+		</span>
+					(<span class="var-type"><a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a></span>&nbsp;<span class="var-name">&$destinationNode</span>)
+			</div>
+	
+			<ul class="parameters">
+					<li>
+				<span class="var-type"><a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a></span>
+				<span class="var-name">&$destinationNode</span><span class="var-description">: Node to connect to</span>			</li>
+				</ul>
+		
+		
+	</div>
+<a name="methodgetData" id="getData"><!-- --></a>
+<div class="oddrow">
+	
+	<div class="method-header">
+		<span class="method-title">getData</span> (line <span class="line-number">119</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Node data getter.</p>
+<p class="description"><p>Each graph node can contain a reference to one variable. This is the getter for that reference.</p></p>
+	<ul class="tags">
+				<li><span class="field">return:</span> Data stored in node</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">mixed</span>
+		<span class="method-name">
+			&amp;getData
+		</span>
+				()
+			</div>
+	
+		
+		
+	</div>
+<a name="methodgetGraph" id="getGraph"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">getGraph</span> (line <span class="line-number">90</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Node graph getter</p>
+	<ul class="tags">
+				<li><span class="field">return:</span> Graph where node is stored</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result"><a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a></span>
+		<span class="method-name">
+			&amp;getGraph
+		</span>
+				()
+			</div>
+	
+		
+		
+	</div>
+<a name="methodgetMetadata" id="getMetadata"><!-- --></a>
+<div class="oddrow">
+	
+	<div class="method-header">
+		<span class="method-title">getMetadata</span> (line <span class="line-number">171</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Node metadata getter</p>
+<p class="description"><p>Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an  associative array or in a dictionary. This method gets the data under the given key. If the key does  not exist, an error will be thrown, so testing using metadataKeyExists might be needed.</p></p>
+	<ul class="tags">
+				<li><span class="field">return:</span> Metadata Data stored in node under given key</li>
+				<li><span class="field">access:</span> public</li>
+				<li><span class="field">see:</span> <a href="../Structures_Graph/Structures_Graph_Node.html#methodmetadataKeyExists">Structures_Graph_Node::metadataKeyExists()</a></li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">mixed</span>
+		<span class="method-name">
+			&amp;getMetadata
+		</span>
+					(<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$nullIfNonexistent</span> = <span class="var-default">false</span>])
+			</div>
+	
+			<ul class="parameters">
+					<li>
+				<span class="var-type">string</span>
+				<span class="var-name">$key</span><span class="var-description">: Key</span>			</li>
+					<li>
+				<span class="var-type">boolean</span>
+				<span class="var-name">$nullIfNonexistent</span><span class="var-description">: nullIfNonexistent (defaults to false).</span>			</li>
+				</ul>
+		
+		
+	</div>
+<a name="methodgetNeighbours" id="getNeighbours"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">getNeighbours</span> (line <span class="line-number">262</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Return nodes connected to this one.</p>
+	<ul class="tags">
+				<li><span class="field">return:</span> Array of nodes</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">array</span>
+		<span class="method-name">
+			getNeighbours
+		</span>
+				()
+			</div>
+	
+		
+		
+	</div>
+<a name="methodinDegree" id="inDegree"><!-- --></a>
+<div class="oddrow">
+	
+	<div class="method-header">
+		<span class="method-title">inDegree</span> (line <span class="line-number">309</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Calculate the in degree of the node.</p>
+<p class="description"><p>The indegree for a node is the number of arcs entering the node. For non directed graphs,  the indegree is equal to the outdegree.</p></p>
+	<ul class="tags">
+				<li><span class="field">return:</span> In degree of the node</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">integer</span>
+		<span class="method-name">
+			inDegree
+		</span>
+				()
+			</div>
+	
+		
+		
+	</div>
+<a name="methodmetadataKeyExists" id="metadataKeyExists"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">metadataKeyExists</span> (line <span class="line-number">151</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Test for existence of metadata under a given key.</p>
+<p class="description"><p>Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an  associative array or in a dictionary. This method tests whether a given metadata key exists for this node.</p></p>
+	<ul class="tags">
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">boolean</span>
+		<span class="method-name">
+			metadataKeyExists
+		</span>
+					(<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>)
+			</div>
+	
+			<ul class="parameters">
+					<li>
+				<span class="var-type">string</span>
+				<span class="var-name">$key</span><span class="var-description">: Key to test</span>			</li>
+				</ul>
+		
+		
+	</div>
+<a name="methodoutDegree" id="outDegree"><!-- --></a>
+<div class="oddrow">
+	
+	<div class="method-header">
+		<span class="method-title">outDegree</span> (line <span class="line-number">333</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Calculate the out degree of the node.</p>
+<p class="description"><p>The outdegree for a node is the number of arcs exiting the node. For non directed graphs,  the outdegree is always equal to the indegree.</p></p>
+	<ul class="tags">
+				<li><span class="field">return:</span> Out degree of the node</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">integer</span>
+		<span class="method-name">
+			outDegree
+		</span>
+				()
+			</div>
+	
+		
+		
+	</div>
+<a name="methodsetData" id="setData"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">setData</span> (line <span class="line-number">134</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Node data setter</p>
+<p class="description"><p>Each graph node can contain a reference to one variable. This is the setter for that reference.</p></p>
+	<ul class="tags">
+				<li><span class="field">return:</span> Data to store in node</li>
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">mixed</span>
+		<span class="method-name">
+			setData
+		</span>
+					(<span class="var-type">mixed</span>&nbsp;<span class="var-name">$data</span>)
+			</div>
+	
+		
+		
+	</div>
+<a name="methodsetGraph" id="setGraph"><!-- --></a>
+<div class="oddrow">
+	
+	<div class="method-header">
+		<span class="method-title">setGraph</span> (line <span class="line-number">104</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Node graph setter. This method should not be called directly. Use Graph::addNode instead.</p>
+	<ul class="tags">
+				<li><span class="field">access:</span> public</li>
+				<li><span class="field">see:</span> <a href="../Structures_Graph/Structures_Graph.html#methodaddNode">Structures_Graph::addNode()</a></li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">void</span>
+		<span class="method-name">
+			setGraph
+		</span>
+					(<span class="var-type"><a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a></span>&nbsp;<span class="var-name">&$graph</span>)
+			</div>
+	
+			<ul class="parameters">
+					<li>
+				<span class="var-type"><a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a></span>
+				<span class="var-name">&$graph</span><span class="var-description">: Set the graph for this node.</span>			</li>
+				</ul>
+		
+		
+	</div>
+<a name="methodsetMetadata" id="setMetadata"><!-- --></a>
+<div class="evenrow">
+	
+	<div class="method-header">
+		<span class="method-title">setMetadata</span> (line <span class="line-number">214</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Node metadata setter</p>
+<p class="description"><p>Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an  associative array or in a dictionary. This method stores data under the given key. If the key already exists,  previously stored data is discarded.</p></p>
+	<ul class="tags">
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">void</span>
+		<span class="method-name">
+			setMetadata
+		</span>
+					(<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">mixed</span>&nbsp;<span class="var-name">$data</span>)
+			</div>
+	
+			<ul class="parameters">
+					<li>
+				<span class="var-type">string</span>
+				<span class="var-name">$key</span><span class="var-description">: Key</span>			</li>
+					<li>
+				<span class="var-type">mixed</span>
+				<span class="var-name">$data</span><span class="var-description">: Data</span>			</li>
+				</ul>
+		
+		
+	</div>
+<a name="methodunsetMetadata" id="unsetMetadata"><!-- --></a>
+<div class="oddrow">
+	
+	<div class="method-header">
+		<span class="method-title">unsetMetadata</span> (line <span class="line-number">196</span>)
+	</div> 
+	
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Delete metadata by key</p>
+<p class="description"><p>Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an  associative array or in a dictionary. This method removes any data that might be stored under the provided key.  If the key does not exist, no error is thrown, so it is safe using this method without testing for key existence.</p></p>
+	<ul class="tags">
+				<li><span class="field">access:</span> public</li>
+			</ul>
+	
+	<div class="method-signature">
+		<span class="method-result">void</span>
+		<span class="method-name">
+			unsetMetadata
+		</span>
+					(<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>)
+			</div>
+	
+			<ul class="parameters">
+					<li>
+				<span class="var-type">string</span>
+				<span class="var-name">$key</span><span class="var-description">: Key</span>			</li>
+				</ul>
+		
+		
+	</div>
+						
+		</div>
+	</div>
+	
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:29 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</div></body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html b/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html
new file mode 100644
index 00000000..d36821c8
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Docs for page AcyclicTest.php</title>
+			<link rel="stylesheet" href="../media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="page-body">			
+<h2 class="file-name">/Structures/Graph/Manipulator/AcyclicTest.php</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+	<div class="info-box-title">Description</div>
+	<div class="nav-bar">
+					<span class="disabled">Description</span> |
+							<a href="#sec-classes">Classes</a>
+			|							<a href="#sec-includes">Includes</a>
+												</div>
+	<div class="info-box-body">	
+		<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">This file contains the definition of the Structures_Graph_Manipulator_AcyclicTest graph manipulator.</p>
+	<ul class="tags">
+				<li><span class="field">see:</span> <a href="../Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html">Structures_Graph_Manipulator_AcyclicTest</a></li>
+			</ul>
+		
+			</div>
+</div>
+		
+	<a name="sec-classes"></a>	
+	<div class="info-box">
+		<div class="info-box-title">Classes</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+			<span class="disabled">Classes</span>
+			|							<a href="#sec-includes">Includes</a>
+																		</div>
+		<div class="info-box-body">	
+			<table cellpadding="2" cellspacing="0" class="class-table">
+				<tr>
+					<th class="class-table-header">Class</th>
+					<th class="class-table-header">Description</th>
+				</tr>
+								<tr>
+					<td style="padding-right: 2em; vertical-align: top">
+						<a href="../Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html">Structures_Graph_Manipulator_AcyclicTest</a>
+					</td>
+					<td>
+											The Structures_Graph_Manipulator_AcyclicTest is a graph manipulator  which tests whether a graph contains a cycle.
+										</td>
+				</tr>
+							</table>
+		</div>
+	</div>
+
+	<a name="sec-includes"></a>	
+	<div class="info-box">
+		<div class="info-box-title">Includes</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+							<a href="#sec-classes">Classes</a>
+				|						<span class="disabled">Includes</span>
+														</div>
+		<div class="info-box-body">	
+			<a name="_PEAR_php"><!-- --></a>
+<div class="oddrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name">'PEAR.php'</span>)
+			(line <span class="line-number">35</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+	
+</div>
+<a name="_Structures/Graph_php"><!-- --></a>
+<div class="evenrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name"><a href="../Structures_Graph/_Structures_Graph_php.html">'Structures/Graph.php'</a></span>)
+			(line <span class="line-number">37</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+	
+</div>
+<a name="_Structures/Graph/Node_php"><!-- --></a>
+<div class="oddrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name"><a href="../Structures_Graph/_Structures_Graph_Node_php.html">'Structures/Graph/Node.php'</a></span>)
+			(line <span class="line-number">39</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+	
+</div>
+		</div>
+	</div>
+	
+	
+	
+	
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:28 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</div></body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html b/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html
new file mode 100644
index 00000000..e7913254
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Docs for page TopologicalSorter.php</title>
+			<link rel="stylesheet" href="../media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="page-body">			
+<h2 class="file-name">/Structures/Graph/Manipulator/TopologicalSorter.php</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+	<div class="info-box-title">Description</div>
+	<div class="nav-bar">
+					<span class="disabled">Description</span> |
+							<a href="#sec-classes">Classes</a>
+			|							<a href="#sec-includes">Includes</a>
+												</div>
+	<div class="info-box-body">	
+		<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">This file contains the definition of the Structures_Graph_Manipulator_TopologicalSorter class.</p>
+	<ul class="tags">
+				<li><span class="field">see:</span> <a href="../Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html">Structures_Graph_Manipulator_TopologicalSorter</a></li>
+			</ul>
+		
+			</div>
+</div>
+		
+	<a name="sec-classes"></a>	
+	<div class="info-box">
+		<div class="info-box-title">Classes</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+			<span class="disabled">Classes</span>
+			|							<a href="#sec-includes">Includes</a>
+																		</div>
+		<div class="info-box-body">	
+			<table cellpadding="2" cellspacing="0" class="class-table">
+				<tr>
+					<th class="class-table-header">Class</th>
+					<th class="class-table-header">Description</th>
+				</tr>
+								<tr>
+					<td style="padding-right: 2em; vertical-align: top">
+						<a href="../Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html">Structures_Graph_Manipulator_TopologicalSorter</a>
+					</td>
+					<td>
+											The Structures_Graph_Manipulator_TopologicalSorter is a manipulator  which is able to return the set of nodes in a graph, sorted by topological  order.
+										</td>
+				</tr>
+							</table>
+		</div>
+	</div>
+
+	<a name="sec-includes"></a>	
+	<div class="info-box">
+		<div class="info-box-title">Includes</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+							<a href="#sec-classes">Classes</a>
+				|						<span class="disabled">Includes</span>
+														</div>
+		<div class="info-box-body">	
+			<a name="_PEAR_php"><!-- --></a>
+<div class="oddrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name">'PEAR.php'</span>)
+			(line <span class="line-number">35</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+	
+</div>
+<a name="_Structures/Graph_php"><!-- --></a>
+<div class="evenrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name"><a href="../Structures_Graph/_Structures_Graph_php.html">'Structures/Graph.php'</a></span>)
+			(line <span class="line-number">37</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+	
+</div>
+<a name="_Structures/Graph/Node_php"><!-- --></a>
+<div class="oddrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name"><a href="../Structures_Graph/_Structures_Graph_Node_php.html">'Structures/Graph/Node.php'</a></span>)
+			(line <span class="line-number">39</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+	
+</div>
+<a name="_Structures/Graph/Manipulator/AcyclicTest_php"><!-- --></a>
+<div class="evenrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name"><a href="../Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html">'Structures/Graph/Manipulator/AcyclicTest.php'</a></span>)
+			(line <span class="line-number">41</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+	
+</div>
+		</div>
+	</div>
+	
+	
+	
+	
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:29 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</div></body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Node_php.html b/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Node_php.html
new file mode 100644
index 00000000..d1d3596a
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_Node_php.html
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Docs for page Node.php</title>
+			<link rel="stylesheet" href="../media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="page-body">			
+<h2 class="file-name">/Structures/Graph/Node.php</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+	<div class="info-box-title">Description</div>
+	<div class="nav-bar">
+					<span class="disabled">Description</span> |
+							<a href="#sec-classes">Classes</a>
+			|							<a href="#sec-includes">Includes</a>
+												</div>
+	<div class="info-box-body">	
+		<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">This file contains the definition of the Structures_Graph_Node class</p>
+	<ul class="tags">
+				<li><span class="field">see:</span> <a href="../Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a></li>
+			</ul>
+		
+			</div>
+</div>
+		
+	<a name="sec-classes"></a>	
+	<div class="info-box">
+		<div class="info-box-title">Classes</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+			<span class="disabled">Classes</span>
+			|							<a href="#sec-includes">Includes</a>
+																		</div>
+		<div class="info-box-body">	
+			<table cellpadding="2" cellspacing="0" class="class-table">
+				<tr>
+					<th class="class-table-header">Class</th>
+					<th class="class-table-header">Description</th>
+				</tr>
+								<tr>
+					<td style="padding-right: 2em; vertical-align: top">
+						<a href="../Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a>
+					</td>
+					<td>
+											The Structures_Graph_Node class represents a Node that can be member of a  graph node set.
+										</td>
+				</tr>
+							</table>
+		</div>
+	</div>
+
+	<a name="sec-includes"></a>	
+	<div class="info-box">
+		<div class="info-box-title">Includes</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+							<a href="#sec-classes">Classes</a>
+				|						<span class="disabled">Includes</span>
+														</div>
+		<div class="info-box-body">	
+			<a name="_PEAR_php"><!-- --></a>
+<div class="evenrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name">'PEAR.php'</span>)
+			(line <span class="line-number">35</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+	
+</div>
+<a name="_Structures/Graph_php"><!-- --></a>
+<div class="oddrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name"><a href="../Structures_Graph/_Structures_Graph_php.html">'Structures/Graph.php'</a></span>)
+			(line <span class="line-number">37</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+	
+</div>
+		</div>
+	</div>
+	
+	
+	
+	
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:29 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</div></body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_php.html b/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_php.html
new file mode 100644
index 00000000..cb74519c
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/Structures_Graph/_Structures_Graph_php.html
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Docs for page Graph.php</title>
+			<link rel="stylesheet" href="../media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="page-body">			
+<h2 class="file-name">/Structures/Graph.php</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+	<div class="info-box-title">Description</div>
+	<div class="nav-bar">
+					<span class="disabled">Description</span> |
+							<a href="#sec-classes">Classes</a>
+			|							<a href="#sec-includes">Includes</a>
+			|							<a href="#sec-constants">Constants</a>
+										</div>
+	<div class="info-box-body">	
+		<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The Graph.php file contains the definition of the Structures_Graph class</p>
+	<ul class="tags">
+				<li><span class="field">see:</span> <a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a></li>
+			</ul>
+		
+			</div>
+</div>
+		
+	<a name="sec-classes"></a>	
+	<div class="info-box">
+		<div class="info-box-title">Classes</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+			<span class="disabled">Classes</span>
+			|							<a href="#sec-includes">Includes</a>
+				|										<a href="#sec-constants">Constants</a>
+															</div>
+		<div class="info-box-body">	
+			<table cellpadding="2" cellspacing="0" class="class-table">
+				<tr>
+					<th class="class-table-header">Class</th>
+					<th class="class-table-header">Description</th>
+				</tr>
+								<tr>
+					<td style="padding-right: 2em; vertical-align: top">
+						<a href="../Structures_Graph/Structures_Graph.html">Structures_Graph</a>
+					</td>
+					<td>
+											The Structures_Graph class represents a graph data structure.
+										</td>
+				</tr>
+							</table>
+		</div>
+	</div>
+
+	<a name="sec-includes"></a>	
+	<div class="info-box">
+		<div class="info-box-title">Includes</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+							<a href="#sec-classes">Classes</a>
+				|						<span class="disabled">Includes</span>
+			|							<a href="#sec-constants">Constants</a>
+															</div>
+		<div class="info-box-body">	
+			<a name="_Structures/Graph/Node_php"><!-- --></a>
+<div class="oddrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name"><a href="../Structures_Graph/_Structures_Graph_Node_php.html">'Structures/Graph/Node.php'</a></span>)
+			(line <span class="line-number">37</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Graph Node</p>
+	
+</div>
+<a name="_PEAR_php"><!-- --></a>
+<div class="evenrow">
+	
+	<div>
+		<span class="include-title">
+			<span class="include-type">require_once</span>
+			(<span class="include-name">'PEAR.php'</span>)
+			(line <span class="line-number">35</span>)
+		</span>
+	</div>
+
+	<!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">PEAR base classes</p>
+	
+</div>
+		</div>
+	</div>
+	
+	<a name="sec-constants"></a>	
+	<div class="info-box">
+		<div class="info-box-title">Constants</div>
+		<div class="nav-bar">
+			<a href="#sec-description">Description</a> |
+							<a href="#sec-classes">Classes</a>
+				|										<a href="#sec-includes">Includes</a>
+				|						<span class="disabled">Constants</span>
+											</div>
+		<div class="info-box-body">	
+			<a name="defineSTRUCTURES_GRAPH_ERROR_GENERIC"><!-- --></a>
+<div class="oddrow">
+	
+	<div>
+		<span class="const-title">
+			<span class="const-name">STRUCTURES_GRAPH_ERROR_GENERIC</span> = 100
+			(line <span class="line-number">40</span>)
+		</span>
+	</div>
+	
+	<!-- ========== Info from phpDoc block ========= -->
+	
+		
+</div>
+		</div>
+	</div>
+	
+	
+	
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:28 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</div></body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/Structures_Graph/tutorial_Structures_Graph.pkg.html b/lib/docs/Structures_Graph/docs/html/Structures_Graph/tutorial_Structures_Graph.pkg.html
new file mode 100644
index 00000000..ffea0c90
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/Structures_Graph/tutorial_Structures_Graph.pkg.html
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Structures_Graph Tutorial</title>
+			<link rel="stylesheet" href="../media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="page-body">			
+
+<div><a name="package.database.structures_graph.tutorial"></a><div class="ref-title-box"><h1 class="ref-title">Structures_Graph Tutorial</h1>
+  <h2 class="ref-purpose">A first tour of graph datastructure manipulation</h2></div>
+ <span><a name="package.database.structures_graph.tutorial.intro"></a><h2 class="title">Introduction</h2><p>Structures_Graph is a package for creating and manipulating graph datastructures. A graph is a set of objects, called nodes, connected by arcs. When used as a datastructure, usually nodes contain data, and arcs represent relationships between nodes. When arcs have a direction, and can be travelled only one way, graphs are said to be directed. When arcs have no direction, and can always be travelled both ways, graphs are said to be non directed.</p>
+  <p>Structures_Graph provides an object oriented API to create and directly query a graph, as well as a set of Manipulator classes to extract information from the graph.</p></span>
+ <span><a name="package.database.structures_graph.tutorial.creation"></a><h2 class="title">Creating a Graph</h2><p>Creating a graph is done using the simple constructor:
+   <pre class="listing"><pre>
+require_once 'Structures/Graph.php';
+
+$directedGraph =&amp; new Structures_Graph(true);
+$nonDirectedGraph =&amp; new Structures_Graph(false);
+    </pre></pre>
+   and passing the constructor a flag telling it whether the graph should be directed. A directed graph will always be directed during its lifetime. It's a permanent characteristic.</p>
+  <p>To fill out the graph, we'll need to create some nodes, and then call Graph::addNode.
+   <pre class="listing"><pre>
+require_once 'Structures/Graph/Node.php';
+
+$nodeOne =&amp; new Structures_Graph_Node();
+$nodeTwo =&amp; new Structures_Graph_Node();
+$nodeThree =&amp; new Structures_Graph_Node();
+
+$directedGraph-&gt;addNode(&amp;$nodeOne);
+$directedGraph-&gt;addNode(&amp;$nodeTwo);
+$directedGraph-&gt;addNode(&amp;$nodeThree);
+    </pre></pre>
+   and then setup the arcs:
+   <pre class="listing"><pre>
+$nodeOne-&gt;connectTo($nodeTwo);
+$nodeOne-&gt;connectTo($nodeThree);
+    </pre></pre>
+   Note that arcs can only be created after the nodes have been inserted into the graph.</p></span>
+ <span><a name="package.database.structures_graph.tutorial.nodesanddata"></a><h2 class="title">Associating Data</h2><p>Graphs are only useful as datastructures if they can hold data. Structure_Graph stores data in nodes. Each node contains a setter and a getter for its data.
+   <pre class="listing"><pre>
+$nodeOne-&gt;setData(&quot;Node One's Data is a String&quot;);
+$nodeTwo-&gt;setData(1976);
+$nodeThree-&gt;setData('Some other string');
+
+print(&quot;NodeTwo's Data is an integer: &quot; . $nodeTwo-&gt;getData());
+    </pre></pre></p>
+  <p>Structure_Graph nodes can also store metadata, alongside with the main data. Metadata differs from regular data just because it is stored under a key, making it possible to store more than one data reference per node. The metadata getter and setter need the key to perform the operation:
+   <pre class="listing"><pre>
+$nodeOne-&gt;setMetadata('example key', &quot;Node One's Sample Metadata&quot;);
+print(&quot;Metadata stored under key 'example key' in node one: &quot; . $nodeOne-&gt;getMetadata('example key'));
+$nodeOne-&gt;unsetMetadata('example key');
+    </pre></pre></p></span>
+ <span><a name="package.database.structures_graph.tutorial.querying"></a><h2 class="title">Querying a Graph</h2><p>Structures_Graph provides for basic querying of the graph:
+   <pre class="listing"><pre>
+// Nodes are able to calculate their indegree and outdegree
+print(&quot;NodeOne's inDegree: &quot; . $nodeOne-&gt;inDegree());
+print(&quot;NodeOne's outDegree: &quot; . $nodeOne-&gt;outDegree());
+
+// and naturally, nodes can report on their arcs
+$arcs = $nodeOne-&gt;getNeighbours();
+for ($i=0;$i&lt;sizeof($arcs);$i++) {
+    print(&quot;NodeOne has an arc to &quot; . $arcs[$i]-&gt;getData());
+}
+    </pre></pre></p></span></div>
+
+
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:28 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</div></body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/classtrees_Structures_Graph.html b/lib/docs/Structures_Graph/docs/html/classtrees_Structures_Graph.html
new file mode 100644
index 00000000..abb613f3
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/classtrees_Structures_Graph.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title></title>
+			<link rel="stylesheet" href="media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+						
+<!-- Start of Class Data -->
+<H2>
+	
+</H2>
+<h2>Root class Structures_Graph</h2>
+<ul>
+<li><a href="Structures_Graph/Structures_Graph.html">Structures_Graph</a></li></ul>
+
+<h2>Root class Structures_Graph_Manipulator_AcyclicTest</h2>
+<ul>
+<li><a href="Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html">Structures_Graph_Manipulator_AcyclicTest</a></li></ul>
+
+<h2>Root class Structures_Graph_Manipulator_TopologicalSorter</h2>
+<ul>
+<li><a href="Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html">Structures_Graph_Manipulator_TopologicalSorter</a></li></ul>
+
+<h2>Root class Structures_Graph_Node</h2>
+<ul>
+<li><a href="Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a></li></ul>
+
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:28 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/elementindex.html b/lib/docs/Structures_Graph/docs/html/elementindex.html
new file mode 100644
index 00000000..fdf6d187
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/elementindex.html
@@ -0,0 +1,339 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title></title>
+			<link rel="stylesheet" href="media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+						<a name="top"></a>
+<h2>Full index</h2>
+<h3>Package indexes</h3>
+<ul>
+	<li><a href="elementindex_Structures_Graph.html">Structures_Graph</a></li>
+</ul>
+<br />
+<div class="index-letter-menu">
+	<a class="index-letter" href="elementindex.html#a">a</a>
+	<a class="index-letter" href="elementindex.html#c">c</a>
+	<a class="index-letter" href="elementindex.html#g">g</a>
+	<a class="index-letter" href="elementindex.html#i">i</a>
+	<a class="index-letter" href="elementindex.html#m">m</a>
+	<a class="index-letter" href="elementindex.html#n">n</a>
+	<a class="index-letter" href="elementindex.html#o">o</a>
+	<a class="index-letter" href="elementindex.html#r">r</a>
+	<a class="index-letter" href="elementindex.html#s">s</a>
+	<a class="index-letter" href="elementindex.html#t">t</a>
+	<a class="index-letter" href="elementindex.html#u">u</a>
+</div>
+
+	<a name="a"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">a</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">addNode</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodaddNode">Structures_Graph::addNode()</a> in Graph.php</div>
+							<div class="index-item-description">Add a Node to the Graph</div>
+					</dd>
+			<dt class="field">
+						<span class="include-title">AcyclicTest.php</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html">AcyclicTest.php</a> in AcyclicTest.php</div>
+					</dd>
+		</dl>
+	<a name="c"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">c</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">connectsTo</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodconnectsTo">Structures_Graph_Node::connectsTo()</a> in Node.php</div>
+							<div class="index-item-description">Test wether this node has an arc to the target node</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">connectTo</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodconnectTo">Structures_Graph_Node::connectTo()</a> in Node.php</div>
+							<div class="index-item-description">Connect this node to another one.</div>
+					</dd>
+		</dl>
+	<a name="g"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">g</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">getData</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodgetData">Structures_Graph_Node::getData()</a> in Node.php</div>
+							<div class="index-item-description">Node data getter.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">getGraph</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodgetGraph">Structures_Graph_Node::getGraph()</a> in Node.php</div>
+							<div class="index-item-description">Node graph getter</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">getMetadata</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodgetMetadata">Structures_Graph_Node::getMetadata()</a> in Node.php</div>
+							<div class="index-item-description">Node metadata getter</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">getNeighbours</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodgetNeighbours">Structures_Graph_Node::getNeighbours()</a> in Node.php</div>
+							<div class="index-item-description">Return nodes connected to this one.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">getNodes</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodgetNodes">Structures_Graph::getNodes()</a> in Graph.php</div>
+							<div class="index-item-description">Return the node set, in no particular order. For ordered node sets, use a Graph Manipulator insted.</div>
+					</dd>
+			<dt class="field">
+						<span class="include-title">Graph.php</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_php.html">Graph.php</a> in Graph.php</div>
+					</dd>
+		</dl>
+	<a name="i"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">i</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">inDegree</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodinDegree">Structures_Graph_Node::inDegree()</a> in Node.php</div>
+							<div class="index-item-description">Calculate the in degree of the node.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">isAcyclic</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html#methodisAcyclic">Structures_Graph_Manipulator_AcyclicTest::isAcyclic()</a> in AcyclicTest.php</div>
+							<div class="index-item-description">isAcyclic returns true if a graph contains no cycles, false otherwise.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">isDirected</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodisDirected">Structures_Graph::isDirected()</a> in Graph.php</div>
+							<div class="index-item-description">Return true if a graph is directed</div>
+					</dd>
+		</dl>
+	<a name="m"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">m</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">metadataKeyExists</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodmetadataKeyExists">Structures_Graph_Node::metadataKeyExists()</a> in Node.php</div>
+							<div class="index-item-description">Test for existence of metadata under a given key.</div>
+					</dd>
+		</dl>
+	<a name="n"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">n</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="include-title">Node.php</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_Node_php.html">Node.php</a> in Node.php</div>
+					</dd>
+		</dl>
+	<a name="o"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">o</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">outDegree</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodoutDegree">Structures_Graph_Node::outDegree()</a> in Node.php</div>
+							<div class="index-item-description">Calculate the out degree of the node.</div>
+					</dd>
+		</dl>
+	<a name="r"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">r</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">removeNode</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodremoveNode">Structures_Graph::removeNode()</a> in Graph.php</div>
+							<div class="index-item-description">Remove a Node from the Graph</div>
+					</dd>
+		</dl>
+	<a name="s"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">s</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">setData</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodsetData">Structures_Graph_Node::setData()</a> in Node.php</div>
+							<div class="index-item-description">Node data setter</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">setGraph</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodsetGraph">Structures_Graph_Node::setGraph()</a> in Node.php</div>
+							<div class="index-item-description">Node graph setter. This method should not be called directly. Use Graph::addNode instead.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">setMetadata</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodsetMetadata">Structures_Graph_Node::setMetadata()</a> in Node.php</div>
+							<div class="index-item-description">Node metadata setter</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">sort</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html#methodsort">Structures_Graph_Manipulator_TopologicalSorter::sort()</a> in TopologicalSorter.php</div>
+							<div class="index-item-description">sort returns the graph's nodes, sorted by topological order.</div>
+					</dd>
+			<dt class="field">
+						Structures_Graph
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html">Structures_Graph</a> in Graph.php</div>
+							<div class="index-item-description">The Structures_Graph class represents a graph data structure.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">Structures_Graph</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodStructures_Graph">Structures_Graph::Structures_Graph()</a> in Graph.php</div>
+							<div class="index-item-description">Constructor</div>
+					</dd>
+			<dt class="field">
+						<span class="const-title">STRUCTURES_GRAPH_ERROR_GENERIC</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_php.html#defineSTRUCTURES_GRAPH_ERROR_GENERIC">STRUCTURES_GRAPH_ERROR_GENERIC</a> in Graph.php</div>
+					</dd>
+			<dt class="field">
+						Structures_Graph_Manipulator_AcyclicTest
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html">Structures_Graph_Manipulator_AcyclicTest</a> in AcyclicTest.php</div>
+							<div class="index-item-description">The Structures_Graph_Manipulator_AcyclicTest is a graph manipulator  which tests whether a graph contains a cycle.</div>
+					</dd>
+			<dt class="field">
+						Structures_Graph_Manipulator_TopologicalSorter
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html">Structures_Graph_Manipulator_TopologicalSorter</a> in TopologicalSorter.php</div>
+							<div class="index-item-description">The Structures_Graph_Manipulator_TopologicalSorter is a manipulator  which is able to return the set of nodes in a graph, sorted by topological  order.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">Structures_Graph_Node</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodStructures_Graph_Node">Structures_Graph_Node::Structures_Graph_Node()</a> in Node.php</div>
+							<div class="index-item-description">Constructor</div>
+					</dd>
+			<dt class="field">
+						Structures_Graph_Node
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a> in Node.php</div>
+							<div class="index-item-description">The Structures_Graph_Node class represents a Node that can be member of a  graph node set.</div>
+					</dd>
+		</dl>
+	<a name="t"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">t</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="include-title">TopologicalSorter.php</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html">TopologicalSorter.php</a> in TopologicalSorter.php</div>
+					</dd>
+		</dl>
+	<a name="u"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">u</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">unsetMetadata</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodunsetMetadata">Structures_Graph_Node::unsetMetadata()</a> in Node.php</div>
+							<div class="index-item-description">Delete metadata by key</div>
+					</dd>
+		</dl>
+
+<div class="index-letter-menu">
+	<a class="index-letter" href="elementindex.html#a">a</a>
+	<a class="index-letter" href="elementindex.html#c">c</a>
+	<a class="index-letter" href="elementindex.html#g">g</a>
+	<a class="index-letter" href="elementindex.html#i">i</a>
+	<a class="index-letter" href="elementindex.html#m">m</a>
+	<a class="index-letter" href="elementindex.html#n">n</a>
+	<a class="index-letter" href="elementindex.html#o">o</a>
+	<a class="index-letter" href="elementindex.html#r">r</a>
+	<a class="index-letter" href="elementindex.html#s">s</a>
+	<a class="index-letter" href="elementindex.html#t">t</a>
+	<a class="index-letter" href="elementindex.html#u">u</a>
+</div>	</body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/elementindex_Structures_Graph.html b/lib/docs/Structures_Graph/docs/html/elementindex_Structures_Graph.html
new file mode 100644
index 00000000..85344acc
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/elementindex_Structures_Graph.html
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title></title>
+			<link rel="stylesheet" href="media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+						<a name="top"></a>
+<h2>[Structures_Graph] element index</h2>
+<a href="elementindex.html">All elements</a>
+<br />
+<div class="index-letter-menu">
+	<a class="index-letter" href="elementindex_Structures_Graph.html#a">a</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#c">c</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#g">g</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#i">i</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#m">m</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#n">n</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#o">o</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#r">r</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#s">s</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#t">t</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#u">u</a>
+</div>
+
+	<a name="a"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">a</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">addNode</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodaddNode">Structures_Graph::addNode()</a> in Graph.php</div>
+							<div class="index-item-description">Add a Node to the Graph</div>
+					</dd>
+			<dt class="field">
+						<span class="include-title">AcyclicTest.php</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html">AcyclicTest.php</a> in AcyclicTest.php</div>
+					</dd>
+		</dl>
+	<a name="c"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">c</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">connectsTo</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodconnectsTo">Structures_Graph_Node::connectsTo()</a> in Node.php</div>
+							<div class="index-item-description">Test wether this node has an arc to the target node</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">connectTo</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodconnectTo">Structures_Graph_Node::connectTo()</a> in Node.php</div>
+							<div class="index-item-description">Connect this node to another one.</div>
+					</dd>
+		</dl>
+	<a name="g"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">g</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">getData</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodgetData">Structures_Graph_Node::getData()</a> in Node.php</div>
+							<div class="index-item-description">Node data getter.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">getGraph</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodgetGraph">Structures_Graph_Node::getGraph()</a> in Node.php</div>
+							<div class="index-item-description">Node graph getter</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">getMetadata</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodgetMetadata">Structures_Graph_Node::getMetadata()</a> in Node.php</div>
+							<div class="index-item-description">Node metadata getter</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">getNeighbours</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodgetNeighbours">Structures_Graph_Node::getNeighbours()</a> in Node.php</div>
+							<div class="index-item-description">Return nodes connected to this one.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">getNodes</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodgetNodes">Structures_Graph::getNodes()</a> in Graph.php</div>
+							<div class="index-item-description">Return the node set, in no particular order. For ordered node sets, use a Graph Manipulator insted.</div>
+					</dd>
+			<dt class="field">
+						<span class="include-title">Graph.php</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_php.html">Graph.php</a> in Graph.php</div>
+					</dd>
+		</dl>
+	<a name="i"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">i</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">inDegree</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodinDegree">Structures_Graph_Node::inDegree()</a> in Node.php</div>
+							<div class="index-item-description">Calculate the in degree of the node.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">isAcyclic</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html#methodisAcyclic">Structures_Graph_Manipulator_AcyclicTest::isAcyclic()</a> in AcyclicTest.php</div>
+							<div class="index-item-description">isAcyclic returns true if a graph contains no cycles, false otherwise.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">isDirected</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodisDirected">Structures_Graph::isDirected()</a> in Graph.php</div>
+							<div class="index-item-description">Return true if a graph is directed</div>
+					</dd>
+		</dl>
+	<a name="m"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">m</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">metadataKeyExists</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodmetadataKeyExists">Structures_Graph_Node::metadataKeyExists()</a> in Node.php</div>
+							<div class="index-item-description">Test for existence of metadata under a given key.</div>
+					</dd>
+		</dl>
+	<a name="n"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">n</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="include-title">Node.php</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_Node_php.html">Node.php</a> in Node.php</div>
+					</dd>
+		</dl>
+	<a name="o"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">o</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">outDegree</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodoutDegree">Structures_Graph_Node::outDegree()</a> in Node.php</div>
+							<div class="index-item-description">Calculate the out degree of the node.</div>
+					</dd>
+		</dl>
+	<a name="r"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">r</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">removeNode</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodremoveNode">Structures_Graph::removeNode()</a> in Graph.php</div>
+							<div class="index-item-description">Remove a Node from the Graph</div>
+					</dd>
+		</dl>
+	<a name="s"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">s</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">setData</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodsetData">Structures_Graph_Node::setData()</a> in Node.php</div>
+							<div class="index-item-description">Node data setter</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">setGraph</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodsetGraph">Structures_Graph_Node::setGraph()</a> in Node.php</div>
+							<div class="index-item-description">Node graph setter. This method should not be called directly. Use Graph::addNode instead.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">setMetadata</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodsetMetadata">Structures_Graph_Node::setMetadata()</a> in Node.php</div>
+							<div class="index-item-description">Node metadata setter</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">sort</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html#methodsort">Structures_Graph_Manipulator_TopologicalSorter::sort()</a> in TopologicalSorter.php</div>
+							<div class="index-item-description">sort returns the graph's nodes, sorted by topological order.</div>
+					</dd>
+			<dt class="field">
+						Structures_Graph
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html">Structures_Graph</a> in Graph.php</div>
+							<div class="index-item-description">The Structures_Graph class represents a graph data structure.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">Structures_Graph</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph.html#methodStructures_Graph">Structures_Graph::Structures_Graph()</a> in Graph.php</div>
+							<div class="index-item-description">Constructor</div>
+					</dd>
+			<dt class="field">
+						<span class="const-title">STRUCTURES_GRAPH_ERROR_GENERIC</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_php.html#defineSTRUCTURES_GRAPH_ERROR_GENERIC">STRUCTURES_GRAPH_ERROR_GENERIC</a> in Graph.php</div>
+					</dd>
+			<dt class="field">
+						Structures_Graph_Manipulator_AcyclicTest
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html">Structures_Graph_Manipulator_AcyclicTest</a> in AcyclicTest.php</div>
+							<div class="index-item-description">The Structures_Graph_Manipulator_AcyclicTest is a graph manipulator  which tests whether a graph contains a cycle.</div>
+					</dd>
+			<dt class="field">
+						Structures_Graph_Manipulator_TopologicalSorter
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html">Structures_Graph_Manipulator_TopologicalSorter</a> in TopologicalSorter.php</div>
+							<div class="index-item-description">The Structures_Graph_Manipulator_TopologicalSorter is a manipulator  which is able to return the set of nodes in a graph, sorted by topological  order.</div>
+					</dd>
+			<dt class="field">
+						<span class="method-title">Structures_Graph_Node</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodStructures_Graph_Node">Structures_Graph_Node::Structures_Graph_Node()</a> in Node.php</div>
+							<div class="index-item-description">Constructor</div>
+					</dd>
+			<dt class="field">
+						Structures_Graph_Node
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html">Structures_Graph_Node</a> in Node.php</div>
+							<div class="index-item-description">The Structures_Graph_Node class represents a Node that can be member of a  graph node set.</div>
+					</dd>
+		</dl>
+	<a name="t"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">t</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="include-title">TopologicalSorter.php</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html">TopologicalSorter.php</a> in TopologicalSorter.php</div>
+					</dd>
+		</dl>
+	<a name="u"></a>
+	<div class="index-letter-section">
+		<div style="float: left" class="index-letter-title">u</div>
+		<div style="float: right"><a href="#top">top</a></div>
+		<div style="clear: both"></div>
+	</div>
+	<dl>
+			<dt class="field">
+						<span class="method-title">unsetMetadata</span>
+					</dt>
+		<dd class="index-item-body">
+			<div class="index-item-details"><a href="Structures_Graph/Structures_Graph_Node.html#methodunsetMetadata">Structures_Graph_Node::unsetMetadata()</a> in Node.php</div>
+							<div class="index-item-description">Delete metadata by key</div>
+					</dd>
+		</dl>
+
+<div class="index-letter-menu">
+	<a class="index-letter" href="elementindex_Structures_Graph.html#a">a</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#c">c</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#g">g</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#i">i</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#m">m</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#n">n</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#o">o</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#r">r</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#s">s</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#t">t</a>
+	<a class="index-letter" href="elementindex_Structures_Graph.html#u">u</a>
+</div>	</body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/errors.html b/lib/docs/Structures_Graph/docs/html/errors.html
new file mode 100644
index 00000000..cdc198ac
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/errors.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>phpDocumentor Parser Errors and Warnings</title>
+			<link rel="stylesheet" href="media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+						<a href="#Post-parsing">Post-parsing</a><br>
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:29 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/index.html b/lib/docs/Structures_Graph/docs/html/index.html
new file mode 100644
index 00000000..d272cf6c
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/index.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html 
+     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//FR"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+   <html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<!-- Generated by phpDocumentor on Fri, 30 Jan 2004 16:37:28 +0000  -->
+  <title>Structures_Graph Documentation</title>
+  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+</head>
+
+<FRAMESET rows='100,*'>
+	<FRAME src='packages.html' name='left_top' frameborder="1" bordercolor="#999999">
+	<FRAMESET cols='25%,*'>
+		<FRAME src='li_Structures_Graph.html' name='left_bottom' frameborder="1" bordercolor="#999999">
+		<FRAME src='Structures_Graph/tutorial_Structures_Graph.pkg.html' name='right' frameborder="1" bordercolor="#999999">
+	</FRAMESET>
+	<NOFRAMES>
+		<H2>Frame Alert</H2>
+		<P>This document is designed to be viewed using the frames feature.
+		If you see this message, you are using a non-frame-capable web client.</P>
+	</NOFRAMES>
+</FRAMESET>
+</HTML>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/li_Structures_Graph.html b/lib/docs/Structures_Graph/docs/html/li_Structures_Graph.html
new file mode 100644
index 00000000..d563cde4
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/li_Structures_Graph.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title></title>
+			<link rel="stylesheet" href="media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+						<div class="package-title">Structures_Graph</div>
+<div class="package-details">
+
+	<dl class="tree">
+		
+		<dt class="folder-title">Description</dt>
+		<dd>
+			<a href='classtrees_Structures_Graph.html' target='right'>Class trees</a><br />
+			<a href='elementindex_Structures_Graph.html' target='right'>Index of elements</a><br />
+							<a href="todolist.html" target="right">Todo List</a><br />
+					</dd>
+	
+							
+							
+									<dt class="folder-title">Tutorials/Manuals</dt>
+					<dd>
+											<dl class="tree">
+						<dt class="folder-title">Package-level</dt>
+						<dd>
+													<div><a href="Structures_Graph/tutorial_Structures_Graph.pkg.html" target="right">Structures_Graph Tutorial</a></div>
+
+												</dd>
+						</dl>
+										
+										
+										</dd>
+													<dt class="folder-title">Classes</dt>
+											<dd><a href='Structures_Graph/Structures_Graph.html' target='right'>Structures_Graph</a></dd>
+											<dd><a href='Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html' target='right'>Structures_Graph_Manipulator_AcyclicTest</a></dd>
+											<dd><a href='Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html' target='right'>Structures_Graph_Manipulator_TopologicalSorter</a></dd>
+											<dd><a href='Structures_Graph/Structures_Graph_Node.html' target='right'>Structures_Graph_Node</a></dd>
+																						<dt class="folder-title">Files</dt>
+											<dd><a href='Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html' target='right'>AcyclicTest.php</a></dd>
+											<dd><a href='Structures_Graph/_Structures_Graph_php.html' target='right'>Graph.php</a></dd>
+											<dd><a href='Structures_Graph/_Structures_Graph_Node_php.html' target='right'>Node.php</a></dd>
+											<dd><a href='Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html' target='right'>TopologicalSorter.php</a></dd>
+																	
+						
+			</dl>
+</div>
+<p class="notes"><a href="http://www.phpdoc.org" target="_blank">phpDocumentor v <span class="field">1.2.3</span></a></p>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/media/banner.css b/lib/docs/Structures_Graph/docs/html/media/banner.css
new file mode 100644
index 00000000..e67227b7
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/media/banner.css
@@ -0,0 +1,32 @@
+body 
+{ 
+	background-color: #CCCCFF; 
+	margin: 0px; 
+	padding: 0px;
+}
+
+/* Banner (top bar) classes */
+
+.banner {  }
+
+.banner-menu 
+{ 
+	clear: both;
+	padding: .5em;
+	border-top: 2px solid #6666AA;	
+}
+
+.banner-title 
+{ 
+	text-align: right; 
+	font-size: 20pt; 
+	font-weight: bold; 
+	margin: .2em;
+}
+
+.package-selector 
+{ 
+	background-color: #AAAADD; 
+	border: 1px solid black; 
+	color: yellow;
+}
diff --git a/lib/docs/Structures_Graph/docs/html/media/stylesheet.css b/lib/docs/Structures_Graph/docs/html/media/stylesheet.css
new file mode 100644
index 00000000..4a097a22
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/media/stylesheet.css
@@ -0,0 +1,134 @@
+a { color: #336699; text-decoration: none; }
+a:hover { color: #6699CC; text-decoration: underline; }
+a:active { color: #6699CC; text-decoration: underline; }
+
+body { background : #FFFFFF; }
+body, table { font-family: Georgia, Times New Roman, Times, serif; font-size: 10pt }
+p, li { line-height: 140% }
+a img { border: 0px; }
+dd { margin-left: 0px; padding-left: 1em; }
+
+/* Page layout/boxes */
+
+.info-box {}
+.info-box-title { margin: 1em 0em 0em 0em; padding: .25em; font-weight: normal; font-size: 14pt; border: 2px solid #999999; background-color: #CCCCFF }
+.info-box-body { border: 1px solid #999999; padding: .5em; }
+.nav-bar { font-size: 8pt; white-space: nowrap; text-align: right; padding: .2em; margin: 0em 0em 1em 0em; }
+
+.oddrow { background-color: #F8F8F8; border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em}
+.evenrow { border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em}
+
+.page-body { max-width: 800px; margin: auto; }
+.tree dl { margin: 0px }
+
+/* Index formatting classes */
+
+.index-item-body { margin-top: .5em; margin-bottom: .5em}
+.index-item-description { margin-top: .25em }
+.index-item-details { font-weight: normal; font-style: italic; font-size: 8pt }
+.index-letter-section { background-color: #EEEEEE; border: 1px dotted #999999; padding: .5em; margin-bottom: 1em}
+.index-letter-title { font-size: 12pt; font-weight: bold }
+.index-letter-menu { text-align: center; margin: 1em }
+.index-letter { font-size: 12pt }
+
+/* Docbook classes */
+
+.description {}
+.short-description { font-weight: bold; color: #666666; }
+.tags {	padding-left: 0em; margin-left: 3em; color: #666666; list-style-type: square; }
+.parameters {	padding-left: 0em; margin-left: 3em; font-style: italic; list-style-type: square; }
+.redefinitions { font-size: 8pt; padding-left: 0em; margin-left: 2em; }
+.package {  }
+.package-title { font-weight: bold; font-size: 14pt; border-bottom: 1px solid black }
+.package-details { font-size: 85%; }
+.sub-package { font-weight: bold; font-size: 120% }
+.tutorial { border-width: thin; border-color: #0066ff }
+.tutorial-nav-box { width: 100%; border: 1px solid #999999; background-color: #F8F8F8; }
+.nav-button-disabled { color: #999999; }
+.nav-button:active, 
+.nav-button:focus, 
+.nav-button:hover { background-color: #DDDDDD; outline: 1px solid #999999; text-decoration: none }
+.folder-title { font-style: italic }
+
+/* Generic formatting */
+
+.field { font-weight: bold; }
+.detail { font-size: 8pt; }
+.notes { font-style: italic; font-size: 8pt; }
+.separator { background-color: #999999; height: 2px; }
+.warning {  color: #FF6600; }
+.disabled { font-style: italic; color: #999999; }
+
+/* Code elements */
+
+.line-number {  }
+
+.class-table { width: 100%; }
+.class-table-header { border-bottom: 1px dotted #666666; text-align: left}
+.class-name { color: #000000; font-weight: bold; }
+
+.method-summary { padding-left: 1em; font-size: 8pt }
+.method-header { }
+.method-definition { margin-bottom: .3em }
+.method-title { font-weight: bold; }
+.method-name { font-weight: bold; }
+.method-signature { font-size: 85%; color: #666666; margin: .5em 0em }
+.method-result { font-style: italic; }
+
+.var-summary { padding-left: 1em; font-size: 8pt; }
+.var-header { }
+.var-title { margin-bottom: .3em }
+.var-type { font-style: italic; }
+.var-name { font-weight: bold; }
+.var-default {}
+.var-description { font-weight: normal; color: #000000; }
+
+.include-title {  }
+.include-type { font-style: italic; }
+.include-name { font-weight: bold; }
+
+.const-title {  }
+.const-name { font-weight: bold; }
+
+/* Syntax highlighting */
+
+.src-code {  border: 1px solid #336699; padding: 1em; background-color: #EEEEEE; }
+
+.src-comm { color: green; }
+.src-id {  }
+.src-inc { color: #0000FF; }
+.src-key { color: #0000FF; }
+.src-num { color: #CC0000; }
+.src-str { color: #66cccc; }
+.src-sym { font-weight: bold; }
+.src-var { }
+
+.src-php { font-weight: bold; }
+
+.src-doc { color: #009999 }
+.src-doc-close-template { color: #0000FF }
+.src-doc-coretag { color: #0099FF; font-weight: bold }
+.src-doc-inlinetag { color: #0099FF }
+.src-doc-internal { color: #6699cc }
+.src-doc-tag { color: #0080CC }
+.src-doc-template { color: #0000FF }
+.src-doc-type { font-style: italic }
+.src-doc-var { font-style: italic }
+
+/* tutorial */
+
+.authors {  }
+.author { font-style: italic; font-weight: bold }
+.author-blurb { margin: .5em 0em .5em 2em; font-size: 85%; font-weight: normal; font-style: normal }
+.example { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em }
+.listing { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em; white-space: nowrap }
+.release-info { font-size: 85%; font-style: italic; margin: 1em 0em }
+.ref-title-box {  }
+.ref-title {  }
+.ref-purpose { font-style: italic; color: #666666 }
+.ref-synopsis {  }
+.title { font-weight: bold; margin: 1em 0em 0em 0em; padding: .25em; border: 2px solid #999999; background-color: #CCCCFF  }
+.cmd-synopsis { margin: 1em 0em }
+.cmd-title { font-weight: bold }
+.toc { margin-left: 2em; padding-left: 0em }
+
diff --git a/lib/docs/Structures_Graph/docs/html/packages.html b/lib/docs/Structures_Graph/docs/html/packages.html
new file mode 100644
index 00000000..ebed0d3c
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/packages.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title></title>
+			<link rel="stylesheet" href="media/stylesheet.css" />
+			<link rel="stylesheet" href="media/banner.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+			<div class="banner">
+				<div class="banner-title">Structures_Graph</div>
+				<div class="banner-menu">
+	        <table cellpadding="0" cellspacing="0" style="width: 100%">
+	          <tr>
+              <td>
+								              </td>
+              <td style="width: 2em">&nbsp;</td>
+              <td style="text-align: right">
+								              </td>
+						</tr>
+          </table>
+				</div>
+			</div>
+		</body>
+	</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/html/todolist.html b/lib/docs/Structures_Graph/docs/html/todolist.html
new file mode 100644
index 00000000..597eb4f1
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/html/todolist.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+		<head>
+			<!-- template designed by Marco Von Ballmoos -->
+			<title>Todo List</title>
+			<link rel="stylesheet" href="media/stylesheet.css" />
+			<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+		</head>
+		<body>
+						<div align="center"><h1>Todo List</h1></div>
+<h2>Structures_Graph</h2>
+<h3><a href="Structures_Graph/Structures_Graph.html#methodremoveNode">Structures_Graph::removeNode()</a></h3>
+<ul>
+    <li>This is unimplemented</li>
+</ul>
+	<p class="notes" id="credit">
+		Documentation generated on Fri, 30 Jan 2004 16:37:29 +0000 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.3</a>
+	</p>
+	</body>
+</html>
\ No newline at end of file
diff --git a/lib/docs/Structures_Graph/docs/tutorials/Structures_Graph/Structures_Graph.pkg b/lib/docs/Structures_Graph/docs/tutorials/Structures_Graph/Structures_Graph.pkg
new file mode 100644
index 00000000..23def415
--- /dev/null
+++ b/lib/docs/Structures_Graph/docs/tutorials/Structures_Graph/Structures_Graph.pkg
@@ -0,0 +1,98 @@
+<refentry id="{@id package.database.structures_graph.tutorial}">
+ <refnamediv>
+  <refname><classname>Structures_Graph</classname> Tutorial</refname>
+  <refpurpose>A first tour of graph datastructure manipulation</refpurpose>
+ </refnamediv>
+ <refsect1 id="{@id package.database.structures_graph.tutorial.intro}">
+  <title>Introduction</title>
+  <para>
+  Structures_Graph is a package for creating and manipulating graph datastructures. A graph is a set of objects, called nodes, connected by arcs. When used as a datastructure, usually nodes contain data, and arcs represent relationships between nodes. When arcs have a direction, and can be travelled only one way, graphs are said to be directed. When arcs have no direction, and can always be travelled both ways, graphs are said to be non directed.
+  </para>
+  <para>
+  Structures_Graph provides an object oriented API to create and directly query a graph, as well as a set of Manipulator classes to extract information from the graph.
+  </para>
+ </refsect1>
+ <refsect1 id="{@id package.database.structures_graph.tutorial.creation}">
+  <title>Creating a Graph</title>
+  <para>
+   Creating a graph is done using the simple constructor:
+   <programlisting>
+    <![CDATA[
+require_once 'Structures/Graph.php';
+
+$directedGraph =& new Structures_Graph(true);
+$nonDirectedGraph =& new Structures_Graph(false);
+    ]]>
+   </programlisting>
+   and passing the constructor a flag telling it whether the graph should be directed. A directed graph will always be directed during its lifetime. It's a permanent characteristic.
+  </para>
+  <para>
+  To fill out the graph, we'll need to create some nodes, and then call Graph::addNode.
+   <programlisting>
+    <![CDATA[
+require_once 'Structures/Graph/Node.php';
+
+$nodeOne =& new Structures_Graph_Node();
+$nodeTwo =& new Structures_Graph_Node();
+$nodeThree =& new Structures_Graph_Node();
+
+$directedGraph->addNode(&$nodeOne);
+$directedGraph->addNode(&$nodeTwo);
+$directedGraph->addNode(&$nodeThree);
+    ]]>
+   </programlisting>
+   and then setup the arcs:
+   <programlisting>
+    <![CDATA[
+$nodeOne->connectTo($nodeTwo);
+$nodeOne->connectTo($nodeThree);
+    ]]>
+   </programlisting>
+   Note that arcs can only be created after the nodes have been inserted into the graph. 
+  </para>
+ </refsect1>
+ <refsect1 id="{@id package.database.structures_graph.tutorial.nodesanddata}">
+  <title>Associating Data</title>
+  <para>
+  Graphs are only useful as datastructures if they can hold data. Structure_Graph stores data in nodes. Each node contains a setter and a getter for its data.
+   <programlisting>
+    <![CDATA[
+$nodeOne->setData("Node One's Data is a String");
+$nodeTwo->setData(1976);
+$nodeThree->setData('Some other string');
+
+print("NodeTwo's Data is an integer: " . $nodeTwo->getData());
+    ]]>
+   </programlisting>
+  </para>
+  <para>
+  Structure_Graph nodes can also store metadata, alongside with the main data. Metadata differs from regular data just because it is stored under a key, making it possible to store more than one data reference per node. The metadata getter and setter need the key to perform the operation:
+   <programlisting>
+    <![CDATA[
+$nodeOne->setMetadata('example key', "Node One's Sample Metadata");
+print("Metadata stored under key 'example key' in node one: " . $nodeOne->getMetadata('example key'));
+$nodeOne->unsetMetadata('example key');
+    ]]>
+   </programlisting>
+  </para>
+ </refsect1>
+ <refsect1 id="{@id package.database.structures_graph.tutorial.querying}">
+  <title>Querying a Graph</title>
+  <para>
+  Structures_Graph provides for basic querying of the graph:
+   <programlisting>
+    <![CDATA[
+// Nodes are able to calculate their indegree and outdegree
+print("NodeOne's inDegree: " . $nodeOne->inDegree());
+print("NodeOne's outDegree: " . $nodeOne->outDegree());
+
+// and naturally, nodes can report on their arcs
+$arcs = $nodeOne->getNeighbours();
+for ($i=0;$i<sizeof($arcs);$i++) {
+    print("NodeOne has an arc to " . $arcs[$i]->getData());
+}
+    ]]>
+   </programlisting>
+  </para>
+ </refsect1>
+</refentry>
diff --git a/lib/docs/UNL_DWT/docs/examples/Template_style1.php b/lib/docs/UNL_DWT/docs/examples/Template_style1.php
new file mode 100644
index 00000000..69514f23
--- /dev/null
+++ b/lib/docs/UNL_DWT/docs/examples/Template_style1.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Template Definition for template_style1.dwt
+ */
+require_once 'UNL/DWT.php';
+
+class UNL_DWT_Template_style1 extends UNL_DWT 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    var $__template = 'Template_style1.tpl';                                // template name
+    var $doctitle = "<title>Sample Template Style 1</title>";                       // string()  
+    var $head = "";                           // string()  
+    var $header = "Header";                         // string()  
+    var $leftnav = "<p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut. </p>";                        // string()  
+    var $content = "<h2>Subheading</h2> <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. </p> <p> Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </p>";                        // string()  
+    var $footer = "Footer";                         // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_DWT_Template_style1',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/docs/UNL_DWT/docs/examples/Template_style1.tpl b/lib/docs/UNL_DWT/docs/examples/Template_style1.tpl
new file mode 100644
index 00000000..bd63d040
--- /dev/null
+++ b/lib/docs/UNL_DWT/docs/examples/Template_style1.tpl
@@ -0,0 +1,86 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><!-- InstanceBegin template="/Templates/template_style1.dwt" codeOutsideHTMLIsLocked="false" -->
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<!-- InstanceBeginEditable name="doctitle" -->
+<title>Sample Template Style 1</title>
+<!-- InstanceEndEditable -->
+<style type="text/css">
+#container
+{
+width: 90%;
+margin: 10px auto;
+background-color: #fff;
+color: #333;
+border: 1px solid gray;
+line-height: 130%;
+}
+#top
+{
+padding: .5em;
+background-color: #ddd;
+border-bottom: 1px solid gray;
+}
+#top h1
+{
+padding: 0;
+margin: 0;
+}
+#leftnav
+{
+float: left;
+width: 160px;
+margin: 0;
+padding: 1em;
+}
+#content
+{
+margin-left: 200px;
+border-left: 1px solid gray;
+padding: 1em;
+max-width: 36em;
+}
+#footer
+{
+clear: both;
+margin: 0;
+padding: .5em;
+color: #333;
+background-color: #ddd;
+border-top: 1px solid gray;
+}
+#leftnav p { margin: 0 0 1em 0; }
+#content h2 { margin: 0 0 .5em 0; }
+</style>
+<!-- InstanceBeginEditable name="head" -->
+<!-- InstanceEndEditable -->
+</head>
+<body>
+<div id="container">
+<div id="top">
+<h1>
+<!-- InstanceBeginEditable name="header" -->
+Header
+<!-- InstanceEndEditable -->
+</h1>
+</div>
+<div id="leftnav">
+<!-- InstanceBeginEditable name="leftnav" -->
+    <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut. </p>
+<!-- InstanceEndEditable -->
+</div>
+<div id="content">
+<!-- InstanceBeginEditable name="content" -->
+    <h2>Subheading</h2>
+    <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. </p>
+    <p> Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </p>
+<!-- InstanceEndEditable -->
+</div>
+<div id="footer">
+<!-- InstanceBeginEditable name="footer" -->
+Footer
+<!-- InstanceEndEditable -->
+</div>
+</div>
+</body>
+</html>
diff --git a/lib/docs/UNL_DWT/docs/examples/example.ini b/lib/docs/UNL_DWT/docs/examples/example.ini
new file mode 100644
index 00000000..09da8e95
--- /dev/null
+++ b/lib/docs/UNL_DWT/docs/examples/example.ini
@@ -0,0 +1,5 @@
+[UNL_DWT]
+dwt_location    = /Users/bbieber/Documents/workspace/UNL_Elgg/lib/docs/UNL_DWT/docs/examples/
+class_location  = /Users/bbieber/Documents/workspace/UNL_Elgg/lib/docs/UNL_DWT/docs/examples/
+tpl_location	= /Users/bbieber/Documents/workspace/UNL_Elgg/lib/docs/UNL_DWT/docs/examples/
+class_prefix    = UNL_DWT_
\ No newline at end of file
diff --git a/lib/docs/UNL_DWT/docs/examples/example_style1.php b/lib/docs/UNL_DWT/docs/examples/example_style1.php
new file mode 100644
index 00000000..bf6dacd7
--- /dev/null
+++ b/lib/docs/UNL_DWT/docs/examples/example_style1.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * This example uses the DWT object generated by: '/usr/local/bin/php /Users/bbieber/Documents/workspace/UNL_Elgg/lib/php/UNL/DWT/createTemplates.php /Users/bbieber/Documents/workspace/UNL_Elgg/lib/docs/UNL_DWT/docs/examples/example.ini'
+ * 
+ */
+ini_set('display_errors',true);
+error_reporting(E_ALL|E_STRICT);
+
+require_once 'UNL/DWT.php';
+if ('/Users/bbieber/Documents/workspace/UNL_Elgg/lib/data' == '@'.'DATA_DIR@') {
+    $configfile = 'example.test.ini';
+} else {
+    $configfile = '/Users/bbieber/Documents/workspace/UNL_Elgg/lib/docs/UNL_DWT/docs/examples/example.ini';
+}
+$config = parse_ini_file($configfile, true);
+foreach($config as $class=>$values) {
+   UNL_DWT::$options = $values;
+}
+$page = UNL_DWT::factory('Template_style1');
+$page->header  = "Example Using Template Style 1";
+$page->leftnav = "<ul><li><a href='http://pear.unl.edu/'>UNL PEAR Channel</a></li></ul>";
+$page->content = "<p>This example demonstrates the usefulness of the DWT object generator for Dreamweaver Templates.</p>";
+$page->content .= "<p>Included with the DWT package is a Dreamweaver template with 4 editable regions [template_style1.dwt]. This page is rendered using the DWT class created from that template.</p>";
+$page->content .= "<p>To create classes for your Templates, create a .ini file with the location of your Dreamweaver templates (dwt's) and then run the createTemplates.php script to generate objects for each of your template files.</p>";
+$page->content .= "<p>Here is the ini file used to create the Template_style1:<pre><code>".file_get_contents($configfile)."</code></pre></p>";
+$page->content .= "<p>And the command used to create the template classes:<pre><code>/usr/local/bin/php /Users/bbieber/Documents/workspace/UNL_Elgg/lib/php/UNL/DWT/createTemplates.php /Users/bbieber/Documents/workspace/UNL_Elgg/lib/docs/UNL_DWT/docs/examples/example.ini</code></pre></p>";
+$page->footer  = "<a href='mailto:brett.bieber@gmail.com'>Brett Bieber</a>";
+echo $page->toHtml();
\ No newline at end of file
diff --git a/lib/docs/UNL_DWT/docs/examples/scanner_example.php b/lib/docs/UNL_DWT/docs/examples/scanner_example.php
new file mode 100644
index 00000000..c0ba1901
--- /dev/null
+++ b/lib/docs/UNL_DWT/docs/examples/scanner_example.php
@@ -0,0 +1,11 @@
+<?php
+require_once 'UNL/DWT/Scanner.php';
+
+$file = file_get_contents(dirname(__FILE__).'/'.'template_style1.dwt');
+
+$scanned = new UNL_DWT_Scanner($file);
+
+echo $scanned->leftnav;
+echo $scanned->content;
+
+?>
\ No newline at end of file
diff --git a/lib/docs/UNL_DWT/docs/examples/template_style1.dwt b/lib/docs/UNL_DWT/docs/examples/template_style1.dwt
new file mode 100644
index 00000000..f22ce6ab
--- /dev/null
+++ b/lib/docs/UNL_DWT/docs/examples/template_style1.dwt
@@ -0,0 +1,80 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<!-- TemplateBeginEditable name="doctitle" -->
+<title>Sample Template Style 1</title>
+<!-- TemplateEndEditable -->
+<style type="text/css">
+#container
+{
+width: 90%;
+margin: 10px auto;
+background-color: #fff;
+color: #333;
+border: 1px solid gray;
+line-height: 130%;
+}
+
+#top
+{
+padding: .5em;
+background-color: #ddd;
+border-bottom: 1px solid gray;
+}
+
+#top h1
+{
+padding: 0;
+margin: 0;
+}
+
+#leftnav
+{
+float: left;
+width: 160px;
+margin: 0;
+padding: 1em;
+}
+
+#content
+{
+margin-left: 200px;
+border-left: 1px solid gray;
+padding: 1em;
+max-width: 36em;
+}
+
+#footer
+{
+clear: both;
+margin: 0;
+padding: .5em;
+color: #333;
+background-color: #ddd;
+border-top: 1px solid gray;
+}
+
+#leftnav p { margin: 0 0 1em 0; }
+#content h2 { margin: 0 0 .5em 0; }
+</style>
+<!-- TemplateBeginEditable name="head" --><!-- TemplateEndEditable -->
+</head>
+
+<body>
+<div id="container">
+<div id="top">
+<h1><!-- TemplateBeginEditable name="header" -->Header<!-- TemplateEndEditable --></h1>
+</div>
+<div id="leftnav"><!-- TemplateBeginEditable name="leftnav" -->
+    <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut. </p>
+<!-- TemplateEndEditable --></div>
+<div id="content"><!-- TemplateBeginEditable name="content" -->
+    <h2>Subheading</h2>
+    <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. </p>
+    <p> Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </p>
+<!-- TemplateEndEditable --></div>
+<div id="footer"><!-- TemplateBeginEditable name="footer" -->Footer<!-- TemplateEndEditable --></div>
+</div>
+</body>
+</html>
diff --git a/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/config.inc.php b/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/config.inc.php
new file mode 100644
index 00000000..eecf1ba0
--- /dev/null
+++ b/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/config.inc.php
@@ -0,0 +1,4 @@
+<?php
+require_once 'UNL/Autoload.php';
+
+set_include_path(dirname(__FILE__).'/../src'.PATH_SEPARATOR.get_include_path());
\ No newline at end of file
diff --git a/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getExactMatches.php b/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getExactMatches.php
new file mode 100644
index 00000000..70e3def0
--- /dev/null
+++ b/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getExactMatches.php
@@ -0,0 +1,10 @@
+<?php
+require_once 'config.inc.php';
+
+$pf = new UNL_Peoplefinder();
+
+$results = $pf->getExactMatches('Bieber');
+
+foreach ($results as $uid) {
+    echo $uid->cn.'<br />';
+}
\ No newline at end of file
diff --git a/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getLikeMatches.php b/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getLikeMatches.php
new file mode 100644
index 00000000..9428199b
--- /dev/null
+++ b/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getLikeMatches.php
@@ -0,0 +1,10 @@
+<?php
+require_once 'config.inc.php';
+
+$pf = new UNL_Peoplefinder();
+
+$results = $pf->getLikeMatches('Bieber');
+
+foreach ($results as $uid) {
+    echo $uid->cn.'<br />';
+}
\ No newline at end of file
diff --git a/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getUID.php b/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getUID.php
new file mode 100644
index 00000000..e54d6f11
--- /dev/null
+++ b/lib/docs/UNL_Peoplefinder/pear.unl.edu/examples/getUID.php
@@ -0,0 +1,7 @@
+<?php
+require_once 'config.inc.php';
+
+$pf = new UNL_Peoplefinder();
+$uid = $pf->getUID('bbieber2');
+echo 'uid:' . $uid->uid;
+echo ' cn:' . $uid->cn;
\ No newline at end of file
diff --git a/lib/docs/UNL_Templates/docs/examples/customization/CustomClass.php b/lib/docs/UNL_Templates/docs/examples/customization/CustomClass.php
new file mode 100644
index 00000000..35f99cca
--- /dev/null
+++ b/lib/docs/UNL_Templates/docs/examples/customization/CustomClass.php
@@ -0,0 +1,102 @@
+<?php
+
+require_once 'UNL/Templates.php';
+
+class CustomClass
+{
+    public $template;
+    
+    function __construct()
+    {
+        $this->template = UNL_Templates::factory('Fixed');
+        $this->autoGenerate('Department of Mathematics', 'Math');
+    }
+    
+    function autoGenerateBreadcrumbs($unitShortName, array $organization = array('name' => 'UNL', 'url' => 'http://www.unl.edu/'), $delimiter = ' | ')
+    {
+        $fileName             = array_shift(explode('.', array_pop(explode(DIRECTORY_SEPARATOR, htmlentities($_SERVER['SCRIPT_NAME'])))));
+        $generatedBreadcrumbs = '';
+        $generatedDocTitle    = '';
+        
+        $isIndexPage = preg_match('/index/', $fileName);
+        
+        $searchFor = array($_SERVER['DOCUMENT_ROOT'], '_');
+        $replaceWith = array($unitShortName, ' ');
+        
+        $keys = explode(DIRECTORY_SEPARATOR, str_replace($searchFor, $replaceWith, getcwd()));
+        $values = array();
+        
+        for ($i = count($keys)-1; $i >= 0; $i--) {
+            array_push($values, str_replace($_SERVER['DOCUMENT_ROOT'], '', implode(DIRECTORY_SEPARATOR, explode(DIRECTORY_SEPARATOR, getcwd(), -$i)).DIRECTORY_SEPARATOR));
+        }
+        
+        for ($i = 0; $i < count($keys)  - $isIndexPage ; $i++) {
+            $generatedBreadcrumbs .= '<li><a href="'. $values[$i] .'">' . ucwords($keys[$i]) .' </a></li> '; 
+            $generatedDocTitle    .= ucwords($keys[$i]) . $delimiter;
+        }
+    
+        if ($isIndexPage) {
+            $generatedBreadcrumbs .= '<li>'. ucwords(end($keys)) .'</li></ul>';
+            $generatedDocTitle    .= ucwords(end($keys));
+        } else {
+            $generatedBreadcrumbs .= '<li>'. ucwords($fileName) .'</li></ul>';
+            $generatedDocTitle    .= ucwords($fileName);
+        }
+        
+        $doctitle    = '<title>' . $organization['name'] . $delimiter . $generatedDocTitle . '</title>';
+        $breadcrumbs = '<ul><li class="first"><a href="'.$organization['url'].'">'.$organization['name'].'</a></li> ' . $generatedBreadcrumbs;
+    
+        $this->template->doctitle = $doctitle;
+        $this->template->breadcrumbs = $breadcrumbs;
+    }
+    
+    /**
+     * This function finds an html file with the content of the body file and
+     * inserts it into the template.
+     *
+     * @param string $unitName Name of the department/unit
+     * 
+     * @return void
+     */
+    function autoGenerateBody($unitName)
+    {
+        // The file that has the body is in the same dir with the same base file name.
+        $bodyFile = array_shift(explode('.', array_pop(explode(DIRECTORY_SEPARATOR, htmlentities($_SERVER['SCRIPT_NAME']))))) . '.html';
+    
+        $maincontentarea_array = file($bodyFile);
+        $maincontentarea       = implode(' ', $maincontentarea_array);
+        $subhead               = preg_replace('/<!--\s*(.+)\s*-->/i', '$1', array_shift($maincontentarea_array));
+    
+        $titlegraphic = '<h1>' . $unitName . '</h1><h2>' . $subhead    . '</h2>';
+    
+        $this->template->titlegraphic    = $titlegraphic;
+        $this->template->maincontentarea = $maincontentarea;
+    }
+    
+    /**
+     * Autogenerate the contents of a page.
+     *
+     * @param string $unitName      name of the unit/department
+     * @param string $unitShortName abbreviation for the unit
+     * @param array  $organization  organization heirarchy
+     * @param string $delimiter     what separates files
+     * 
+     * @return void
+     */
+    function autoGenerate($unitName, $unitShortName, array $organization = array('name' => 'UNL', 'url' => 'http://www.unl.edu/'), $delimiter = ' | ')
+    {
+        $this->autoGenerateBreadcrumbs($unitShortName, $organization, $delimiter);
+        $this->autoGenerateBody($unitName);
+    }
+    
+    /**
+     * renders a string representation of the template
+     *
+     * @return unknown
+     */
+    function __toString()
+    {
+        return $this->template->toHtml();
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/docs/UNL_Templates/docs/examples/customization/customization_example.html b/lib/docs/UNL_Templates/docs/examples/customization/customization_example.html
new file mode 100644
index 00000000..0b9cbc15
--- /dev/null
+++ b/lib/docs/UNL_Templates/docs/examples/customization/customization_example.html
@@ -0,0 +1 @@
+This is the main content of the body.
\ No newline at end of file
diff --git a/lib/docs/UNL_Templates/docs/examples/customization/customization_example.php b/lib/docs/UNL_Templates/docs/examples/customization/customization_example.php
new file mode 100644
index 00000000..4cd36edb
--- /dev/null
+++ b/lib/docs/UNL_Templates/docs/examples/customization/customization_example.php
@@ -0,0 +1,8 @@
+<?php
+require_once 'CustomClass.php';
+
+$page = new CustomClass();
+
+echo $page;
+
+?>
\ No newline at end of file
diff --git a/lib/docs/UNL_Templates/docs/examples/example1.php b/lib/docs/UNL_Templates/docs/examples/example1.php
new file mode 100644
index 00000000..912af5ef
--- /dev/null
+++ b/lib/docs/UNL_Templates/docs/examples/example1.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * This example demonstrates the usage of the UNL Templates.
+ *
+ * 
+ * @package UNL_Templates
+ */
+
+ini_set('display_errors',true);
+error_reporting(E_STRICT);
+set_include_path(realpath(dirname(__FILE__).'/../../').PATH_SEPARATOR.realpath(dirname(__FILE__).'/../../../UNL_DWT').PATH_SEPARATOR.realpath(dirname(__FILE__).'/includes/pear/php'));
+require_once 'UNL/Templates.php';
+UNL_Templates::$options['version'] = 3;
+$page = UNL_Templates::factory('Fixed', array('sharedcodepath' => 'sharedcode'));
+$page->addScript('test.js');
+$page->addScriptDeclaration('function sayHello(){alert("Hello!");}');
+$page->addStylesheet('foo.css');
+$page->addStyleDeclaration('.foo {font-weight:bold;}');
+$page->titlegraphic     = '<h1>Hello UNL Templates</h1>';
+$page->maincontentarea  = '<p>This is my main content.</p>';
+$page->navlinks         = '<ul><li>Hello world!</li></ul>';
+$page->leftRandomPromo  = '';
+$page->maincontentarea  .= highlight_file(__FILE__, true);
+$page->loadSharedcodeFiles();
+echo $page;
diff --git a/lib/docs/UNL_Templates/docs/examples/scanner.php b/lib/docs/UNL_Templates/docs/examples/scanner.php
new file mode 100644
index 00000000..2226c08c
--- /dev/null
+++ b/lib/docs/UNL_Templates/docs/examples/scanner.php
@@ -0,0 +1,11 @@
+<?php
+highlight_file(__FILE__);
+require_once 'UNL/Templates/Scanner.php';
+
+$html = file_get_contents('http://www.unl.edu/ucomm/unltoday/');
+
+// Scan this rendered UNL template-based page for editable regions
+$scanner = new UNL_Templates_Scanner($html);
+
+// All editable regions are now member variables of the scanner object.
+echo $scanner->maincontentarea;
diff --git a/lib/docs/XML_Util/XML/examples/example.php b/lib/docs/XML_Util/XML/examples/example.php
new file mode 100644
index 00000000..920ebd97
--- /dev/null
+++ b/lib/docs/XML_Util/XML/examples/example.php
@@ -0,0 +1,299 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Examples (file #1)
+ *
+ * several examples for the methods of XML_Util
+ * 
+ * PHP versions 4 and 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2003-2008 Stephan Schmidt <schst@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 name of the author 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   XML
+ * @package    XML_Util
+ * @subpackage Examples
+ * @author     Stephan Schmidt <schst@php.net>
+ * @copyright  2003-2008 Stephan Schmidt <schst@php.net>
+ * @license    http://opensource.org/licenses/bsd-license New BSD License
+ * @version    CVS: $Id: example.php,v 1.17 2008/05/05 19:05:28 ashnazg Exp $
+ * @link       http://pear.php.net/package/XML_Util
+ */
+
+    /**
+     * set error level
+     */
+    error_reporting(E_ALL);
+
+    require_once 'XML/Util.php';
+    
+    /**
+     * replacing XML entities
+     */
+    print 'replace XML entities:<br>';
+    print XML_Util::replaceEntities('This string contains < & >.');
+    print "\n<br><br>\n";
+
+    /**
+     * reversing XML entities
+     */
+    print 'replace XML entities:<br>';
+    print XML_Util::reverseEntities('This string contains &lt; &amp; &gt;.');
+    print "\n<br><br>\n";
+
+    /**
+     * building XML declaration
+     */
+    print 'building XML declaration:<br>';
+    print htmlspecialchars(XML_Util::getXMLDeclaration());
+    print "\n<br><br>\n";
+
+    print 'building XML declaration with additional attributes:<br>';
+    print htmlspecialchars(XML_Util::getXMLDeclaration('1.0', 'UTF-8', true));
+    print "\n<br><br>\n";
+
+    /**
+     * building document type declaration
+     */
+    print 'building DocType declaration:<br>';
+    print htmlspecialchars(XML_Util::getDocTypeDeclaration('package', 
+        'http://pear.php.net/dtd/package-1.0'));
+    print "\n<br><br>\n";
+
+    print 'building DocType declaration with public ID (does not exist):<br>';
+    print htmlspecialchars(XML_Util::getDocTypeDeclaration('package', 
+        array('uri' => 'http://pear.php.net/dtd/package-1.0', 
+            'id' => '-//PHP//PEAR/DTD PACKAGE 0.1')));
+    print "\n<br><br>\n";
+
+    print 'building DocType declaration with internal DTD:<br>';
+    print '<pre>';
+    print htmlspecialchars(XML_Util::getDocTypeDeclaration('package', 
+        'http://pear.php.net/dtd/package-1.0', 
+        '<!ELEMENT additionalInfo (#PCDATA)>'));
+    print '</pre>';
+    print "\n<br><br>\n";
+
+    /**
+     * creating an attribute string
+     */
+    $att = array(
+        'foo'  => 'bar',
+        'argh' => 'tomato'
+    );
+
+    print 'converting array to string:<br>';
+    print XML_Util::attributesToString($att);
+    print "\n<br><br>\n";
+
+
+    /**
+     * creating an attribute string with linebreaks
+     */
+    $att = array(
+        'foo'  => 'bar',
+        'argh' => 'tomato'
+    );
+
+    print 'converting array to string (including line breaks):<br>';
+    print '<pre>';
+    print XML_Util::attributesToString($att, true, true);
+    print '</pre>';
+    print "\n<br><br>\n";
+
+
+    /**
+     * splitting a qualified tag name
+     */
+    print 'splitting qualified tag name:<br>';
+    print '<pre>';
+    print_r(XML_Util::splitQualifiedName('xslt:stylesheet'));
+    print '</pre>';
+    print "\n<br>\n";
+
+
+    /**
+     * splitting a qualified tag name (no namespace)
+     */
+    print 'splitting qualified tag name (no namespace):<br>';
+    print '<pre>';
+    print_r(XML_Util::splitQualifiedName('foo'));
+    print '</pre>';
+    print "\n<br>\n";
+
+    /**
+     * splitting a qualified tag name (no namespace, but default namespace specified)
+     */
+    print 'splitting qualified tag name '
+        . '(no namespace, but default namespace specified):<br>';
+    print '<pre>';
+    print_r(XML_Util::splitQualifiedName('foo', 'bar'));
+    print '</pre>';
+    print "\n<br>\n";
+
+    /**
+     * verifying XML names
+     */
+    print 'verifying \'My private tag\':<br>';
+    print '<pre>';
+    print_r(XML_Util::isValidname('My Private Tag'));
+    print '</pre>';
+    print "\n<br><br>\n";
+    
+    print 'verifying \'-MyTag\':<br>';
+    print '<pre>';
+    print_r(XML_Util::isValidname('-MyTag'));
+    print '</pre>';
+    print "\n<br><br>\n";
+
+    /**
+     * creating an XML tag
+     */
+    $tag = array(
+        'namespace'  => 'foo',
+        'localPart'  => 'bar',
+        'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'),
+        'content'    => 'I\'m inside the tag'
+    );
+
+    print 'creating a tag with namespace and local part:<br>';
+    print htmlentities(XML_Util::createTagFromArray($tag));
+    print "\n<br><br>\n";
+
+    /**
+     * creating an XML tag
+     */
+    $tag = array(
+        'qname'        => 'foo:bar',
+        'namespaceUri' => 'http://foo.com',
+        'attributes'   => array('key' => 'value', 'argh' => 'fruit&vegetable'),
+        'content'      => 'I\'m inside the tag'
+    );
+
+    print 'creating a tag with qualified name and namespaceUri:<br>';
+    print htmlentities(XML_Util::createTagFromArray($tag));
+    print "\n<br><br>\n";
+
+    /**
+     * creating an XML tag
+     */
+    $tag = array(
+        'qname'        => 'bar',
+        'namespaceUri' => 'http://foo.com',
+        'attributes'   => array('key' => 'value', 'argh' => 'fruit&vegetable')
+    );
+
+    print 'creating an empty tag without namespace but namespace Uri:<br>';
+    print htmlentities(XML_Util::createTagFromArray($tag));
+    print "\n<br><br>\n";
+
+    /**
+     * creating an XML tag with more namespaces
+     */
+    $tag = array(
+        'namespace'   => 'foo',
+        'localPart'   => 'bar',
+        'attributes'  => array('key' => 'value', 'argh' => 'fruit&vegetable'),
+        'content'     => 'I\'m inside the tag',
+        'namespaces'  => array(
+            'bar'  => 'http://bar.com',
+            'pear' => 'http://pear.php.net',
+        )
+    );
+
+    print 'creating an XML tag with more namespaces:<br />';
+    print htmlentities(XML_Util::createTagFromArray($tag));
+    print "\n<br><br>\n";
+
+    /**
+     * creating an XML tag with a CData Section
+     */
+    $tag = array(
+        'qname'      => 'foo',
+        'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'),
+        'content'    => 'I\'m inside the tag'
+    );
+
+    print 'creating a tag with CData section:<br>';
+    print htmlentities(XML_Util::createTagFromArray($tag, XML_UTIL_CDATA_SECTION));
+    print "\n<br><br>\n";
+
+    /**
+     * creating an XML tag with a CData Section
+     */
+    $tag = array(
+        'qname'      => 'foo',
+        'attributes' => array('key' => 'value', 'argh' => 't�t�'),
+        'content'    => 
+            'Also XHTML-tags can be created '
+            . 'and HTML entities can be replaced � � � � <>.'
+    );
+
+    print 'creating a tag with HTML entities:<br>';
+    print htmlentities(XML_Util::createTagFromArray($tag, XML_UTIL_ENTITIES_HTML));
+    print "\n<br><br>\n";
+
+    /**
+    * creating an XML tag with createTag
+    */
+    print 'creating a tag with createTag:<br>';
+    print htmlentities(XML_Util::createTag('myNs:myTag', 
+        array('foo' => 'bar'), 
+        'This is inside the tag', 
+        'http://www.w3c.org/myNs#'));
+    print "\n<br><br>\n";
+
+    
+    /**
+     * trying to create an XML tag with an array as content
+     */
+    $tag = array(
+        'qname'   => 'bar',
+        'content' => array('foo' => 'bar')
+    );
+    print 'trying to create an XML tag with an array as content:<br>';
+    print '<pre>';
+    print_r(XML_Util::createTagFromArray($tag));
+    print '</pre>';
+    print "\n<br><br>\n";
+    
+    /**
+     * trying to create an XML tag without a name
+     */
+    $tag = array(
+        'attributes' => array('foo' => 'bar'),
+    );
+    print 'trying to create an XML tag without a name:<br>';
+    print '<pre>';
+    print_r(XML_Util::createTagFromArray($tag));
+    print '</pre>';
+    print "\n<br><br>\n";
+?>
diff --git a/lib/docs/XML_Util/XML/examples/example2.php b/lib/docs/XML_Util/XML/examples/example2.php
new file mode 100644
index 00000000..0bf9b743
--- /dev/null
+++ b/lib/docs/XML_Util/XML/examples/example2.php
@@ -0,0 +1,145 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Examples (file #2)
+ *
+ * several examples for the methods of XML_Util
+ * 
+ * PHP versions 4 and 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2003-2008 Stephan Schmidt <schst@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 name of the author 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   XML
+ * @package    XML_Util
+ * @subpackage Examples
+ * @author     Stephan Schmidt <schst@php.net>
+ * @copyright  2003-2008 Stephan Schmidt <schst@php.net>
+ * @license    http://opensource.org/licenses/bsd-license New BSD License
+ * @version    CVS: $Id: example2.php,v 1.11 2008/05/05 19:03:13 ashnazg Exp $
+ * @link       http://pear.php.net/package/XML_Util
+ */
+
+    /**
+     * set error level
+     */
+    error_reporting(E_ALL);
+
+    require_once 'XML/Util.php';
+
+    /**
+     * creating a start element
+     */
+    print 'creating a start element:<br>';
+    print htmlentities(XML_Util::createStartElement('myNs:myTag', 
+        array('foo' => 'bar'), 'http://www.w3c.org/myNs#'));
+    print "\n<br><br>\n";
+
+
+    /**
+     * creating a start element
+     */
+    print 'creating a start element:<br>';
+    print htmlentities(XML_Util::createStartElement('myTag', 
+        array(), 'http://www.w3c.org/myNs#'));
+    print "\n<br><br>\n";
+
+    /**
+     * creating a start element
+     */
+    print 'creating a start element:<br>';
+    print '<pre>';
+    print htmlentities(XML_Util::createStartElement('myTag', 
+        array('foo' => 'bar', 'argh' => 'tomato'), 
+        'http://www.w3c.org/myNs#', true));
+    print '</pre>';
+    print "\n<br><br>\n";
+
+
+    /**
+     * creating an end element
+     */
+    print 'creating an end element:<br>';
+    print htmlentities(XML_Util::createEndElement('myNs:myTag'));
+    print "\n<br><br>\n";
+
+    /**
+     * creating a CData section
+     */
+    print 'creating a CData section:<br>';
+    print htmlentities(XML_Util::createCDataSection('I am content.'));
+    print "\n<br><br>\n";
+
+    /**
+     * creating a comment
+     */
+    print 'creating a comment:<br>';
+    print htmlentities(XML_Util::createComment('I am a comment.'));
+    print "\n<br><br>\n";
+
+    /**
+     * creating an XML tag with multiline mode
+     */
+    $tag = array(
+        'qname'        => 'foo:bar',
+        'namespaceUri' => 'http://foo.com',
+        'attributes'   => array('key' => 'value', 'argh' => 'fruit&vegetable'),
+        'content'      => 'I\'m inside the tag & contain dangerous chars'
+    );
+
+    print 'creating a tag with qualified name and namespaceUri:<br>';
+    print '<pre>';
+    print htmlentities(XML_Util::createTagFromArray($tag, 
+        XML_UTIL_REPLACE_ENTITIES, true));
+    print '</pre>';
+    print "\n<br><br>\n";
+
+    /**
+     * create an attribute string without replacing the entities
+     */
+    $atts = array('series' => 'Starsky &amp; Hutch', 'channel' => 'ABC');
+    print 'creating a attribute string, '
+        . 'entities in values already had been replaced:<br>';
+    print htmlentities(XML_Util::attributesToString($atts, 
+        true, false, false, false, XML_UTIL_ENTITIES_NONE));
+    print "\n<br><br>\n";
+
+    /**
+     * using the array-syntax for attributesToString()
+     */
+    $atts = array('series' => 'Starsky &amp; Hutch', 'channel' => 'ABC');
+    print 'using the array-syntax for attributesToString()<br>';
+    print htmlentities(XML_Util::attributesToString($atts, 
+        array('entities' => XML_UTIL_ENTITIES_NONE)));
+    print "\n<br><br>\n";
+
+
+?>
diff --git a/lib/downloads/Archive_Tar-1.3.3.tgz b/lib/downloads/Archive_Tar-1.3.3.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..2cc3c08fb6bd38e3777a9772cdc9d4d0aa06498b
GIT binary patch
literal 18119
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

literal 0
HcmV?d00001

diff --git a/lib/downloads/Cache_Lite-1.7.8.tgz b/lib/downloads/Cache_Lite-1.7.8.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..b3adfa3078c2e6dd71b7002a9956c7ba615cc8a8
GIT binary patch
literal 30061
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
Ue*Oah0RR6300yr6i2!~A0CaQDng9R*

literal 0
HcmV?d00001

diff --git a/lib/downloads/Console_Getopt-1.2.3.tgz b/lib/downloads/Console_Getopt-1.2.3.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..156a0740d6e55f7afad6501d8c927d7a86de7a9c
GIT binary patch
literal 4011
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
R009600|3TZc+~(#008lK)*b)=

literal 0
HcmV?d00001

diff --git a/lib/downloads/HTTP_Request2-0.5.1.tgz b/lib/downloads/HTTP_Request2-0.5.1.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..1fb02a30c70ae63705bdeaf26bfc1aed1980fafc
GIT binary patch
literal 58027
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%0Dvw4jD1_yOmmyHH=YvPlgS!q8kG<
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

literal 0
HcmV?d00001

diff --git a/lib/downloads/Net_URL2-0.3.0.tgz b/lib/downloads/Net_URL2-0.3.0.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..19d38a7154681a396327aeb570b25566592aa7a7
GIT binary patch
literal 8371
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
J7qbAK001SWPCWns

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..7c324d9e16d8e0908ee46dd3f812a9d9f1621d53
GIT binary patch
literal 8379
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
R009600|3NzWMTlG005WZXXF3?

literal 0
HcmV?d00001

diff --git a/lib/downloads/PEAR-1.9.0.tgz b/lib/downloads/PEAR-1.9.0.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..3c526dc594d6a2f3044c5fb479361b42b4394cf8
GIT binary patch
literal 291634
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%0DkNPrZt5D$^Gq{<@hiet%F>^ZI4>%kZ4
zC6(fWF&sicO6&4MT29-_Msefq%23Iwa2epNMcJA3Y=IS`F3AkW<nPujnFKQ>v=Ooj
zcpna4D`_RzH%u$z88d>oRX!aBB`NLhQ;ao{|JINJtWy5ldbIuM@s=k4ZEtQqx|jbx
zZ~ia71H2C0DLt>aS$bZ<l6rX7Mb@ZWN)L9Jll%W^aB)F|mfb8HtJ$NL%rv$2?YECV
zTOKj_e0}yzVw<;}M=a%giF_2z7xZSn-w$`1d5kZzA?=tr>Z>OnLwlrC+OcNZWL-)!
zfL5K4Y_?1~GVU$bEZNtjHrbc6c4~t}1Sbj!)K&MiV7{bUHk?$j+N5M%w*kJAGTIQ|
zs21O*O7a@AukA9T?Eg-bW^KySy!=8QXmH-`YIWTK=h}7kAwP9E<qnJEs&`vciur|v
z<VKy6N?u0~p_x|`r2PFd1i1s9eU}fgzlyfLOI7t<rl;>yC4Jwlq3`Z<-F%k~wqK`}
z%LOt0DyCGdF3mkzucX&4IOyutYaPYbwXRug{85j<m#NEZ2hKT#pOA3YnZu6*y_GC}
zMaHCztT8M?X9Eh6k4tHi0!~KZ;ugpu5a8V=f8dSqZ~6u*J<*LzV8%L_u?A*b2E*R<
z30WqW^Nzr+SHQPcEXPvIO;VwOY+vMuqC{lgnrvZ|gl~l;p*sU+M~a+rY<BV#ZDkn>
zz014@GW2S9JUY)Ovzatieln|T$+@9Yg~@Q}NgZfeK)JoiWymtrj^?k$Vea9wh^KP+
ztfM!^w4jCZpnbi32`A0fi=zY%5$q46H<rE!sG9<p2Qi@m6kjs9;*hCIHJBZC@Q&GS
zx|BmMxBE>~;!%Gd(y*aBk87PM%@2$YYD9|cDbVoa<eFusJBzM>qo+iI!frO#ABu{c
z3Xe@~v&OT(t{#)@zedSUF8)1ltL|KK3A1Je9Z#k`6pU6e##6!?y`af5T{_qJPO&H<
z>Mdp1*aN?f^+nPD1aoxOI4$vWAPzSB8;^tu;X3D030{eBcewlY35RE`e$E90juyLI
zu+A7Qp-ulQPJRJs0T*g#LoV%#e288oJ<k_6E*3GDa&Hl(ux#?6YHBbqWVKf%6}Ttj
zw~R^u_?O`CsEcspB%OvS0)`#0eS01TaCYTv<i1d-JfCHZfnPCui(b!Nv2SoRG?h=w
z?pJZWAc2kwoC<ecUs!RxYV_(3v{<yR?1oFnh5wqIq2+H)myXd<xY%KEeQ?pGlwBqn
z|69KDc=98WdKLdv#VD)moGllmCUl8Ug%?|Si@U6rJOmSpc&a@zEBOYek_rD%BzTfP
z6sd`NEw`!hjx4DVrl!?D8__(*8h<iz6^FTeZnW)tlHTPK_6-gJTx^@>3#M-A88`Dg
zaZ;G-ifxZZJBe#4T&nB4E{dIJu7`KJ@K85i+JGk($}=or!Fn09GgGunZWDv0&>;}W
zl989%C=K~|9cnU{b&y(hiwJt}!6-Rh%!zsoDfTDH6fHi}aGr(}^kYq~!c^{oCgFZx
z+KapfHHe9XI#Z$=6KFG~h&i*%LIE1+&rP5NkfekRmQ@7Zg$L~%+inLT((H?4Tynf-
zLPxQw8Gka091TuTae7>iPwg=gN5r!ql2wHc^^nP@Ocy*Xnw>aX6<0H5*K!tg!&U5f
z#hO9@Ef@dB+<G6I`TlKOQ!8Ipy3ydtbP82s#<L*4@L=V=;4}|Y57#3LC-gPfVV?S$
zDykYkIL15eHZGHOUK$N=0%7y%Hn@b$uTPb7M#G!qQ<FQyNnbV;q0n^m2lcwStl}2W
zPDFp5hmhfDt9a6~DU8i-h|_sFsF7!bpGK)tQ-P=<9YBXyypX^9?KcMN`%`cjkiH|l
z5elLh!wpZ3$p}s-vjh@%l5cCHj2hSApd@clhr<|nL(}z}D{{z$?}_RVSe|38_P-4#
z{!97)pTsvj_rIWiP3r%qrm_vV63OR<QIlVY_~HpyA>&2fyC6UJ%Saa@i5^UA60KLH
z5g|mTh(F{{hA*}2NR)E2(yTx_gZ-1D*Ua?AJ5_H{u{p~3Hg=cffSxBlGa0ums}5xh
z8m)Gv6;q=Ns&ej?MX<R&qK(pGj};4Yh1&lAip}Ap6;aHlZQ;Ery6>?OWvYL?oC(PW
z;te6f%}1swX}I5&R}f*mWWkRp#S|Z#GJ43tjsQ}(NK%mjbm2l^ppFVJY3hEdY)-9t
zvjE0XfyYb$0$z2odc15&{@o0Xe6Zy$hGGYoskOvX+46NzC5}bd<FG-V+Y;{B0m`jd
z^&bL91ek`?lb|Z|BK$yja1<}XMp4x^nH>igsliRC7#?SAh7#==0il(W2~eA-2*#EX
zs89?TYeHX?9+Omi^x?l-Nv(}(h$q*K4cXDpUmd)7_Wtd`zfKNcynAx+g#21zq7mW2
z7V1}#MnR_nhVj$vI?8b)N(8IiCEzYe={2fpgv6|EL?}I~CJP`XC`~cksqBGAh4$KG
zxK>R`9cVzhWPbGkpQ;h&Yf+XC*btr%qO#vzYMZF6Ug*R&SQMS=`HTrSy4a~%DG+k)
zE5*c~(Xy2BnKRxhM6plQ#=SBqhh-+4;nST~)uiS`ZaQH}CAg0J;1}}qw+Fyd9t`21
z_5&F7Zx7lH%oSyRWx#DYaP;T)!7VvkB&{XQ2fHv;vJ)y(YKz<kw%)dji`BQY3~bG%
z#`rTBgtS^@Jyj62<_ZKsz#;pOkQ%Moe+*x`W&<?A1=++RlECMJF^fbIJ1yH%(S}yL
zA>;E8QAOj@W_kjdQbwcG01F>e>8s~y0*0mJngSZDaV+NCtSkYtZx!Z_fW4!P;RNvm
z9lH|>V+Ua066+3Kx_(2EM{r9zK1<NUk)UbSN|PXa-<BB1pf%w(cM)^^&WHFSPOf9j
z8pC`jq%|--d^rm*sH*h%se>6e;pCrMYdG9@^|mBDlUFnh?pn=)CD$PztsRgZg>a=2
zh7n0IYMfo6XQ|1P*<v+Z-pbPWMGDOlw_uHNwIVRL>>Xh4QG6B5B4IN}hg@@=BH=KK
zKqccz+3m7uB&;br@|#~<U$d7<(ry`Crq~!Sgte9Xm-1H^qfJ#{p(l&Bs-cyGshO(n
ze6pCl+5_o)8Jxk(CyPCS`r_PU5net;j@oS5)V?l0aH|kj-ZvF*5SGP-%tCEVxUgWo
zT{78R8J}*Y^|=ynkQLrB4+xy!e)Ar%#wX0vzti5hY7;T`zx?2B9e;wq&%*Y)X+Rd;
zoeYmYGa0s#3<Xh^Ax6D5yUx;Hwn*|@W+Xib<%#!5il=I8P)b;SvfO2qpm+Jch1&!#
zga*%B`~opOTs6CkU;@_ntcMT1C_6b-A5*v|p8hiC@cecE`nB%YFY1<Xw~t>28H1o<
z*6J2~r*cn(4_TPvA+u;EMFHT2QE(|McytIX_()U<i))B^2;QO2lExdtMA)xKKKrH0
zaA&uvS;TOTkh`AH;Kd9UsrE2!XpSk$L%;*}5K#Y8cS2d|b`>w};jZXW{^j<NN3qM3
zCncX=<KxV2zkA;4Tc#v^mmV*7tUmXpH%;^Nd6iUQb*$IkFsQhn%%-+9$W|Y!lIXd!
z#_a{Ft84o8CJ(Tcp1bV5$_T(9(!5EOu**{-QA|-QkY8VQp@t%2M1jR}(G@Au#>znv
zatm^k=V=()8;FFWwpcmZ>|-|N5~#s1U(p%Slqeb(+M*1?n9|xXQeBLWGH~jOA&t|g
z5%>l~OW-Q7Ee~xL>n_3@;ahM5f0Q2eH)ctEmJ?mEa6y<BC6d8P%;S)aeylhET$SV(
zlQdRbjfgljGoNMg#AX1bKCu*KkTZW&WtEG_ls4^m>Bc1yT|u#~c*l|*b~*Y~GN`-Z
z=}YwA{^sqQT@lUL4EDVCFL8UNhcymp<5Hwz9(ZkUw_X1p$hP-oQD3?d>Qcv=8Ppj&
zji7nGY%rsKFAO2;AXR(cgIR->_PE<#O8k=c#~uZ22UGEq_^D#!v$WkOP>yJ|oj+Y+
z=TBXBKHEq_O_^sW1p5=r6MeKXg}m})lQ?d#R1WsD16$XYW5aQ{t86d}De{|nD4`F3
zIuipL6Z94n43Kq#yDq}8p$pJ!BF$8!g?FL=Eezom-GCo>{<>z#!2ACCW@i@=j2Q6L
zA#{#~q_Ea$7K5yFrbUf3no2<V2yN$Bf6E0y-VZSJI{dHh+6W-SU(u6=-y-yc;0{7A
z!ig-#s=V5rFPG_UTrTr8xr(NcifL5+(m7t7S)5bIY{y9!`V|a^)$IfryJf3<X|y@J
zr!X&Fn2oBozthSKi2icxP<^jj@65TAv?%C;M`zBtEEq}JXpwBY9Gq$oMYk<I9C~kK
zEO$dhZJNh1%)IOKF!tyoNBNC+$%6L?!VTu;GKHqHbFs2;3VU9Sq+36K1>nZq?vAk(
z>sf7jwdz5`=?O_fY`8A!3vKjTcAL6(5n!cDi1Cbaei0}id8P-A`k8wj4x+m<2|lgP
zhUd4zh9|rv;EBk*RmG3394Df&q_rHj=ytRb2`7+~%V5spSY^|}oJXCVTm`d5h@aF*
zmsJBy2<~}!!XL{z{)R0>r2OMEbJ@R>DDJd9IPe=mcLyTkw80vq7G2I~gsFAF>d^$6
z>z3j0;S4MAyKCG>+{d(1KQv<1^KJ*L+VWs98VZLe<fh5Vy%L>9;nXN5Zk$gcaC{H)
zYm$ZfSO2m<_3N;fO=q??%&_*FAmIJTF~D<<Bbu@mlu;MucTJen0p6wIRg^3;DSzcp
zC0ig}n(vgqi15?*-XwA8_5J2kwC7h)_ClUUmo<b!J})8&NTXh1L$v#`D5I#}s6)^D
z8+fAnUhP6URp~9_XP#iPLG;4Y+>1b$>Puf3Y_98#p|K<ZVDF5$i3liUt0f~ceoOA@
zYXUOs;1ZFmry$^oARgFGjp6?$KR>#3bVySGFYA~F*Tv4<arFD+l<w1v1d5}dlwnaM
zOiZIIa>&dX6WyL>9@4iNDfnl_WPiqORLW}u8)-<s+9-wJ^DS0-URMM1?_k3T)4GNu
zgc_Dzbc;9!Z)D0>M{|MiQ5T1Pmfy@mNY>A4$MGx<>K-&)7jzg}U%GyzXRnKq3dc6D
zLo=vj9+9r=m_=Rd2IKxrI;}b|={}C)<tIxz2kA}Ic{UqTpJ&4{#|t#k*Nw*>o@s0F
zcOnOt9`@u^q&uh?RAN*->Ad6>@`8S(oG+;v|Mffb=~NCes2#L5vH<=E`f@|$XsMGH
z2}uBXK!(3InvB^Y?i|s$#O(!qw0p6A#-HjD0|HRV$VWL4`&_x=WD**@y-b{jC;P`Z
zWMnsN;WTyw?hf>OhOqYiGdcZ4IUShV_)tn@T_qd{8q)Tq<QM*P>FLrHnAE2PQ1`Ju
z@_&?GACEOllDOH~Ln@)$6ayv0t8fOXr{NE<&!o|Kktg`)c{qbFx+n+015{~40F+{H
z|F=z0{x7!tl(j!~jP97&#UzWFjYIY_vk2(O56I!XvKi<Ff;_Ya2X_so!M-qe_|4`^
z{Xp`5(3YS^<kZ&7YCtjgJ#Elg1LXm?f(j__$B9n_bRVkMu+Kq4_pORW2@eKTdcxRk
z-kZI)g285=g>y2rbrZ=aD<e1(XZ|_lS~`}Q)pN}9qcOBRq7N{<(fjDq#K?@Wk*guM
z0w_BUNGaM;NqnLVT9M6oY9fvQF|beGy{ZQ32lL3c!!5ox0B1#7RKV;*<tkdFk)g@!
zWI`jBbc&PaX6Fh#q~zNppZv#mK6Tva&4P0)x;9J7M|gf3$TJYyteAu3D?~3b-=<Ac
zXf@~9j=nsCEyC(k<FoK4$-_)tNc^a@Ht6i0%k7@wCy_A#P7Y?IJ+1MJ0x;vN^lt~Z
z#v{ML09}qs7nRC`*+6x<&}^Uwds4nLgIJ>FLbJpu6Sn*lFZZ>-$E?r1=Vip+KcO&#
zr$W69KAOzavN@VJ4L?q1i)qzEv+A<cprh<iDYY*f6%8<Lb~G!74-_{vvMs&Rs#GId
z(XrxjtUkX&72L|Vi%+d(;8kopheaxUqol2;?mMwY%W;%N7G^vzgXFG`pOtw$`=W|t
z@HSSSA&tnL-Z@xDflNT)@+ep(Y;u{h4`F8BvqhFCmmY*8I|yfnE)^nLWf-s>pm{@o
zYE{jMPh8ISXq^i*mVBuT&+w__8vZ^xBw~MjR=_qo64y^uA5CD2*Z7W0<ZmVMC5T1T
zGP`f(u}$)V^%UemcA=jF_{?|;;ETFb0BtHy0UJ>|1qimmDL@Et3gDNePQiQ9vEeCT
zUDkIBIKX920iU?jDS*ZeP63C#<SEcbD==N<6iCFEAi{6TDUio@J_X>Qr)XB;9PD%P
zBvNHcA%<c!+0>KU(Pfk>qf$`_K!dX)?EzUSz<PVk#3rM6y}b)aQ+8d>j1)-Z{TfsN
zF1>5pbwM_@gK0oojb><<<yH}`8j4gk&v8veD5LR)OR!5&LG0G*e%_v0JXNJ#hw&@3
z&(={xt`hu9?1A{U%w($V5cW-vp&b0hDHTB-u178mQqg&(!<U(>g18LHHLL#85LEqZ
z$s_HrJ_9KK7Khj5(<OL=4)xE@CEV%Zx=yQe4m(b(@et(@0~e9C!PVwkT_dKP`Thle
zd1DU(;E-qF2h;E)*)Cb0=E*D}JHA63S_3IdC{q~b#dPRb>#%R_S%~CToSdZ8LR7bo
zRAbMw8HvC#U=~gC%*BYpm%_Ncs@<ShHR7yb$Z>a<UfQ5zH|n@qkpyAQcg9YgZ<~No
zYj|qeU34i9d-!rMj%5YnJTj%W`hyc4jGMEvtXnlQ^`_ZXcMA`lIXNL(n8o;ukJ^|O
z!uxRWs@vEP-?CulWtRdn+B?o1!2Xm{x5+&3d2$`kl3)sxlj?vFkjE7#r7o+mGwM`=
zq-j>PZ=!gqNqMywqS?Bt2$uEcdey7)HjrNicauozh_O+WzdekZdW{$-v#A|p_q~*c
z;BN;!ce?a(I4EFn?MONm(g?@xmGO0Zr1`U4y^aZM8d7il&s;Uwn(8YVZdhJK)@pEU
zd5x}FM;Xv%q5Qplj}Rf8=iV|wXSLwp6|P}58NzEUvLb1U#UR^YXR0@b+k={0>_Ah+
zKFKU9d}WVH{RaBjyC@1y1!TvE2qO?wZIY};c}p^NBV!zv_F-*E?)`JK1P`bO%XjR(
zorfv;K0fmfZ?ZhRT=JpD*~Z<lZ!<(!JYqpQId6K%Xdhtec^;;*^GPf9t37VT2+N*0
zI_CYE`#fjv?cwkVSpe@c$S3EpkJ*9}6&47~{yHA|U)T{`3GXFNq?CEVT1RI&dt(!u
zV-0GRc1Op)PRT;7y><Je0k=kqh;D~8jObv8bdf`87`5RW=d>EDSS;76I<2TaIjc~s
zt5KDbc>_I85dAGrI^t-}G?U#7r4ivRAZ~&5wvkpPezk_%*m&FAfa^?*)eO1oH|925
z#q}C>mtNFm4ZO=6d2hqeTW{=j+uMSrSQvTTyoN(h+#ry{C4p=&3kcxM6E6#Hy!;$I
z!e=6*W+vL-?%dXC&|a5Odu7A+s>ba#nTwY+a<6LWzJ2Vg4BkuZId{YNEgQd=z}?-9
z`)8Hr9IomWjN`XsAa}sL-pz&CiTTJYu)rECZq?)MI#k`WG+E4RJhPORR!4EAm984{
zVchLT5-d>q@b?NgFd-1%ct1c>>dlM2q)KsI%EEV#@|WjPoEr<pVN<SnSfL^d<#mRw
z@uw0n+j(Atk)f%fLE9X3iggx-s!q;%NY!q|#!*pNim4YHN*%+|iXhH`95F2~Uju%w
ztopjR>r#r@a>`kwt7Ua1?RFHkMw7TDg{@j?bG}xWQNZrTGFG$i4VS9trg<*6f@Ull
zj@VlMl&_-Qx@mz+?wR$k`mL?_T4=EHPPh$~x&pE0di7d#>vibYj<Z^2QZ9=2I+X1@
zno6D4z2q5hrhV7&v9+k+OHQPj(zs4_d<`o3x-Kol_>KvT9mRqbb@kiR*XxC*s&neC
ztgbg!+3QU6YgOpYxd`#<W;x_6VQ^3JTajomtI2J`hhg1#uTHm4p(>}HDvw+j*lobI
zNdl_oQgh|F6$-)5QnT>9j+1!k;)Y=!WHmL)J?W3FgqXiQ*wmsqr39m<;-ey?Q;_96
zjc}(jEmJAsu$0-@`^PAfQ`Kout5X48DH*0nPm!a^kbG3as4heC6(lCUvg9K+g}J%r
zxow)L)|#o7Pns8Xgy*g}@vta4t%nzfA-VKd%4PfMFZVz2gK1#52Hy@ghgkIX8BNkV
zJP0q79FNrMV{C11e)G*&-d_meA8Y@@&o__0eoTL34ZW?cuQnff_lt7}Kf5d|bH+L6
zUK=Ws@3*|&6t@7L8}g^O%PI-(zmh6b(&Wl?vk30LJLFBF8_xv2KTT*m=)XG@A0z1V
zB+Vy_d_RpyXZ{C#!%{_iL;P!+O!gnn@*Q@jAD-nqtslbNn}&H1&EO&23q-b6D1Yqb
z=b@KjrNzPS5W16z4b_?LLNUz#Vt$qe(=bz}`kH*>J-H&V1CW0|ur}5SLi?hTd5W`z
zd5ZA6x65uyPITUpwAtsRf#2y@FdxeCywk;OcH^<${op!CLyt1R@G6XfFsEb|i!|g^
zAl--BV7o&J6$E}XPs7tNO~dI4*c-#+7E*-eltp?M1eUY^dN;|!I}ffx5t==P0yJsZ
z3aAn-a-c++7YG8Qr3N8_6_n>3#-Y*T32nlBGU&F528-?Rt2tD-nZg}Kv6&?Cv?!V`
zExf+ce2>HD<%Msyt)Yu`ThAQUTwm{ralNy7IEhYg$Uf&)eG@WiphiF!gH@2=Ul;4`
z?FQ-D{<D8Pd9yo&-;_OIUVmI}N>#D4#cHwD7e!B|d?N%<Q9vwaYev?Hkdv(+UsbYO
zP{82QTj_YRMcK_l@ZnaL=MX>gXhU(}VZTEjbL&FUZnj0r=D&wUA`NCU_IIXZ6PU4~
z)DkO*j1jzpF5=`m<~U?BXVAy^;`kDs3yqTCe?j|Wwq;>@V#3$w5%=Y09D)&qafoc-
zdGE>RSW2lSK1SX|s1=-DhH(xXR$MMHFzci(W$QX3Lytr1kF|(rP$7X=J|d(@$N@>C
z=`@U4f1O>a0P=+49mF@@oKTsiS;uM6T|Sg5{uYNwoEmz)5qcPIHZo8xcY~Isq4hco
zejlgi%i6%7hp|dKfnY)3h?HF+9*)?qux<+8(6%e4RhuGCAZKk#4u-xGKO0wqqe{*I
zIZ(VWp-N|v2Wi)X6v8s~RrqD%YZByOFldR1^Sguq9urCxoM8rhgq=({{U~l^i!-uv
zIr(FJgDXPUsfW?5;m6=|PSzzlMQKRP0+#mqQ!x?|zVRbvF<V?bB8y4d5=OK&_-62R
zj~)XCi3|&P3ACO+?PIG!e)g-h>e5Q@PRJHX`xCM~LS^Bf!ROvT!?AZrW)Mvvs~$A6
zZUF4SnwYo1WKt{2x9G4ir~muo>;A#JXTyURhwnYak5K+FB;=W82|W$);Yps)#JNBf
zq+r*BRxxK~p5#xa<m}%oe9iR#`T6{|_5a7)UqAk)r2lVk-s}H&qW^zKmbisQo&M^<
z4me>u;Dl*E9Z6a4d5Qwn^CU^V$D}IOCV=XLob&VmxO5~vejdBz3mjNV1n7N*Eb(jh
z)%O#^7tfOPhU^c>)P<jM-bsD{XZ$Q!<b>PcK03^!Gw*3|aX~KV-7FjPa`XFo!yllk
z)YCA4yLERG&SuG(+IEu6Z_?=OJSUs-+ixHDw>LMx#S7sH0?Dw^j3&1SfaiHW9}UTk
zLq5Qy_Jbrn8?px3aGXv1><>6v-kb2+dwTfXW9jh`8t44v=h;t(BX8r?bmSGs(cAv}
z<F6h+_5hRq=HL5U-+EhLjkdlWef8*PZ@M^L{OWBmtl|r1VPjYU`37uyLq@`(pkEfn
zlaRK53Aaiij?iy-YW>Z@Rtu_p@l6977cDZ2AG6rolLY$s3QvK5lNd1YcTDYo_p@*1
z9VvDT-l|OJV*=5C7GZjW2_pXVn}w~<$U|<v>K4G7&9!>~m)*!VcpW6=JGuc{^x@!&
z-25A2X-nmde2MR1F(6a9qfDwi<k#9IweqAsms@Ce**vMY<Z=vcnMV5eqS~v#Q!i~q
z1QXhMmr;G+-EgUmCV}=9e(Xjji%qkRII?N8nmn^bJ$Xv+X}+W~RkbU|BS7hRk)`Zx
zLGz}noCRRlx(@1ae+;XsZ{2j#t>0kFEp-^7XU$=pt+3mmjd7{nci*IT_cb+Z*Z>CU
z83hP-4%-%O)oj`Vt-CZqRB$jVHM;GiYO`<Mj-tJ*cT+aM-%ZxNL;Dq$;f8!VsGpmg
zp}GOKzrS0h=4QFKdmHWEbs`cWOB3lxvWvUOMWlU=NEF<&l|R)%{X#BRZh&#y`?~eN
zZtL^*)q8)s%+@bV_zic%&$YY3<uzdqJ3#1pf6V8FicKdO`rP)N?eU>*{}pc#)jM!9
zSwUZ4_Zx+saNQm16N#oT_%Rz~3FItK7n3|mnH#xi{(Uf+z_mMHjLEgjJ{{t}oOULV
zorfEXsOLT0ph#04qVVn{$P+POG%}cSI@po-<Gz*ZfG30`lM7Zm`el+rA=X9K*<g$q
zx|84ZLBSmt1{{r|>_wU;DeX`$uR?u4(;&)1xt*!fI1AD^322)hH9MYg)ZpBg;HP1}
zNMpk={;L>Lzy+|>X}Z7-<%RIoh-mNVtSYY3wy`=2|90T{ZQqFSMhZuE4|IRJZm{z@
z3>Ssy+_*U!(YVlei|icn{0CXA86=3s{x1#=-U5{O9}eEgRjV!|Xp5z|B-rSM+wlu)
z25si|yqH|2J*OB3F->{6fR-2|a+!GB{YRe9J3g~gqJy{~k9siq+d8<W`fT&`_h&ZO
zYK17tT&0OtzV3mx;Q|_^7+Ch4=5Or(^U1-RS8sk8Da)=dvv(eti~abEIXI3_y@*H+
z^EAoH{Wr^cAPZA4booELdH=6>FEE6Q%Q3X0S3xp_-v)`Awk_{9{m9Cu&<?lJf+IU+
zn;1_+7+PjJv|03Pn4ETa3-7_6x8;1O+I%q3974!$1Rm-LYJ?0{Q~fc9(tLEX;40+w
z*egh5-r`KSJ>kNwyjj8Ozekv3soOz#Mua@5V=uLqs@hQs9Bm#eUqb?CwZfj1&RI(1
zY&bUto=D*};#!n7$rNN8RVs?7@uOCWXYKK+NU<F|x<fvvRc0cwafbMjpbivcrcF9-
z)Ch~^b-Z<~l(Q5!Z^kG~#io&0Ws5l|v>9dQv?=8@_>{KCc^bq$kq<r`yzcnWc5AQ+
zRAU`VOo`nUri}^%`LsKec1*D&1yg1_fgXQAs#h$xNaSu@KrK#84vB2AN#7(MBN90)
zoEv)A0lWY%;;C;RP}>m3aUFN3#6UD^SrMn>IZ?x!tfZ1E8v84s+gc(O0Z<YXl2%*B
zjotIcgG$>8U^H?^{CVUTaaiA3KF0{8I8ow{)S%GP7`EbiB{Z}TAuJhnXIrg6a{v)_
zdEi%4w=sWHcTh`PVaU_JQ+fS@4WY^P`<d=MIe|9CuqyY8j8(aLxdz$;x=C4!7azf{
zQd|e7&^-GIdS(~QrU}tH<0L172Ru2|1m`V#zv)-$mweTM-SmX}?Cp7{M9B@c`>gT~
z#79P-1_e{ALpdl|8>2W9Ix>arj5`Xr+^tS`G+e#f9;&^Fw_thQpcm@BHu>QYrTbH&
zxrC{3nu5uQ$u_;<x9k_ZOh9(a&#2{E-0<>Z&@v)Dy6WPef*vTW%7YYHFYb0FHr-cZ
zy%N){6SPvW5u@LwbW;p!5iNie|0e(0+);yj%icZIP#DY$a~|i-I%}3(Rk$U6q?_}`
zNeanK01i@F{q{TzK;4&(k#c@J9v!V)0HxO#fskst+fkQjLd33IrV_BeO=Fxi1gCe1
z>|=NvxCwJPp_eiGzKG2(`ays;%^kK+B_LzeI=B1oX?5=zgJyY|^v}N2KSJRx9tM3=
z&OuusIAGTkD0J;**PY_J*Cm!Ukjh^3^L;OptxF_p^JD)@n*;bo7slFmAdG!c!p;{i
z8Gg~?*6&QpQpJILG3zr>^ox_T{P%^|0Pa|iNEWjxGQ=_2%3)59^|bI3Ry^Vd-aG0g
zKyCytI18e9;B}sd<HeZ=SNMqOzG7ZTlpn(^BZGCis0(-fiaaeYqTCbN2kFQr*d4D|
zjC+mm+xS~D31&{>T(44|vs|F)qH=6vG{JO=P9~nz(v%~I6AN<`+2vk|iX%<VVt@om
z3Mq@j142|#$KZkUT=u5&e5Kxt`H5u)pibr&XPLOIV7rPeT^k1D*HWTuozap?mR4h>
z$+B2BNZQgo8BCWJQ>W3)SWacN0e)+Roszpk9PhNO>BI0L38!gIg-$@yyk5V=?EwQV
zJIGa{WZLeR2~ESNG&E;g(>tLURM=lZrzmXSj+C#?!urV_55hK8R6ZLfB2L5da!zpT
zRMN@&?Kd6)Z~~4?K^mG{+TP|hHI5wf{XN5#-E`L4{+=fyp67(RoOa}V@UV@$J(+zN
z&ME?Vu*XDk6M~Bv2~|Kjf<83~|D}y?P<$VhKC~u&6PoZI@*USf9WN8t3q?w6ry{i{
z*vlfWnhn)aF&t!1np$qo$XA&OkVD~ExEz%Y=9RXmlXc*G9e+S!4t!IFbGq=BT&T)2
zH#p|l`b5yfcGGY^&(uEarBlMyhz*--F|>KYh7^+<k^{I|Fw<3hGh?9BvY?JD)T@}6
z`8!d`Bb%TB32&%Th3AlRETJ5SVtJw;SOMs#-nLU4P)xRQJefs-B+nFCEbWA|a2b;+
z&4DJS%fSAyS_|+qtx840NCuF{@A}8obSSUaPEC0kU2?&@KIS5y_AOU9Rq>!FUDDn4
zt9(rjnnt^%HBYA`j&q6H_+E~>IJYe^VO>~fEr=^?#dHYSxZ7Ip_y9Tz8m7<ygR)X|
z6v<Gl8XZy*ySfokc(P8nY7dt^2A10jO}BxAX`05iHTBgK(xz}#LlKkZO)frEsUnN1
ztj(6GBl%G3>FVXeGrjU)B_cUO{bjIo%^=5awPPCF-__FAI<4w*IGoWaz@`xtQe4(D
zh_M!cJ4Qo&X0Q%trF_8XjGUPs%vbXkR=JKq33!e;;TAoSJFOO$IPedpsjaOAKMZdY
z(o>2AYsYqx=Y>h!>8RL?RcYoy0=l}8HC+RGm666fOQvDBuUv&ov-U1YQR$*mwP{f}
zAg&}%u6wki=vj2dVgspTyX{$rA|$^QvuSVEXk&GE+xlM53b$NY6D>HL)Rfs{3N9k?
zxbM8;FCz6Ao{1W~x;5fG_pVd-4`jc~=NauGrtoiP=j;#W1VhhVK^C+sN#ch=LV$R=
z7!FSk$v$E{O6bDd1NT^DrQQRx4~gtTf?a6kXBs&@4|0f5GI$Bo078C<{Q*aC;17If
zjm50nG(Xrb7lAB17#|4iPgCXRsUHLSfW|4;D=4Aywvp+br1F)@`ch?nmN`Ttz_3G~
zXS&wcD>sKEU0pF5LB4!S-5Gf*4{g<MV<Nl$23Mssdsyjxsl!@2l9j%&pFaOn+p6zd
zOTKPdiwWx{IHIUJ8T$E43wvKjb{p$<ZL6hGGRr%d;7enbx;8b(+aOlJt0e)HA!4>_
z>7k%(uGS2Fh0|fp3#`qgDLt%uBeyqN!;4bIiM}gix=PRLMwV}3*WZc#`%9R{Ef|b%
z$*FV+hth{&bmX}fQlT@N40R7M(c(!+RX7^9UUW4@t(TH(7R_0TO@l)R2nG*Du(^yI
zCz@g{vBaTs**UNoD>>jM=1L+bUj`SUHwn``h+=wmP9+}|57N0rXEC|-q{>i2P3Cdt
zVA#OxcuTr52yns|E~6OU{iwiwNnN67&QZ<Jvro7Y25VC@M*-%q-ut)D-;TV)b9C4m
zL-q}iqR{iki=0Rfc{BqHOOdVvwP&I^LAbNLhIC9w4TG<dER6#jrkEF<vF?aUC#ZB<
zZHkf;nAjDP(rDSqYspQ3cULhg9zj0X^C<0*u_xEd2mR~Dfd&DY&lV|U#_*=(s6jf8
z8%U%A+S_#+<sn?NL|`UtfqWto@mMSxc3bU+l#a#pHR-7nXe!QE$)0JNahlrg8);gD
zuQD)M3IzINc9!XMR;`d-YeWNs41#J%Bcm;{6;q7&r~`&ovNE%K3VNrR;ng8+0c4O0
zr)`@9rM#3n<-`G!%3SUkgn0=F7QwtYbIVWB#;nfJ{s_|g97}nA+QysjQ=^bo3hNn>
z!^Q;t&c<bSCYU*Mk}=(E&<>rWrXX8eW-`7Z`rnC4Jqo!#lZBkOw#kKK$zv_@SKIZN
zP3BA_gk6z1Cy7U+aR`bY7#aZ|>5a{q?-ZTTPn7YTfIpkbX<vtAv|t#_=I6n18eWC7
zA?ATa=ioNvg7(hC*<8))Zq5Dhc|uu=jV~Nbix;n|M<-MZ{(ttqyuWQDN%Z~gPXTkZ
z205Xq!$%Uza-!HuMsFS4Pg0Iq*~=e9f)Yj~!2v+YO6>3cs;Uok1KkaPI_!z1osA{3
zkLvEK>Z<BGq#xRN63yE#A63J{$$ieVa3G_(-0UA`@czm-%lX<>YrHEN+N76O>5Uh4
zuUa84eJ!&|;emo#k5u%~L-=F{X~WA#O^g1`S@kWJebX68zcu6ADw)1Fy>cKCQ^5*G
z`6aT6IA0lx9Ssi(o@Z40*4Ek_bjMr6BdVueoCD1&rXksYUghIOdBC!AsGosVFrXD!
z<$>zwjz`w#j?#M!P1V#gbCm}diz6Ven^QEADH*v0tpm#mW|w}Y`=<d{s~00Eo|}e%
z-1W-qj=PWMWpU9R@(HTx^>{VUg@W5@{$|CD%(<w*ql-9{bP42awM(qZFm#j0dBa6f
zU}_9bv&+9(uw^~;s2&5D^==yVaEl=*OF_H*gPh8n**tF08$5G}Wx8K5Hm>y0!=r9I
zpJjHT$BpQZ@JbIEW(BHEaC8KUa}~iI6>jm4I5Q!*Zdp&WBhlOLRgGRyXVF~AON~iJ
zXMR?wb<j8lq4ZJsK1+gOR!YRA`*-K|Xu|`Ce4v)LWT$(#>M`zBjo83#9Jjd`>d_K5
zRnXU3+EVa?N!W6oK>n_y)R0)rSF?B(lLB6S@9FNPM7Ds~-m`6QbN$gb>(*OGw)|?_
z+gRUx<gKdR|BF7eUB6@0DARco&9ZU3^<Sg2A5eppo!4xgmFU?VP_HhG56d7vtO;Rn
zV{C-6x87-b;nK)0&s%M6;j#Yy`|sW`oKe<xIALH&wE_ohIU4fo4XD3}WnNps_6{Lo
z{*C+)Ane>gIE*6VsK8rMzTP9P!9qpao@aBCv%c<X={zK{nM9h(Gq#Q|RP;P{-8z1q
z*S#gY(VfqoO^(NsL)8`y+xK3XmhU$vpC#7pig&v%m+%?}wmjQ)qXZ-@CG{w>shRS7
z%|ruqeH^F!N;CB0-)nt%nteSYi^K)wdgAda2Z+7IM=AcUe%vHmtX!P#gy_XdZWoj0
z`If``18`stpns3W*oyGf2guNyn}pG7aylQ7-FcdxI6#qm|ICm%S8OsmLx8|HLf82G
z`5~Y7?W|>d;hQa{dVZ#hQ?v@VSMVKU+ruFV{?WX&YJ?56^pgQOthD_#RGoS>V;c|n
zLp18Vef!56A~}rKu}GTPDcJ(#!S%csd;7c34`1*9b8xWxW@mo~ensksG0b9-hD|u2
zoyo*!c&3XP7Q*9gn=%X<!lD|pB`L>h2}iU^OYxZv@**N^I`1L{DMlb-;=3I!R>K1K
zWgxKQtFN45lM6RZ;4tLJ+|vv&jse=H8KJDfaEB9sL}2UIax_E)!D^BMz9smMOyvv0
zQGtRg{09=~J8kokJFX}moKdj&kDqV--$Nws_tVLB%;B#8>pk3fyup6U>;JAlesov=
z_g3ov$_kuZl;3V`^wwKgL_1l`R?&u#YL&wG7c*}^Ji(eND3>6fq}D3o(3m$c*9cEC
zSDkpc))q;zM0{c_5sy$2tRQ-OL%7pM@>+~op<);+jn2c#WzX{-;g>0}q;T#{gZI&N
zF;(lw=kq>|W>FD<$Ou3%%of2!M61PP59B}4oljEaeOPIc{ym)|e5_2V_u$`)INS18
zN22Za@gz89pXT6rPlM#-*}?AN;ohsC4xX;zUkpqE8|+gs$)agEiBF2aPK?05j8AB{
zJUHSM?{Sb(Q(g%2k{oH^3w=lQ8J_-o5rtWCvVR*VdySz)qbQwEf=gcSlsrzv)xhv0
zpDQ2wX^OVwusBU>oaP0ef%Wl3&8Ik_(7Vzs%Fua5R(+niah^lii%cn@hTE3gR`k+!
zto|Atd?L_O1wozmDWJw;7L~SiVT9qJSjUalxigs%vEc)Cm+Jmt<}-4X;vn!zR?)Q0
zcmCeq*h9Bg6qk9>0qz%$k#UL=^?&es90@B!Pg{us{L?I$v&}EAB{QQ3J1EI)dVpg{
zB!@e1R?+Y^iGo?iNk*MhpXTZCq(rDg<9yG5+9Ns)-vgDi!dmTF7*e$(ERV{U3_{AA
z*9V7dKkXi3r8?wFogz`b`Nta=O(jVI1#nehrv{vQZ-nWma0abGItsjDJi-z`tT(VN
zeAmMo?BtA)dcTh-mDgr(y|?~VN8Jx~#;0ovAEg<Na9t#&lg!=gy}O4jGszjby6}Iz
zdGNROhu?0c#Re3KOHS7SlRPol&W^+fU>5nkfnc%g<=Nd;`&s@t<v%#so0tDKzutWE
zby5D?Sl_sl|87P8`wkBI9+ey`lp8|~P^i3f&tq-=@kWS>DF{+{%{=B`eJ`A`(R~%J
zDEdsiE%CQe`Yc#vzy#^Y53=aQ`yn_x3unM4)8p@Xar$S)hCc@hupjUL2D22KPXA?X
z`4jpV{SXFNQ1R(7oWO;mw;jgw%OpBE%>dKB{r2nC&Gq$fsSMu^4U$r$Ni+;+WC8Pd
zRVp;@r12sdhP^mBS>p}Twc~WO%Kt!$@m_@&-VX;ayqD}V8co>A;ph3U2Yqj4Z`Ah$
zjR6UKyZ-g2hj6T}KLU6FuKwe%`;RvM$72idRya_zGp;pppm3jie04&iSd$x_M(Djp
zKji(F2LiEg_IXLk_1?xk^cEI~K>iKnb50*yeBqE!Xg+Z&9(hu+z-twj5Y5)$zi?;Y
zVM_yS;V0Dhh(}))37+GTR$~F3yn!2p@3Rn3)KCfV9<#BW2Z^+Oq~-T_U$T>Wl_5>a
zW@X`cu5(tDjn9@TOG=ty!-}LyWku2}E3bZKT~eA56vk_>t-FNY+bXKOt;%A;LjCn?
zty9rf8?JX!x!zi;bItQ0O}8P0|E`3vj=o(JK&B)&gfOjyu!gE$6F^antQmy!N(ir}
z<ktnBY0V9RUsMABIamj3Zh=(d8*V~YO$80i3N?WR<-Q@9)n(VOV2!9`n#?>=cX8Z&
z&~SzCohzgtY__a{qZ)W?-R7nikGFmkYe#hzXOe^%a#z%KCei9Tt2*O=H(S#=m$I6s
zoGUv12qwtWH5R_j`9qUJiRAs;7om5^=8j`H<keL^8F9bWRXMnaJP-u>6cZz$;NaV$
zpz4JL>Fo|KfhA50O;(T{DTSTcIQsYa$f)><FCudIN++m`z!iTAx6maEE5*z)$c8WC
z<V<;}B>Xmp6ozwphA(b66K^RNWaE+7*J5PVfEa$frH54>7ef9@J->FoPFYg4JYqZ<
z$q=$q$d@vwH4>w7lC3=6D4(00Xz^FGPXkM+;V9_~J-hXyq%5AG#j3xQ+tc>`?g$*C
zevMKKo0EmoKzc1${!yOq%;GvM2Cjg<lvB?CWp*};FJ@ZtQ@cw<eikF;Fb?AbQdGoN
zlxiKjb_6dID#wv$8K7PHk$-MVK$v5b?5(9>39>A8`G9az!Dc|7abBWJ{e*HTQhf)P
zmx$e&*RtSxEL(F45<=!%WOwKc6rnee6I+XngRe|V+k+rAB`c}9D(Sg$UxSn2%Y?U5
zC45y|cTH=m;q#K?lggS*u3EycZf^CawV$iivxm76vKy`6A4juMn>!AJPT{X+mvahj
z82er8UfO>A)oJjaE+#w@`em6xsB&?aYS2h^$L~~o{hAyP&4i45VBGaG1~8Ah3A#Mt
zL2Nmjs~0S@xLZQ%iV=2tA0SD%)+XT$XY`)RKj>>?ps^)j0Iv_!`#@<5yi*W5!en)V
zF~qsUVVCQW(2A5quKZPwUJy+xx8~!$X5W0gdNjids8Ok>fLOq91=ape%*1cvDczj(
zO5T@dRy(iYv$ZjD8Em|EOuRWPY=VI|hGS)C*7A+YZmN|v_u=wAWeJeBt_L#Ljp=}7
zPSJvlB$lBxIMx{xn>$vLD;?KId-k`Ia$}U?5eBBW<k!%aquEA9^kI~c>%4YTQtwjM
zOcf6Y(=b8tnm+8(Ft$>=vuGeK?PZVq;@Z*jZ_uu^QF>}tVd_w&zzud^{d(jd?j9Tt
z-u&auVDHuQm%qH&9lY5&{70SH=p7)M4JV6HI6#iH{il1#k1e~?ygGQjd?@}eDH?e8
zUhT;@3sD_UhqRy~XelwyqWN6pBS};C8#lC@6mL4%0kKK=USpS4<pJ=OXodh2gz7+;
zVS(G7jS0*^=uB`rv}{zRvsa%^n0&7?C|@(DmeY=LNBd&4+J*p^xn~8wL`>i4^$a`E
zvbk#;Y&P6<RkX;U30$$r@K#t><0Q9jb@UFa&-4>jp{lATC=9M_o9StlqCHuPo3{U+
zETOQ;#eB^;E&FmH)8P~{=NdD=8aoyu8&u@}7bT6<nO!ahGscC2aAsCNT!>}l!D9-*
z8RNrw5ru&F2foFk0R3#2(U=l(VT-QU67)l_cSo?WHSM_G!C$>zuVoPg#uRNplQpY`
zcC~B;&4tAk_9jX8C_HfZ4{*|7paYy)SLbcDvqqN3EDr{M{>z!av1#3cQmqAqp(+;w
zV2fyaJxLIn@+rxydfQ^(M5ZQox8Q&H=Ns=ztn13KeR@LUtAk}-2Q8Iz-Uwub%izbI
zy_dT$eDf;l8fG$aR#p5`9rVr4!GUd1cFQj@=)r&Qy?J9Bm5ULUVRbJ4FEv6-i%W_#
zsxgPr{B1w#qd35>d~cNt0Tq|O^ZIoo&4n>Lkr`oBWI;;l=9*zJH_@pRUo6tnMS=;7
z@wJzGo#2B@7L$M{HQ=J4VlgO#{AUk{c3--Rg^A&#nIdKAZ0qp#;m%9%aPQ~cK0i_;
zdr)H7<eLm)CR(&x9>ZV{#pr{Y-8l-f{v25w4ZxR2{TW%Z?tNo_#V*dIWfUav*F_T6
zh$|FLt?bjJXJX+u<D-`*@_vUL(CZ^gZy8yq=b!_cqnMhdA^+sd%&CG06)wX}D+xrQ
z3eQ0nP7*M1ZE1FQX%8YvBAThIGz<LszEZs?n$0V=K&3UNQy{%nYGNgV^EHC=U1_Av
zLn*}P>%?asteUGhr^`vz*GbiW#!czfl4pVUsKZU2$wxolIqu(3{70U~d5yoDUOfuL
z8UL}l`DEkkV*Kys=HvCd_>WH$|B++BfMdYTM1K6oglQ;r;B9{M_2Vb&JW}JE)y)mS
z-~PiV{f%$_#~Urii$88SP-CO_sJ9;I!5X9=Gru~jA0-_>Jy6fHD40Zl1mv}a+&A@(
z!(o6ACbQV%`N(J|S>6=%hKpv!Z1Bv>NVN7wF>6gwjKXm=3q?(W*T21b`FiKY?*8D-
z&h!7?`Du4>aJX~03m3~O5I3gFx&ffciB&p4F^@j<=b~@X<fCA2EtsMGue<vPd#_({
zz%iMafc$wJCnL(EpXOQoRaar43%J_IK^UOG+%!s=0vutUMCjWY%kE^BIt`~iPELC>
zlyir{41;Jw=4PCoCLv%0A$Hp54Ocx@S)9^}d2RIjjn3gWOz6+C_Wcy|Zevqk#D%vN
za}$y+l1a*21;;7n(35^P_~w%G`H=cpLCEX^kYEx{!&$~kFPx$!2LuDEW;VI>jxQNI
z;nagz&Cm!>29PWn3EM2~3G;EpjX*-V2#@{L1JGBK`4BJyHg+5U8BiV(_+tvk=gmUw
zf~6YO4Q9U0FbR&zbw4IS0C4eGuNe`gxj)?~8e_o)^a^JC9gy!JK2fNf*^^rlr7T3s
zJB>!{tmPO07@%x+5r$Z)A_T-0d)4LmafWHE7Fj$+YZ#6v;kv|X5b<O|*dKWF2$qR}
z51~)b^Y$_?n53~pG4v+`wuYXpKu0(d9t{D82uh=RnC)*yX#}$f&s*Oxz!nBLZolO4
zFr{#cB&6l&ki&_<0EDAa#0p$UVjxmP*Gnvbk!6?`47ZVuhg>wzK!_t_OP;|v9I=eC
z(%C*yvlSK^QmxY2>YLr?FLU!bLq=$cBTI*y-e2^Ry3Ob?_3BXq#0=uXpG9})@6j2$
z&|33jCTHn9!9OoLVI1K(`A-^pGsj9tPvP-t=$r7bO1*zcS@t4|R6zpfbO4l+#DI?T
z1Wq!UTsE4GqvgJB(tHqwc@EAuJ`_LuaK336o*yytdGpZpE@|wD?vlvwoAndt_RIdu
z<vL>N_2PSJag5_Q#+$`33afjdJ!RGJ3|w?_`A2B)Pi!lqD>dM5^O6@{P*~7;d=`#)
z907L=6{)Sc^GX_0kPTf*Y*dyo7C?xQ(uyAcbhiM8#20X_0Q-y+yyZXxha2)_Mra7!
zxgeym0IDL0c-vsePCS+i%2JL0_q3g2fqWlmFAUoizMlhoin4=p&TwVV_V}I&AR_ZN
z{S9bnG3VPP_Cg6LTDTzi3Hw?h;4^sWKEh<A4<O?hR%)05`;-O*wv&;pgBzbq16{-q
zr7#JJ4uKH0wB*h94bCGxlIUFK;?)^ca8XItI+E8Iln95aJjrb=4NQWqlXvSeDCO&*
z{XnU7Q%X<CD>f9WN)>McwJGECic|kUEu^E~0%|Y8;njW>(E!3kY^c@qntfB{O`+Wt
zMxO>95a_+f?*{1L7|2+9w|K8KSZWPm2tg{V%T`08U$sU%t>oz9Z!?qrSPrYg3yh@9
zh%_i<e!0E?@-cjsNUj_x%2PKd+C>tPY?)J%Q6)0+?1-rWry+XWZ~@vz79FMvU>0ts
zWr&gfWHMZ#U%xNQdUZY)$Wvow-uK*Kiu{0y45VzEiB@XcB2cA7p)rWJyNQxMc7RL{
z#ShV=kb6-*L`%??wa~Lla|Y_JPkQlq%o9GFyi*FU1$>F(MM57bjmNfkekE3jjX)5B
z%$QK-cUGQg!T+og<{_FM`Mfrt!y(wrJ(&Z<de<|KRX<nsy(Uwsi?{h(m`kaZqkNw0
z_3}u=V`Qqv{qX1tr*B?Z!r5Pvi5X=L74cY=U>7Q@xK3gQKJ$Z+;oIUZOtUmZxT=!~
zD^9_3xVF=1?ade~#%hrfGtY1?DNX~KXUl!ohLey{ScSv5(t%X$v)r8LSe=G4ygO}{
z6#;7OA`+DqFmjh!fO0_wB>oh3XNJZleBrC>c+K%aK`jP<5!Z+;eEiD7&fFYFRAM%>
zuA0Fx4!%eG{%2*#OAbhwB(-8w1U|t(3UjN9AgPYMX-J0+X!6>_Tkc)wBCg8XYlRSs
zLuM3T9So>23?VVP<2hN7Eftg6`jor2+4Wld63b;P&u0MoT~vgNEY-zJE1(DV^Cn=U
z%wkc|*TV{&Xv&{pKKDy>@;JdK`{VdLY!q`_zxdead$%<~znefkTXfAe?aU3Jn*rjh
zqghQ9``D!VtfKkthnRon9PM3~WtlN8sz!B;tAq2+O6}=Eu9MkwUGS4r>^Bv;EXo#K
zd+bC3Eq>X5c|<~}-PjPN27{>*q%)3l0-%_G1@Z045~v?u`w_*p8$I2q(a}ouu2^WS
zvHVDqymjeatM*chp5-A3Yq+RUSlFsrc(LqmiLO-}#@jXDGaeHKQ{3N{!<eQR#jXkz
zG<lxWfyB;vIGl**B$7TQl%<CGyOT3BL3x@&XLpz?$65C}3*3zA(V@I9Y79}ySR5|!
zaDkFZrom<EMVXK0B6^ve3!fOr&oP|y+4TgJI*vivAonpS=hgfel+ItsF*Hj{@_c{q
zaPRrfOOIzA`YogvXlHVgCftbaWDjep3hxQL7n~FL%8SHs5=2wV!gzd*P}vxsQ798d
zhKeR+3*TB=`IohulVq!Qy)Ld#3w63&uf=vJ7jt4g$P?s{akN}ezWI2$`L}Ag;)_Xf
zG#Km<7Fsn-{`OUtv0g@Jp)gJ>X5-FBhMD*fPEJwewvxMvm?bB?#b1PTECY?nKC0e@
zpdCHKgma_W7e2?k-x%b)j73>W>7}sD)*qATxJ3wAl;CGEde~qBIa}Zrj7F)kvLNy6
zhTh3OCx7@((qUvXZyaK16R+|;rD|O7vqC>UU-Ljdo1N!6)uJ0PhWf%73VWh@YcYFt
zX}8EW-L-ODf2bR}{bq4RWg*quF3sag<EUm%Wx%uAn_8Z)jwQLHR-w4qnU`?1b{1uI
z^UmUvccv=GHVmPjvzTX4vj$=ox9P|yrvoP4h|Xljl}`?2#%15A=S=;qGdSE5Y-)|T
zZ?&g=&gG7L_*l=tVB+fdxH-&TDBc`xTOG*jdRP;^;@RZVnw7D3#J~NS&PLe}v2-@Z
z%TVdV{CMQ?kqFuKR#*AhUJ8<AG>*a&jX7Y=lloPwc08>eODI=+H}I5GZ36UyDvyiJ
zmfK|PiQ#SJWIJM8jEJtduV9{4mmz}T*CrcFB>6LC`rLBZZS=u5>JC=Kby(A{!eOOt
zlNVH%7JD&OZn3ftSAblOYBxVk<MS|249%o%MG7ZxV$=(Sv8+(^Tt4L!&qmh)i`#$~
zAO8z>F}G;3czUytl@M5aVygB7M`BjNS9#jH^+u$vau+#3Z5DICA&)U8!Q*BWdzMa_
z&yqFLFFHf0r%*|?4)Su_GTBJkegmdX#-zg*&su~gL}?z5P#%T8m-TEh8#GxpNgtjD
zC(+Pb^)3Jr(953B7`{jM6w1{kjGaa8oUftinj>q~@5+Lzyjs01PVcamQ`29$KXSfN
z)=B7jFrPx+{K{<hOntoZfc)5#uw9tHtDY1844rKJ?QP%rl4C?cz_DRi<MmG(OjV?E
z*Z_+^yi7SWy+}c*Nhfmttn6~-7fx}s#rt?ey^m|<W;G29+jfA7#VKQMr)FoAugf$R
zNaFIir-+IrOFzZt(5BoR>nIBBFfZj9No^=+d^qE^&)L@wAeVZ|yaEniGhQr(57&$b
zwNLruG8tSg_d2MW#L8bRP>(=6O4}_C)tAjGOe-emdum4t4_rZ1_@TTL@)l-2rAFDs
z8a~J3uMSV1O@A?879A1c!h<hFEZE4caXF;hBXyE@RY`B%y-m_jS@>{|LF-1#R>jSu
zs<Seds|HgR)^idKgtt3Y^H4qSmFO@KJ)8r&lN`I5;|j=zs%FVh6EKSwmLq4rTPD@P
z{d5mgRNux1+-6yIptoaTk|~#RPGw8^G1M_n!PvFjYMQ(lxl7r@QE>Bu18=t~y<{4p
z>b0Wj9h!Y6Xy&qOafZ&;5KKx8okC^+9o&pvbg#wODS-;bDckBm7;xAziHrYNbj?!=
zSFEF!ExLHwSZA%cY-oer!i-TQ1xX4gu96>#BgkS9(u7Ibdf#m|Q@pN-@@O7>6=%^f
z>^IRyuI2HwUcP$rC85^=BaPHjotl7K5YN2rXZ18Q<p{gF$-m&)(G^Ro92b_X#fFRc
zcR;gC#aiZfmXbjv6X1FD8k{KI9uD78m4@`#6^m-FQ$#bL&f2$}<OWr@+%;c0*Kysr
zym1+D*UxXn2`X8)2wythcWz#jV^+EAs<-hD)5TSJ$FRA#uaghuSX;#{S$6SxJXb;A
zx<<EiwmhofRacN&LWufU*SofKOs-If>m&iRdc256o)*JYX7f>)_Pr`bk2wc0R0TEa
zuBYN$g*k*3L|9$rx3`*UM(4SHXX_dzJ`}pcG&AV%Mv;%(7mCkp^nhB5O%>0pp28Tl
zCs)HmaXx|7+d$Oh3T7|ZgKyh<>dmT$sB6=onK2x;_6xJgt5Y+}n4oQ%I+%%;{8_x7
z;e<B^0Wkw!bevWcE>Rs<Z377QO@Uczhx`<s1bM<A-t`Hp%0fxRYWzTOb=A!OEl4mU
zdB2(2yjg65;=f!^Ksyca-AP4Dw4Sp4q`>D9_jt)s+*U-b;^HtG8Qs!V(?VQsdx*ub
z=~BRi^9br&^m`TFlrZ`FP+nVud*80x8<sIoD+ki}RUHbumKUmPr?i`<wwt3kx2E(7
z>9OXO#7Qf!2+K&Pk%`~XrJh~i(6Np&zqZ;|yzy(iirF}a%*=de<h*5Dy8W;X=pzr`
z;j!NcDXxeR&5&UkMeQb#;Cjps^`C5AudZdXUg4Tfb?xiQ_mi7WlH%}|=Tmc=A-2ig
zbg2j9U-Hw=mZca4D1!NO(^lz=I_4XJKE~H_v?Geo+hWvw_e<WS4NOK&1rbMRZm!m9
z-VC1K_oQz`ezn_N#cP>|m$V#NOI~zkA~xw#;XBLwXn8TN4Q-c+YEUz?XbJ1e1<RRB
zICr5k*cPapc{Ph<Vp++6IrH+J7g#ESDg?`L=b(YnOUPC);zIbY!U$H!<2s~JxZ-#Y
zt`~Vg4gsmjGrV%IB*U&$%eNJ4b<u&z@#<7E%2#iJ<<c=_@3{^luXFjBb066WWo?be
zL1G4(Fl6D7$W19LWXaEoB@q+3dMPb#cp;MXncnWF(X8NR#y$?-n?6oLtkr-gJTiw@
zQO-Uev>3lCJDg~HqQ;Wy3m?T~J0&Yw?2&UTc?ukdD4=_0%G!Ua4sj7;>TEwVq<-UG
zbd*e3W{+Ng4l}`CSYIBR2AMjV@FBa17n70h)qSs)2dR>~CrWc)Y{Z%_+miC8p64#L
z=8Sp;k6Qh$PVuT`vWAH0Em~DS!KL`{)-J{Cz7Tb9LSTK0zb=c<t@1%M-`nR#hs35l
zqbT0FBBK!Xv=-$8lI0){DeGHA;*FbgM09$0=oUJgqP_yF6;B{WgP+_#k8dCq9_G}m
zd;nJ&hQ*(qm@B#I^j0I0LDRR)^dic{YLPc1Roh-HFl#p)bLM;fN(+v+x#buH{RaAu
z@56t)zdy;`-{a-s08$$F^?NM$hM{=e;)f)4%woUlc{leKbAUh%<=AdJOHHN4sj%Fb
zl2K`u?A25_ZjRSBRz#X2b%i6zI5-PObF~<-o+@aosw*YW6>dQ)Jv-nQj*?XD0(eE9
z3gaRaH4V7@f(P0@UYvM;d;HDDdZ*dDl@>@~5=^Q*6xb4lY{59t9roI>*Ce#x3<4YM
z`pYH-Xrx9jtxmgM(63RwmSf_@T;oozsg66;wLHbNmc@n~pYgfpUyJEn(H{z<Q4)C-
zMjTnq#G@ycH&Hzm=#YgM*@YyjV$&TDXDFGj^evQ4uj9`KY?Rpoi*WS&Gc3@9X+(rU
z)mFq(j=_IBT7Tzk**uStf*sXum%>g4nFB$Yl6?FxHD7v3@jGdBwKT-#`evpQr$D&x
zgUB^oz-?{Od7(|ii{nNmzedtuT?z0i9*Q^l4sO@H>pfIkwDTqI+nc>}#l2e{5eV3*
z2Mb><ICM$x((CXrZRllsgPx{Kc$-#lZH>@0*JG{CMxt^Nspc2B$Yq%NSE0Ji>!Z4*
zqXlk<-jvdetny-&kX!F$YoD(5?W3u4%vFW$8W-o1!8SL6z@JeNj<+<a+*T}2En?u0
z=US31{G;n#DG28;5NC7mmbT8cZ4RT2W*fFUynS3cw|7q2M&B3A<N{J?4dP!;2>$C6
zzbSjb9r520|1A@LqlbG_@2kFk-^?p`!`JYuyo%e;iF{4!m=12vWKhdgP-P-m#x$VF
zeawdB_LFStJs>P*CI^C&HLc_F_`FW2%pf%krPcF`;@tYf{no8S1zwlaLo<)Sn^pbl
znOM%9*_LdlwuB|+Di)NQmXjN>m^84ISoW$>SRySnzwoXl)bXk>O!fHMie~(;_kz@r
z(O!qYqZz%H(AaHB-kSJIE@zgg;X8R#Z1QT3{EacUL0rQ}o6A*Yp!s$A%^3sB>&25d
zjUz9`kH-mSQ_hvt`T^xt;S_0J;(!Qjes)r`5&*QcCF4B^S(ywq&oRrIOC{2IdR3X4
zSF0pqEPP#ED2m`Q=ip8Cst^xcYt-|AKPW9yt>&PJ5$@#04RXY2s+Sa4ED7E96!J<=
z98n5HV@QS-6td?uDxjs*Unr$`uLx>sw8%OOHT2MO+{+%Occ!wZWx2w&x@ju8)GP@C
zP0hopX%8xQUl~me%rq6@a`~QCI<ne|z3G^<49?Uqx@OA_orkqKR?kWyRLy4SVx6@H
ziYV-_8RxQ81y2uT3QuHN<D1)QZ7Q7U_O{zKbwje`n`$hva}!v}Ci)bZS(>@YPDSYt
z3lKkVbB{=*KBigyE1&Q0(}`r_x3Gfu%5<ONtS$4G_Rinvt^3x!lUM6a?wBDl|1Ip3
zY1W3A^~?U=&F&0MaI3pgoU!4K+zN#)OILY{{wAAaus1g3o6oW6K^7fP*iChV*KuK{
z+q{nLQ#X(gQ;|cAXA!aLTBedvtdA8nd2+HEyI&f-`V>lCoGjP3Val#3S=U}6ZRiG3
zr8w2~;EL*Z-r$0wi+&R>B3Eh1s$rA(JQ{_{!aA&?DXi{l@p<)>JE{P6r2|8YyJE#`
zBv^>qN`+S7gD%@!_~)6WoJs}5rL`F>l;(|ej&e<SR@kbgWT9)_G8+WTZJl#8CvVka
zEUgMAt5n5|IQ$O^T;LT#N!Juld;LDKH^ubS?tDbMqM=Zz!?6!0qAA!a%BB#59=rSR
zMKIx|G|ZGWV75Wgri3L;>OeKBGNqPf5>k_;bQSLRwzHn2X4Nvl*{x9q(g1Ot8jhx_
zOXhAepG;xZ-KxTm_VTEIg}rH3`cq+cG`cO7PvI(67mP*W{lNhH+1_c)7n=R`MKB)~
zB)U4~>;<jBz`zvh(HEE}()PadN*{WC`I+00Rv>46j@-dPnIn%OGR|S)0_793d#qe3
zT5G9DEz?U_?FcQ#BextQ*y6KFH#OfHmW;&6_wq5RZOtb+_k*(f9w&TTDnZ~)FgR@8
zuS~038lLj1xQE9kIQ+)C;m1AY+8RCAvC4qx0E<9$zj(Ho&*LQ1A`esebOa|lxunoT
zbT)yO^hk!SOyPvgg^a2XDuW)!*{SM$GLO?VI*uk$78ME)66=w~Rt&mS+`lx&v|Wt9
zvvM`bE4Gb~Pc}b-ocyce{60EzT^SaqjOAXOS~}q-7v~Id{a8bg)N<Eyh)StyP0$&9
z7u3x%ZH=KzNu<_jv1@u)15x`ah}z9YL(;R2MuNL7Rnc`*-3=jCF$-~nlQi<IdPr8q
zo;mlgG^c%HBrL(H_pSG$dreEI0N-X0Qo?VUuad~Zg>_L)g@8@@b86)uVk4t$iBdD-
zYyLr2_<%CLXrCZB%gm~1aHb1iRmtG{nzEs6>Jaf{8@uMl#21%tqNdn%DMV$}LUd@L
zSXi~FYB;Ytb#0x-k({*1ewYTc<*fBg!(qnKcV^E&`=02?P)F`J&RwmNe7v?~nUn_=
zf2sDdwwHS@7NDmwky5Q!lcA*ND9*1&m_EKxQrD0PC!UN7cO|sMd^_>1AV@L*mRM2Y
zTC~!-?HVg`H-w|JG~%jO?YiZ$akOr(sc&zqnRqKScXKF9-3080bV07F>c2Mh?Qd8C
zyk7Nh-Phk?cCE2X_v+h2%))b3K0T)k&kM?^=Z!=yU>Qfpvfxn_`B5|;hv>W~MBB9B
z!MKOPM<AmnqA(AU7(W;91rEE>d(?YE2}I?eUw1`+^p&L6vmw?rkQr?zG17I2?!i6J
zJH*eYVRjmiL`RknFlAlRC|d-GOFgrLB{Ljz|7reLJhoLy=6;;1c@Tn$j}%Vl*(Liz
zHdf8s`BZ7Pm`9_0vqw2gie?T#!hhv}6wJ<S2M%c9azW>=_do@;^gu~=AUs%SwnMRF
zskaj4rbd_aQ)!THX6j~vDxTihSiMO#iipJ>$;o=2zor)Gws4vn9c{%w9X6U8qaLx9
zE)SL%peA@thGg#QkvY$EG#f?3s-&3`*_1NfgibU;T3mCXN=BL&!eN5pVjiZp+mHLo
z^ES`C4XYg^hg|;p6(4+SnVRdxtr#q35wOIz_}sWNq7PBnY!tpP(UwBQ>>y;}cx>)`
zzUO<PvVl6!ZH3Q{<9OmlCo_x<6^xyq%PR5jafBHWsIol#3(OApQ1Ul98YXOuhGt$?
zDog($Pwvg8{)x@V)2f!(S)J6a^_UrxM~z?EgFj3q)C`=^NZhifn6}XGJl~h^0d}sZ
zEFLi8orS3i+O{OrD+7uhRyi{$y)EIFf6K!N>*yK!@kq)j#iFfHWm8W!MEQfo4Ghl0
zOL@6<x}NqSkBTYiDD!-r@g$lXrn_d`V9=M?Wn<L2k7ZLhOkK~nNC#%I^EzO-8cM1+
zA05My3niWCch8BfHiUfFbYqM-o8tz<NkWa{z`PKzWXbQ$CORJVcXdH4;VXEcOlh8x
z59pjU5zBIlcJk(VK+_jyG?@dnM4VLtB!;Y=24}lnZO9dCns041JnGbX<GJpmX_%aZ
zFO<MHc_Ec1W?tVZf0V4V?TvX2dcg^o_NDJ60jQAzR_5azt5jN~aI&IM&R#WAo2a>h
z@PxCB_GCV$;TZTL4lA|r3{fmf3}7+N<--@-J9i*I0XYJm0Somq%!6MTmV#UIoPXSA
zy-gX{Cxs2o8MyHdS1fU(iOuxp2%#NCiPBe0_999wFDxo0Lf?8X_+z{jz8}Xx7i`9!
z_hN5<_xa)L{eKP)cHivm@4&Cfh;dus>bf}gZHdWXuxkkoA73O9vV<|dI;cn1#ix%6
zLaKgh3iTZiCvi$c*b)?{n&ACz^;v<%S(OaR{%GP~^){TRX_YC$%ThpF1FL{%_BidO
zBk8XJ?V6>2ZH%PE_G#Y-Xapt>wh|DORTz8SaqZ#tN44Wli!k=^)`HksvS8R$3o+L$
zM({6NZ9*oc)2*8uu=4w~!%~{%x1sXf_%A#0$^Kk?`PWi<eSU3-tG=!%h;I~3v-L#R
zRS!el@p&F_QC=?7Aj`reH-=6oWX&`|W8LYJ3N5QMQr7=0iRM@xox$mGyMrmsfV%5{
zV&7miLL((xf?~K-z_r}7xj>W)JB!&O4M%ntRB>4O;b{_Q`Ow^Am+>HLO4}83PGP)a
zkr_ud*A>Eash!&K{%YjLUgBwVbNvP@Q6b#r*H#CejbvI2bLJFR;-<B=^B@_F7E@<(
zc6{$+FBbeM0_};iz@>K@CSkLOD9oc4&tNc?$U#kWf%P%ss^<Zo=K<Z<-op^l6f0<8
zL1Uu=Mb~p>6`~UPjH)o{`Xz)<DezoHI#Diuy!T;?Dcgq`qdvE5oyjYvTs60M$>;mW
z2u;&}SDYN_KXHQ^$~jfiL{;`4?OOem_vKP=$BnEf`YpuGn2wUgiso<GqDmhv<J}JD
zXbk%!Tq;EEI3lOY&-WjfeRKa2u8b5@C1HZhS(L4!ffN{zDXqqHxZ9%QH*hf(K1nIL
zj`<)S<c1tnZ(cJGwg)RibYwtxRO@?6pj|4eF(~h>P?}KE0xQDM6F#Mkg|<l)f=o;<
zI{4H-3??3>BZAXmzTRj&K#u_m=<?!)Ty($-m!l;g&-fyoOvph1OOi$>^b$q;g84{g
zO|NM@ipCLhGEc(s1f>Wx81{^N`GLLK4}%${wq-z!H1`NGwd@}ZF~zAjPoi_U@64x>
ztD_Ihp<*j(a2|?SqhdG$_d-m0>OV8q5;c8~dnp1v9Ox~4p73g?)Lnm*HQi0ut9TSp
z(g~8YlKDo^fRM?-Xa?$KmmruWw-{i(<#@ZoFq`rWTh0pBLZ11FuWCt8rtjfM#zYpb
zeP&Z)ZAbJ3BZT+eHo)56crLdp(Hm7xS1#N6*@;pN$jCDUKtp0m-9}mW2BYwJanfn1
z71)hU=Dn$Bd#bc3*@daw*`_YR)u|H=cO_w282rypn7F(%yZkZ7<1XX-zwW%;d$Du4
zJJ@@5aJcjG<=(5Gu3MI#kE=Mr;5?W_mV&A!K9I9ew>5D-uCv3|lzC&DQCs2$e;TdJ
z<$RIMjG1eMp9ND)=^Hg5%3P)JV^!$4*hsfPQ)^ExBRet=(CtSR%7j3u-gdrUM=&Ha
zV0)f~CxdB_4NrmH|8M&=%jO^OKk0{YHt+P;)|7k9R7!j~CR^m<i=@cIS1>!}F`$ZN
z>_ucqEzFkppxho^a>ZZI`M`e1>r?47Gid5$&Dp~BGh8EFHQ0oeK^LDi9mOF8bZ8}N
z<$ea}D$pvqX>-ChjVFHp2OwCEy2jJ(8eRdTq?_YKm(H%ssHAHOuj$k{*oqA_9HTLZ
zhomubVr}QtXy;if!M3_6AZv+Y-?s7=Z(FTe3^q&>9uVB`Cqa~k3}pW~rT*83Cv`zP
zN=prOYLdf>#pBw(c;eBG1^8vhuXuR^7^}U#L>|=OLdzg(QYzJO>YZeG8l8u0hb%b2
zBo$^sB9t-SdH}8MFVAzCN`z24NYHqfCBZP;oAFGnBCLHA)7IKwX!DWmqGSEZY;##s
zh=ZatNW%Ff7=}D^Z0qd|u&(tsX$k+Yw(oc0=IDAFsP}F8)te1zK2eup%a#P8G90&n
zaRzeO-#grUzVp%}{@vHI4l7xPM{$^XRhjy+Si48prw7;eA}pjmfgx9u`LJOP1dv%s
z&rU*b61<nDaq0MrOH!h6Sc%$msyDqFpV=$k28c>wLSFLh(M(zTy}F_`Hx=gF_}k9@
zD-dS;WH@lvHZa6Y(j6kr0a$4_nlS-Lhd0XHhoKS%w_(szf~al4BNX7QE@hpaW4Nf4
z01M~v6dEDG#1l!w;UbB$OE~c$1rY}(eM7bMJoM=B0uRf51A$<OF&vO{a1^*e)KXD<
zjnBp0`po;b22-SdXRGm3&BbYW(akS|i#Rz8NB1iui)yIAOXziGNx`7yI)Wi<i&l00
zFqU=mxzYVFs<VaDT~?2^>#)rGsHO^APkpVgx^hFE&|8?(*e_|AP*j@TG@+QVi+#wN
z4Pr=Dm9>0YY+PAejR{})&yhc6B9W_Zu!Z$s<yohKVYhxowo1Mb9&LJ`plvm-Dz<!8
zy^2M+s!Z@>biGU&%X_W;xcB?dyD}@vJV;ZI)XFrThAbw|8^$AE>7A9}qC62;&5Q1J
zirs_1h8R{i!Pr>P!xJjYg^}>Ip{Z$RZzuEcM#w-`is#gk6=&ep=H+dIlEQI_H@m&m
z*h;*}H1h%GJj(y*8#C@WwF1Ex5gsPy;}moqr;FhbHY^-<;TFr_?xn(GaBBu0yPE~*
z0h6IkcTi1(Q(e8FuJ!1;Z9%oHKIMn2YFkeJoa1^oA$$e#Cz$2ok7La5l(};6sc8ZJ
z?v|G*J%CTa9Ddi;<48-&#{QsA@7%rAGz59<a78D45apn;U%T%*t{#+^kZoMPL*9`9
za_t>0@Mx9K|6!Fzedl;uI?$emif>Cxh59S8n%a#|9VDU-#5OBkm$}qgfR4T5qng=K
znqtZU-PISm=`uGK^<aTq_!U#@@QI0K!{H*o@3MQ<<0IA4-gYSD##`J2@ZECTQ~KsI
z#g;R9fF{UA=`cQLd1Y`!HH}>jby!CktmHEgBl=F^;41GM*NjqEb78J5TX;j_lh4f%
zxz$WRy?S+C`8^uVqAa2ueIr)7$*<KN6-1GQYE_)OXM+dlBlT9yRcjJprED68XcVob
zqM5hh-<-r)i;rB{{mCU}O5(2efx1_%Ik;`W`omC@T7@>h0taALIZ)VJRF{l3DVw64
zRb}#D;*HTN_8H6<HiEx)6{FVK8=d`bbZf6JNn4!h?&}%2@iDIa#8-H!OTyHWai^RX
zA3qfr=2m5Np-3~w66!OtkEeFkJ_22*umd(X6n#XI)gMMg={+AtO*$}+Ei&C8H{HlA
z*7W{bNTYAyVmPW<7{YH<DdhgPxBBhZPbha2hdSrywQ^B{ii4%7F;9~vv|SsrGNq<W
zqqNkvI5~G=mzX1yi&OH`DUn&ejoMR`w<_uGTI=o7(rQ-R6@G7dxm~g*v?!03Vt1Bj
zlcz|os^#l1UDnx*2F~Q8mP_0<)iTr6$#F`j?PNguBNIzWGLDaY_*}Kf)u<ke{e<^}
zxFFoLZYsVi0M}}i7E_gBM+@sM)X^-JI<=S_+L&vkQ<~Q7ORJ@2iWk{@k)a|j9#!-*
zh7N<p2VS-lcMf%M)Ti;aggL>Zdah=V)2h*vld98ZAx*o?ZfDLZMHi1cJ(=6WLeWsI
z&j<7*umfgH;lh(;0eOpBz=|E|J9n2$?<|^;-ObdcmiKF2Z0#z^3z)yeiiDR-65UFj
z00<~mjARx!XW?U{JJsS{Rx`q?;M=}jLQ{50Yzr8RB&B*?7=ZoG;))^MFnCGw;(OW*
zJ)!CGFJ-T^_i8;vzf!s(R*UP(_=b9gI|>y+0!w%1=va4AO>@h5rzw>t$tzl>+yck%
znDQ@~1=!pwQx<vZ<QBI>S>I`ZLs!drS*FH!&D<b0dU5492edIInq>@=>CEzSW<~OY
z-RHmT?;ZZL;BA3M?V)Z_Dei&IB}oQ7jDVNM^bo^4z4cSZ|LMx%^n2fHTb&YIr-x+I
z@oQy%ohRWK_9Yw*QjsdfWUebT^NWdFxxT_+LYK&Q*4)U0^HToK#GJUZv_eZY6g97>
zgXXtv-dbA7t5N02iB-K#;C?723T5*vi9w6Y=4s<Q)*x7sW9>LTS)^QCpogw;5KY)q
zV7VsyWy?C+m_LFAlOzmAmx@4-ku@k^#53`RNZxkGp*8R}cQJwi<H-mg5}AijinuFI
zw*AB6#QWRVn;YMDu3YcMM976rrc1N9&z&1KyKKNgO7|hd(KKNUgv4tWWh&3WrmYV?
z?_x-P#6%*NOu$PQCm;u6UQzjY<(QKDLly}Wogtab$Imrjzf-`<M8zP$oL)^|zDBPc
z*Gg7@rBnB=@z{%0B#s?J@jxh&)C{a)W<P%i4qZEHtl-SR#Ng_{ZJ@9|@sT_N0fBjq
z_Fcg|K><~lx#ZV+=`P_x@66n}RTQOlIhy$&T!adioZy4R?9%3}X0lO9d<C&!7&@|j
z>jp!6r3<;0=cre~qQ!P;l8lBFE#DThRi0SbJ}aj!?sdUXS~;zFe1O67OVD>(?F@yl
zp2yQEEVCj^tW@`kb+b5XSG=&?k7nYD#fD!lwN?SU-#-p9Ukvra2v1!`<2qEQ%2`Zm
z)m1NyBmm6(%uDAWQJ}{SiinF8O(V=3i93%uN3j%+bXa67m3;27t(VX%aMT*60>%dP
z`h5jXUV9X+f<=J|bs9fHDwIQ3SWrOZVS7w&=TuaX<|{3+S9z#jwve2Iu&N8n)pSC<
zL+bw^q%PM1#7*19_z}%2<nr&xB?JGO9s!o3H_Nqk?=K>h;->WEX4iFO%^@KvGN4B}
zE-l@=AyT?3`7BQ|jmX65A)pymkR84wo3#GHpUqq*el(&-rNc=b)9t+)?Ci>n$bF)n
z>LIEgKS4ItF%(rIgHA!)4<}otRB$h3e%Ynon}58~WN!DPv7Behg<|G&)%twS%)81J
zWuldQV>=zi6O2?&-#r|=NM8T;>gDU57rXm|H#^V&d*`R!0qps&yZZ-wuU~bR^64@0
zG!PSDa~H$RI}IoE@nTXTF5D?;cS_plq@=OLO04ZDLL+e1xaw;$i5ZI|yniPae>S?_
zoj!Mm|95KPjp}=bgLFTWHqZ#Kl=cgqCwb94N-T}O@5k(Ipe06G1p%rB<S?BEvr(<Y
zVeBQcxG0C<V9`44^6`%rZS`{!Ve2Xt_EubRzOv476Ym&*eT71mv#&>=I5^xn+`T?k
z;`wPfJWG)RkzT2aCT5ce6o(V}WX~V*@$MS3ZrDelO>h!mTQhqIIV<Ch=#zY8StXTu
z`e7N}l-JSKeY{Ko!^}6BJsalOCm#+A9Hh+p@;;SLAtijEI7`;s@0RhY<4)05_WdxP
z>W2?r9i6}>`AaB|e12RAJQM%x=UBhvuy-8xKZ?V4t{z2Y^Yzs1qa&14sHCoLCe=Ux
zvsU7`_3{?v26nqg-c25&-LI{=)zt1+*RcnOun5q6H_;1n9Gt_wz>_dsc~1-n<^sp>
zII|e!u@)cief&RnKcB-7UR$dhy>EN#Yh)hyF`>#gqqXNR_s~9Y9dm4~uRnS6$ooHV
z@Lw1Hg`X$uPabWuUwK3Lm%hLIx%r=`-@zf@qu8ClGf_!kzyL7dp2t4VA4pQ~5lOm_
z`B&c~TR4f6OE^AsF~7&+RG5&=<#qZjSY)TbnegWzi%z^Bg0r)5<~>c*<L|j!`m<ug
zpMXbsKZF4Wia#BOAON4}ZHMvvGKo%3Gr*Z|zx{f3bAA0=%GS0+gQV1G5)H#yO3?7s
zXqZzijTgx<?8V8+8gG!U9jBvJ{s-c|_bR;bemHpHy=0%!XhK4PpXa|G^u3k6QQzal
z;%$EY&E~@=9)hvD{s{i(t*`gjzwK{4`X6t!7%%?tRyatrGtL}c+1ljhr4btN=m*ni
zdBHh|kd$$beY4LcsP*2)Jq+*R=Xs2ukqwbPHCO}1VRKWU==hvjBw#aUp(onN)Pa=x
zPRQuVmyQK|@B1Ec(W@Tsb3Coe^QAK_ldBiL$6pKI-21Z_pZ6PjmQxHi2nwX!M$j@D
z2g8u*nqzU~5$TzEF^2OX(aT!o5oU|yNulZpHeL~--T)pqy3xmzIr9raO_i_=71HSa
zy}X6Fa2OjiOs4V+DQ5V`@nqz~FPP{@F(ddhjNap!hWO{5twIj$(q5K|<D%E|EbI5N
zWm_+3P0)bQ7S7Jw{^9Qa&n!Pwdl<j(cq@b5SHI#$QZ`>AB8n;W9`!cxI2GwxKqD>w
z^Ei#(527^4GJK@NqG0Mr?TwP%4~^n1;1XtJX~00q2dW=tOyvw%ssJM8Bwn1HqERE7
z=N16vtq@mc3N=^Le6Rg)`#rY%aGq^$u77~DT)gkBu~H9-v+4qVf5Z;$9iEz(&H=Hq
zal7?jL-v25r)_@S^}gNcdXK*Cf>`jaJ)r>`jUV;9@@UFf<#F;g>q|S&KqR@Q#h4e=
z_158k%P*_EG~<XL4afWXVDQ`Cs~4|-J1`*8@4x>})dhE69qds`yFwkeiqKykxXbbZ
z(Hjr@#2kP+iqiQcxRfQT+-0eG>zBYa+LjVi*9+H=0o-%~IILV`u5evg1vb<}vWySu
z_*7AT$Xj7=7?_k!Y1i-LquC_Pu(Y}%c1nBrfGg@aPVvFxnfKV{qh8`Tlp1tEI5xn{
zhL|uqv_CW&o7<8t!5kT|ta?u`WJz-*D3Lii83@YcN`<a5mK$<9H}H9?(|3|xgT_1Z
z=^*`g9jBTP%vud+Ep(L$IQ%6B5vL}`p*7G`s(rM|WL0v*&C#E=AFlDoUfs_9(rC*z
zq;H-_4EDbHOz_L^;GV}Mmikv)&aqKWVMCY4X5Z1!#j)8}?xFMJDi5t5Wnt+2EBEjy
zKG`5=-x(oiU%7KHsjRm3x0OitrY(KP|G+&EzYCz>iIzCcyH;l@i=xIb$~=8fxO>ri
z%VNe=l7nFq%`*_PK=>z-Cq2UgyR7&aE0sl|m2}Hf%5#~=AsX?->zFB%3~IeXT1_gJ
z#)pRAKzK$!Gl~$toCVW}g<~;Byr2w{7pD=hsWcq2r(}@011zPMt%{5-DZwiy5QWiT
zJ*2;3M3;Po@>6_9Ud+3ERAw>1RKb`AXE^J40-Fa4gc#N^V@gj%=#Mdp$r%G@876U>
zu1b|pz8l4PaX79p%ok1S-QgL$kq6LTiAI)Nbbu`n_--9RyLTE(D%P%nZF&=9B75cN
z)AoZEzQp1rc_wGE2l-{eKCu|2i|8c>;N@dwg<$<-T?nX^FJ%QQ2gv%<G1c7@>tlm^
zS#V;OYxwNiX|uc~I+AGzCf)@;@TW!d0hTua;Ou&0r|X=isjP0HmJn5mpqD+y#^7&!
z1`&8;ieYE-(+Tm?5gjVfBQy0H(r1`6{$OY;2v_0g%_#*9+QBu$cC>B)uhdEoYgk-G
z0nPGQh`p=|pFvI2gBW$XqE1JC1nP>}d4#`D8~BDdJdIgOYhtWqFyQP>WrFwW2?d5w
zV-7b5k@5oD>I2|j@HC>bR${-83Y*^Bl8X#(u}s+sOq7w2iN|S?bDCA})j;vIDK_41
zIpa`*Sqg$*T2Vltc6f_E>X8na-H9lLi-Hi4w}<7kXlEf9*`>iDnyvh85Imd$Bb|l?
zEIJkb5#7%28H;D+ZEiW++I`-Rf$q+>DwcNtYHQp6oY$5cL+Y&Y{`Z>kgkItGrBRs?
zzs~DuV-&sB-4VIo`xWJa>est=&~DD8Jb^1)6)ZF2f-$ms8|&01d|TH_UVUGmnK+yI
zCRAA=Z<b$$`sba7SA^(hvvM$bUDn-Y*BJU-z~%NPiP3%y|4cz_^BtvFSqmzgz(tO7
z{~}2FMTGZ@#V%5;r^tpPIfz#%mmdKu<R8^odf}{@UHC<i1!P#xq{E%(^9mlO%YGEG
zVsDkTtGJa8K%IkrKts*h-k>X+*j`sY@O*>y#VzSUuT*W}Bj>XId5~0blESG_4@EMC
zzX3oR7<u-G4>h=&)|X2r^?GW3)C*A%9H<-14aw~uwjucq?;NiVPreck)=4!^IG9%x
z2hkOl7vURPijN%}1-c-qg2o&w1-GK~tXF@A-_!&rRM{o3{gJZbD@uMyTVcJc;(qlF
z*37=fZ`<6}lMEQi^hFe)^OfX34GTqAj_YLml{X_&XhEc9Zf5cig<fl36?Fw~WoacP
z(XrdCLi=Kto<`%WUDP-$ZwqF!RyAG$N1>~|P^j9sG`$a?jpElcqD8l#;PUwauLy!^
z`j3?+mYwvB%wxIns_SuNB!U&kNnYGSeuRrQn&ckfsOJV*lp=>Qnr_s(I`j*yhgXl`
z4ur&^S&<x}10wI^_XvDpOj+w^SbPxug_*R5U5GLBnl@;~@sGMvF2zs9??S7P0P}mA
z05Y3;ip0+{s1^-83T-Rg3&AoHg>oCShkd+^d7{)}Rzf!15&K%vl|1o@xOa=ynsD+`
zH&5wkGS}z2Mrl3~q{}`RCMBLnzVIQ>=4vu5q2bi<lr@S?Y22x?QFsQ?#oKVagvlep
ztwl!(Ch1HT?k6z7pGi1t^Omm5JRF|Jf|KJ@cf0j>Zx=mB2=i%jBC@}=$O9Yx)9QQe
zKl1|xpx%A#yq&db2Z*tSfAv+vtD$`JAO&-b_9-Yq2m}mky7{e9L@GKwuUw`JZSa#&
zEzqG}LQG6&{C*rwGJL+vFO^)57guX%tL!k#+nX)l%7RvS1X+1mIVEDbM<J%D9|AWH
z!&w^rfi|?w^{QI$0$OuA<r39vR1l_F&MDZ=oQ0RENxWD|!W6j|f7OzpYn#Mqv(%TK
z+6#IUrlZ^_0&P|h03_yvPoJ4}XY^@efN_=soeZMdie$*%_i_og#`K8pwfMYV%VM(R
z!`R4_k8&j1z4K~S`{v#H*t)z7a?lb#z{XBO&~y(DU+lf=0?Iu4#^k=j4v;MtlLJb~
zkvM>+rfnLQJz)F9QKeZ${eG)X7JoLG8SUUIOS1t!rxhuf(=YR9FWf<+Fde=OXD8Vy
zbejh6IVDendD~|UQ(+>d;_%q}M|SaVd#(Rk{Zkq5V_G;7GVsXFEnx0eG2J3GS>LLG
z#xs|miyM|-Z{nzC>|)FRgp<HD?-pD|AEeDuPg`x@`>&J=cYpQOO4L=Z@)?>!U}URb
zl7fYAXB(@uDIn%><uEvolMH@=%Y|JySVEJFX=S8c$)<BUZNMT8SvS@<ADOZalWSfZ
zyBY64gE`PxXdY+X7Qj04TGz|CDxPn0wt3Ws{prv=tKNpi#D*8YU{2PqMqZT;c|YyG
zHZ%p*8GRv%tqE)~Hx*2c20s!V5wTh(m$wGTrtSKD&O|Iqj|wC0%XHo#C%Zh>iMg7e
znf`?Qg)6rLmTzRmJ~rOVrS?<oDPzA#4HY|U+TFbK^_ag^{%tSUV7duR64P_0+laI3
zs&}-18K!<w0D|S5oP^1M+^gEHlAmzDuMA6;(#w!CT%3mqsI|ZfcL%>5?DDdR%AR1{
zZ8QX8i_<8J&J|hBCj}3Ifqy86y04YV6Fq0)Nl@rXjb|}+9FOszb+xBJAtn+}=0ey|
z#03qTR>p`xWAv17x8|ql$)0AT2pN1!tM$x81R)wgw~}Bm9!}yE3xKP5!6jTztNfr`
z{spOyvuW0;{M0T76RRnDUP#V5(<Sz<atb!lwpgRLVmx^^wJVR92jnZc3WVhei-e(A
zWmiV<->xS#3Z#nMm7+iz@>!TSF2cng5k-Yb3U2H>xF^m`tdoTdphph#DsWdarN#i}
zG>B$yM#YB%ogHS%U!Mk~_~N^e{(ZxWh$REJ1iy{|ZV)lp_6ZAl-|!uG*l~TgTJBqr
zFL1Fk{(W!}B(rFClGe$2sW=DvRaG2e5lME4=J<9YY@=ji2kB`PCS=>HC@JI*1ImlS
z>|i2D<~OkfW4}%Xpc%rrA78Wu0ot~w%S#}!b{hx+XTldrFei{6Kkigb2e$~@mCn}H
zHrwQQVse;g>#<_E6%W%8%d;C$$#B9niA7%1u<kSrM#4oE)WY1(Q2M$G8RfB+x{4Fx
z;X!aLr0^|saE3kR>`UKQ;$k8s&IY;cDP!lzB6@aGr`l}3T<CB$O#Ijcm0aj*MV(2M
zW)41dUqcCwnf6UEQpBq`ueg@i0<u57SsXkZE5AeUTR`u{jM?<gPL3W?MG^Sr@jI8(
zz<(k=h+^2M@r8+>vaRN~;5&N+3?>Cj%VCh}&$?;t57#XTDvUd|X=}Y{9Q&~$an9CX
zh^lDQ8_|wuAReR3Zn+=x`eN1u$19GMg{jri<~y%aY3G(A(cEi2Ma>m9`B`hJgplPO
zrNO&OnaK2$(OVKu<1Dl(AS)x%7~ycX%(UnxF<l1bNmQ^xX%J1)zQx&5%D5FmF2fnJ
z%02Tc<YxAD>m}t>0tH=VCMlhZGpiHtE>myO2)w&YNmgeBz6BftJ_7els_e{T?Dft(
z7{5;c=lrr^1MvRh2C6f_!2(oS(O+&K`>;;`7a?<R0E}pLMgLL$p>+(y$0o+9azj&w
zrI9<mQf_&KJE(qisbcHHm{jUbVW#^$iIBAech1L-&O}2aW0oPypejE-%DqVa7jlIA
zXzarm8cQ}(o#}7`N8g(CU%g=}Z<QK%8b5*snSS|;kG80Fm#?Vkx$SK_bp=g6Fp2`3
zk2`g9${K}(N8i{z1DzGc^<_M~;xeof%~fTbD@Z-HwxPzd%@1&PXNemSmuiYkHFr?*
z%A#ylzrS0YaH}IFSuBY!nk^hUEGO606=d8#l{TYJqYzt@6_`9p(9;ZkVdj|Qc`!^S
zWBzPzatu+M+3M7rz{N@2sp5*!2}+M5*yM=B8W=znFT15A9X2aEJwz;ET}gd7wd5a|
z$P?Z5dgc@!=0%8={sYK~?!zp~CZ#=R&o}b*rl-1M@gBX_+gWSN+5=WMNWys-WbM{=
z3$tc2-!Il#?OlRUz1E7kc}mWKtih2_R5Q@+?OO62(eNSyAt{q#?4lv7mpdDU@52#h
z&mP8;#dKEgej1&e%Kl1sy*E&9x$6wZ<VgiQ-MNBq8((bh|H8Xk_9<r+3|REVf{BY;
zMsF;W%8ld;(>?#t$F9v?LC_`SsgNP~jGZm=nKL96nV`%knxTikHIzsKhpkxZAx=x$
zH%IIiwD=;h2`@m|!B*5&UAHzsr9TAV>O4;QAc&~!b(+*C<LpzA=_39xDWXGL<eh?J
zn4Fd_%HB1)MxGCu``9oyCJVO)>SC{(L}mt$CXJtBYZ%deAt8|1a=GVq`C6OiqNiL{
z-BMTtgIH8~FCES-3Pt5aPbg+B@O^<>;^^qUC{0~(122|$U~e?=N26;JZTw((3JOtM
zCC9E;%#Q;c>@=8-Cg_bGz3+O{U`S5t7r@srA2{<bPwyGeS8n@sezdX9+`IViUSI$A
zq4MoR{B|8q<g22;F~d?C{h4G=M&ipE7i+&&FM)7@k(H00vujJ5h9XnnE^$VqkKio4
z7yyqpTY7RM44GjhTh|+%hM0j+*lNV`3ytJGz_R|zKMTzygY?CO#bzDLEv4VMq#KLH
zS+1*G5G`CiAy)Mm7HGDZ3PD^6%m&u6W^*n`H=_Mk1sddwVJ^JuW}(eGjCfiC8qH42
z(9y?4vqZyN_nfp}zI9g!&CHjr5d<rv%fXRsgg`1^(Qdgu#|ma)EWaKoLNRM%$UPQL
zCM4~7hT5I<EvAMcQONg-UjwG`Z%v)&!ALYPzH4xp_@%AIQ<#pV0O|+tO2B?_LR(IY
zRRH!Y-{zOg@C+pe<IS#))1!M;$msqm+ORHw56jC|EVxtnFhu{GRnL@OtuTHGP%AT5
zI#y6N)9aMxwoE2wxmBTaGd1PRNVX(e+A;;C3j>E_uV&%YAe7e$cNe2eu51;38;y?O
zh-=%}o(_cFGH@$ySUgeDtj70unD4LH*`b+FY4abg43Pm*E(bW<2(WOi{WkgT?d-$b
zgk|<*+dp*KDEY+dpdI9xYyob6QXLTHqXnd>kJc4qbv>)|(Z^*)yzAUZ)!Js>GpGM6
z10~_0B>5iVUuGx}0y06ED=%MVab^W^SYbO1vMh;?^QfO`n4E+PeX2U)()QAPl6>H1
z9()&hNCdx%hfFAzf1y}x9&>GtxUhIi#KtzWKX0a@$<d0<>3e0OYFg0MsXkUKk9_uY
zaSVg95h-CTbZcCaQ-n&hjkg-sjH_2ISB_;lW{1^2tynGSPWY_NN)6(*3S5NJ*m}p|
zFu>^jix3p5OV<FH1Q)^d!W5*|5M7J#Cc@alEN1JeSZ(1-_t=%b3P;<}!&H!UZ(9|7
zdSV(W?bNS!E<`{FE8~nLVP4t%gSt6f6@Zx_wN=ka(LBvf%PB6ytYWw}8f6uqdTeAj
zqv|GYi-8xux}`!X#rhvIt^eA7JPDPGy*F0>W8=~0!-xD=QU7D}$>Xo@>VMpN{f{4H
zy$BK#0-owbCXq}4CDPu_6a`tP%EJ??@_>N+gq~8jR_#L)g}3?jlZW3t<OM%AS2rJd
zn-BXBzwJN#`gRI_Z1f)W)&s5RN25cebhfN9uP;a?B+`iIeT~PgTmb6?Cnub2sk$Ib
z-tis>8ZOc-o<@JLIflUuZr%&bx^o_lLjJ8X6wDT5Zd@FNr<qjd!~x;n#amls(q-ea
zNDaJrDa%~%FN<uqSyV*DA*Ha0ya@()6YvU(<ys<C5=8MLD%Ax^;*5$<luLuKv)!_#
z!z~ZGW~kX=1hf5s4{k|IE3@lM7?itOfn;CgJl4?=Jqgk3j=u-Tm_a$nahoN9in7%E
z{pXj|w2(qtPrkcCeGqnbOz5!GMO#rc^IE1AVr)^XK{l6@Fk@vpaU#bP`A;uj|FHA&
z;K(1aSzjF-?!0`tyFb`}{c`sJ-#2go>$`cW{-yuR><oCojIE6jtIumQ(vo|nf^o&i
z^_mdb4)2gxUmmh*s>lq<9!DpI*=s{k4dyI?7Zpf};jCE(AZ(JF(2?^$<jI5cjSuC|
zHqD8FNJUy?p^_r(DNgdtkjt4P27!s#U_9$Q*ASp)8et~26X2Zv0<MwA6V3)}JBeli
zD0}lHT*buV{8E6W>-U4$i%VsUO&Vj215`JD$Qm!;;+Y4?-(#isBp$M!@tA*_=O~At
zNAzK_5rV8utMn>hJ5M>dr?loV0jQ^<r2+eP>7i?Y;B_(o!X;VC(Wj@xFc8I%enj<i
zBfshQ1(o@xMu_wp%`Ao#)!gQK;RNeeP&J4_Bzq>*6RlfaH98h18W1tDhnY^NQ;d>j
zlo+MF5Q$iTjc{cHTQKT<+2Y6-C&Tz*`5CTGaH}%hX*`RQRKZ5W!yZ0^3=m5(@h05Z
z1N?yht#Wf#_QV0JIO(n-kM!AzUcu93SQgR8fJR5YPC+*R2MIf9z%Tapcb^}=-v8&|
zVE4_={to<#ywE&cb@d))p^MofT?CWc+D40=ini9Ym9R?7+C^Jg?DVtV_5bi4)rk<`
z#Ji<U?2z(N`8^-Ke6;=Mo3k32;(=@Ivp$OrmZnqE&A6@3Z<!v?*F3-dKx+?ffY-FZ
z6})-nsN&YKkBTi7zkjSn4`TXENGhgY(=g5bKUPNRre`}3!>2jS@)wNPY|9PkDjU;P
zmeUcBMB)PDUcL9<!p~Rt@#ea}hX1tgBTQf2Z#8l8EqMzYK<}E?v)ml)$1vQLV6NUn
z1t+x>Y8pf7desBjgy5e-Rvw4qFt|8X)TvpTTvik(orgnAp_>{6F)RkDh-=^H9<v~P
zexN(ws)D@aBQbrheJ5raH6HsNVLRU!F=zsp9v1;vbs(iupRT<qHCroG8?zciTrAgR
z>gg@TLO=*1=;!hT*bS%4=PG&>E$Fc0@5A9DGdeBZ;ZXsPLb+Eq*Yij!OLrSuV?(2S
zv+O&%%Z#WPNO!lN?){vf&O@<V`G$VH_uaF*$C+FBse1n#pI{FAtIgql|MR>jj~*A_
z|2Eb)?%w}y<^7LrvHay>yS33<Z#}!`J>~h1D7)=5Akn95+9$;pK*4D;tZsB1%_<uG
z5n{MbjnQ~R<A@56ezx&+P5l$T)kUjk!|@49)=$?8pF_)%dCFVEkIVKJoW<}dw1vGR
zfrvWhmofWW<$dfEHunHz@)SRSrNQw$`?U0bwa5Qz`v3at_01CfZ`{%U?Z5vU1(NZ}
zr+@I@TwkX**l+0#c83N@Z|%9C(ZFZ$*8ep<1+U!`=k*ud_S=2<78~k#_8y-wmx$4_
z&*DX;TX_JN!g=`(9IY?Y(PLq<5zlw30Y;l@!5&)&cn6jz!jVKOfiKU3pgjD`J`@M5
z?0+G{$%A5h&6sb>da@$uP9!@~tng*CeAoTvL=QZCz>*Cdmxm@=7Ku!4XrLeY=cZ>A
zQ5BpwIilZ0LI~4WM?T<8x|q7l2Qs{}_uXogfZ*ESZZj5u2*?%AvVMQ*@e3#OJvNio
z1aXq1O}3YYZyp+6G1#`jf5~>64^fKz)Gf8A0s2iPVKBP%j>B-~$-GQmZ+IFGS%sr%
zJW9)fBRC~SODhM5>4L<^1y~+hYXX-cB1lBxwXT=O9@?%wxC(@{;039DD4cbbH#DTU
zn~X#vd)Oe8_b~g0;+o((xLEboXRu${xTYi<0KhR25AZt4TT!CPJq^4lD|KR~koh7#
zC1c1xFfbPb8j1Z;g73lp?%^-{uR7-J_MmH+UkCjx1f0W1NK;Q(7bqvt^WZXthW-BZ
z44R4um({u76{B~oMZ?$_HcxM?_6%Z#fWnf?sSE~okZ_EAS5kQa0v2T}n3OndE?0iO
z^YL8Yct>hTt6$Rdcrjr$EeTPHTFb76bP4(Hs(^%^J#^?_%-9o3ENBvaC7G0gZbo8X
ztE*_*-e%yE_AZhr3+Ye!E`unG2N#@B_UqbVP|gf9@|-zR)y$KMYZULCd<fes=VBK9
zI~uipJOJ$C+t8Mz(KhaLSDC?zDb29thB4%NvE$k?!*GW6x34T7VfLW)uGji)XaCjS
ztDpL&&7vKN@XEm5l(!d4`py`6*Sm}tUV2I=Fb!r4EG6$zz?ewvd%`?`Q7m?xOsf{u
z!DxhH)9ZQ2y0-l!<VE@TL##x)uE)@j<r`UY^ihb#4h^Gs>cqOptV1$b{mStn74{!=
zHodX|xYGW+S+f6ZK6-Lz|GBgO-iG}b!!@sL0G9UL&)V3#B>i9209--;8;>_j@n4&d
z@96*Yu>T?kd_EChpTqzxh~Tq|_PQ+_@F&>$&oB51F`$MS*!%N8&TpZL|Hs2yc>mwr
zxO@M<lm9-I{1*?uT=B0C{onNaKgfUUW%|F1|Nl(nzj*kii+_v;?xepjR{D#Fe@)@9
zn*Z;<&u(7+du;IkdboMV|34S`uZiGxb$JX1sV$G;Xyp&DLqx-owZA_Xf$jF`|C7jn
zkM8LI^N{}l1HN$ikJG@N{P(5Ge}DjAs{Ho`w)p1le~%yE$$xkDzfWZUgVo)*yve0W
z`t|d&4c4IlPa^+4ytDs*9`YYxz!xt6aT>Uj|GrfD4-nu>mH!T?Zt)dGz)Jb=Ns0eI
zdGzp(|KG`fw;}(*2)Ax;#Br3rKA{L$kN$5m|2xQk4>!vB-`DTx|Fe+)7zTXdB4ADi
zcT(V&Dg`ne_^SzmRs27>1^>TCkIL`AKv#Fn`SW@Itu2ok8#a>1L^RwN>X7&O(f^Ix
z|DHT4+yC$Mzt2VfOTKjfKTZR8lHV6A`6a{pIe@O1rbdY#W_wA|!Rc3D-B4!C3jTi>
zrrD>6|9!Y|C;#2q|8B+pm+{o<ck#bA`u_y+zYp*9zt2SeLk#%B1wcUrcM{;2Dghz}
ze39|Lzg=A1M*i<dCH?=&<2(L;C;#1s{C9D2@fpOMd@6~s2L0c>|KCQL{=dHS|NA`T
zKfr)5JpVVRfxG<QUt<1mIQ+k??_V|lzdG-)=KmXCKYCK+{~M1U-TD7~7X1GUSN#PM
z0Q3Lm@#9U-{2#4utOH#AN1Ode-+nsPAEixJSe+7o=eg}sYD}qV68?J;CE*~(v3z5N
z7h+%tpuc5m{`=1_-+(w8CcMd=+2PjA4&|y62drd0)@ukxqX@N?U}CA~nX-bOq<#=W
zc>Ht=<s)8&cpgJkS*XM(E9pMD?0Qj#$$Ez@NAK|^W!xn&SrJdFJf9^Ctp9E*2f<p&
zZ-OBv-}mN8bPlK^KZXTo(a>D!A)3JwgGuy9$jgR4SYc}|KATalXkN(Rr<bpP*m-$y
z<PX@EzB)MEdHHg8f3W}h<?ex@o`GTK`~8GUJcJ4UmFi`b<*z_=VK6-Ps^_E($LyT9
zpW!3lI4(lLQlv*z6HieC%ay$G2O4D2Y!Mc72J2-8M1uJN;0oKoUtz>H1ElL2C)+aD
zXizJg)UEizt9g)tL8<29!Vx7Sx8;$w4%$2z2Z)oGqPPP>(Dgnq++nlM20RZm1JO7d
zmN5Vt7_rfcr9=)d=V2RbHWq741l~4FRlQ{_(ij+_qF&aLlcLHbL0hPaai5S%mc9rK
z)ghIuMXOUuMJd;?hCzUp&3%5+n7}*6N*}<*SAw=U%~Ap7m19>e<bbMMV_6-AF%qK;
zk`Q<&Y&2b_$m;-40ml}T0B%&yx6#DZD=^R>#oY@l>w0N2q@hy}?#y$*{Mef>l6jm`
z{&GMK8V|1{K4#i8(oNyR<2VLJ4;_$I4^K-)m<f++QAYuvI22vvPdGZqn$Lqu*gCMF
z4%TsDv{EdSLtvNC-_oN%fqX&G_(*KTJ9}MIwUrq^wI-(d8(ta2JMqSd&jhxZ?hS>H
z$kWVw9Qmq!)K<_(1N{hrSBk`H^lD@etgbBM3{6tm8#c9ya21;6Oa-YmN;uhNv3DHi
z#RUq)`g06}uo0#U_*HG%^^O-A5isgELYSq--CV*3Di?zx%b2I(Vid1ZtDdKjKYlrk
zr}GG<r)WlX8jyEMlP?y5U~`D^7+ly9E-+U4V7$Qp9xrAi97Y@|ZbKj-yh%=>l!oT~
z;`8Pbb$G*KCWyWcV{owpD-*aq(%0x*t4(dC^4p|s8%6JPT;%9jAZwz4@fg&QT=7tz
zR<KlxtRZKo@91O}6K?<|MmFyfZR0>;FcPFMbsnPAz8H&B=PQt1*N~>MB$)UvMRG>h
zp_B;{^eeSO@r4wpyuJxhzdBmp8pp&QH%Y`l<Xd+~#GgG8m);lu^GLZUTJv%~aMuR2
zU~>6K$Yg9ZDxxME&Vb}IdEsW!H0+AeC(#*Q?_LXtq(y`FZjx5soX+oP<g=#{{;d9)
zQ^vs%h$1^p;>F1+;V{}T@cLob4H{1;aePK4Pk|grgU)NBV#72Hy$htEA?u0s6v8bv
zoln9kkd0Y&gf0>6e?AM`J~)v&OV=BP<6tq#P+%6L=syUtZY&0!c5$2!8;|WB^H$>|
zo&rRnxQdB6v<HJ9_g?M}1|7I5&7(xK;bbuiM@4m8kTsG0;r=hX9y;4E$hru(J5iSx
zVgWP!VjM)1g;L8_SRoh36UhbKOhG5i6%;-!<wh&f-9RiWb26@Ty9V`>7WV>;)6Cm^
z?xMcSz=HpxrA^u0p6Aoi`F1OmR<jgF=wO9LU~cFY!#=QZhEn0YmbO=Y4-NBj5ITx*
z)b~a)AQBeWqdC_i_J>56mYG?tjOMVw@3kTI4GO383{>FJ{F>oi!3<%5P}B6p0vpg9
z;`9noBq02@hb3CsIAvJqD5>F}>mT7fJ-_GUh67~*_42Q}-s+={cOSoeKb`njFaa~0
zv)3~5yjHI;={n6@szUoxRlLha>zdc#5d+3ze&B^8Te$UW44#&u#2%xT)o1i?n=ltH
z?E#k}QdY*;Sey^be6fnjYy{|rRbAS)%9DWq+@^v(YuQlbJjK?M@Xce@tFKvie{qpG
zO^rKjIEm9xAZp(JERB;oa!uaDX1FeC9$B&oYxFCb9cuQI(p$~;iXqhhJN$qIQ0U27
z2Yz}@6&F8m{}1IwXYHqOhJ`ERWbJ(8DxM%t|BsDFn-5Fz{|`4e@8W-N-~WSaV0h<%
zE;Qp+OFjNxsD3M+%{S<w{7d!_VWi=0e)Htfw~x4g2tf0#xBjI6`0M`0#_juu@Y9@y
z;YeuO$p3!bdAavu=WuuMclL50z=dgZ5+TM2r)KmEVdcN=E+Z-rIp5U%Mh;O0U{VPH
z0Xqr`NMLwO-tgk%e}O>AE$1`PHWt}@k>PTt0V+N;+`(c#hsz3<sePRa?Sb99T@Pex
zt{gD~U|@c~{yU$Qnfp0_s8Ol74>-@DQa{{;4=<wZ6yN*Oi;zKh=OuF^UNY*b$vX;A
zrtB~C{dtg>kW16_u+7SVLy7X^maYIg=WIV%QF@kCLRJ!59UR0nt&3(n&@54`P4X+-
z`*v|`E}8gr4*phsZ;ixcKLeQ;WgJwXd)dh!Xurmy;viLby%-ew<N~xN`Vw|4|I%oG
z_<$O!VgZO|+#&%qLj~2*K!CFpReIi?fF%trFJ}(whoBqyn5*|ht7fe|iw{r!$PWjD
z@9{A%2}vDdOI=}B39~k@^R=C1cp9CDYllHna8Dq8jt^u}&Pkt;jXcIa`~B$|rn+e}
z&A?wB`35%*XPJ8SP{$0h`+Zt?-(!Pw9oDxSw7hTvB02*2eGb<PPzeNBb6;#!r?y`0
zgsg?GBz!Y^p5FpCyO@mN!_vZiG7KDt-VhY(Okc)F?Eo|rh8X(A-u~|M!`J)&931Sv
z+1cNLUvWZ(YlC9_;6Y(pRQzzbX5(DT&Maoc0|k|+*GrI^H%Q;iYDio5J-lyVR;$m>
zxggNiMTj>$&;NVpr@dD{UC+v+8S}gmBu>U%Bc$m6gnnzN<(l9H#<^3nv4!u^P@OY?
z?>rybkMH&Immu-CwDHf$9w%lx68i^wJZ$DF?YR7o-;BQE5VA7Di~?dQ+sMm@7o&E^
zdO%{%9znWg#q5Ryxsbc*P}g$G!(fI4&8XSKTZS&gmI<{R0!W<1j@#InU%oc1Q7-s)
z*_#gf>lRj6!vx=M<<Lc=lQJc~<xwZucB{aEuVZ&r+7ZGtxwsfPN6uB5fj&T^<-|dF
zYir)0fBxw`=ZAM1>Jy@K&OObVNA5Z%i+2Q{u5X##Xe~$cBOeX00UwOUxR>-|go$)Y
zM<vdgADI<@Xqc_?MXlW>>|`5U$}Q5;bQ5=<Pu414!=|&>_U~vV`sypP=;flK&Hjp;
zapX@&kJH7}WuP=|a>_P&M|erJ8NgjnjMw$x7k)3=OspSG=2|9wtv&-SroGwqT05f=
zy?5a*S$4&Yd>=ommjD|VZ$?ScS*(&UyA!*f<=X1%_jk$c$C!qkrG#WC1#dr~HybV*
z4nQ<)Yph=pIg7jjy3?i;&in%uQc$5z*cH3GzyErFu)llw%l@m*7OwpF-+%XBz!j6B
z@BA!d!f#qM(y!tVC(o3rq6(3c5P_Sn!x5j+{vkAs8~hxPqVXjc{?rZN&!bEbEK?1m
zgD7Q00OPud2EH~C0uw@@>vhS%u&!hD?xCec{4vla4QpEom`Xb+JQP3!Q8v`zyHDE~
zj7EG9B@uVUUDXv#sq<-<D2_oz*4lpmW)%;uA^5mn!np|b$Ar`(vZ<ic)N~#v0d#`y
zg~1WM<5?*7+F`abJ$uu=z`JtuC0=h5>n$2DG@qf_hI~^})NLaG7B0wnn4mccjY~6n
z{Mu$tDCFN+t-GRlfEz<dB<@<eoaKA9O?NGGGOncp3gKHd{;6-ytJnKK@4SSs+2vSZ
zZ^oNIFo9W&Pz_JRA-N*BJYL)?0t2mE9P!G+qp}+%Rl%}8wpZ$ZZNde&bi%&>79=wO
zH*I(9a^z>F=xh7(St|S*gx9V3ufXlA$n|a|ctw}?R%YZ)Fh-+jTNwzhxr<}J7~2A^
zuXQI1ioRhBT8xfS+|7Y&8Mk4KrZ^zJ*}R*JLcdQZk{n62QT?;%*%vz)f@kvCY!=0F
z^d1-}ur{=*hqGZ!0v+?Z|K;$<Z<v9dJ6oa4+H4dgBi=fTvIxYJr`|KK<vsBHqHmAJ
z&sPeOFdC<I#}yVhDoC#HVM}&7v~51JiN|q;et@D|kc4gE_~*g`3)u0vx87SvXR%3E
zw)*g40kam__?rQ3PADfc9bUd9bi<G@6hw+Hrd=eM2fl|Ik^dl=&bQqBzS#Ad=z5Yh
z?D<smoHXs(5<UODh@19(>-&7E^Eln|J%QRT&s0RdQ9N9r&m5`abfv3GEZLOWLCQ}=
z#*Gx>UNHs{<XmX{BWTTk_oiWX8jsSB%}I?T1kE30f$hG}$<=YO)1`VYuPfU{ZBy`G
z;1x~xwExf5DcwR_SGe7CKy0@}09Zh$zajeYYBoIK`Z^6jMjT9oxil?kQ@2i0nF?Eo
zA+1FkCM_MeTBLE(xAa@#+YpAIu&>##h3`=aWM9*7`nRf$gSp1Go_?o1mT$ks^jdFQ
zl4-&Rz%W<8fsej>_IB1P^zY#S_g}nze)!KfyAn|k{&{e?`?L49WqN8GWh3$2wn}r^
zh83d~K@$qQ`uVqFAh@Pl-c#JSXVL)5JG^_kMxVE~Oy0%PTFNu27|atAw70XTyj4C4
z|KJ@KO=4fQjCjSyxQByyPt(P83R=dqR!<;V@e+_=@umP)ul00Ibd)OwJ&9_6U>W#U
z4=8%tt{hV7gRAWkNNegya(F^%_<z`P{kU?&m>gDV%iX8x6YFkz>hSvL`V2W;;h@pz
zJsH@-$<*dy&4>4%Vxwm!Up?N)wpBFa5l&_DfXh*JjV368{?WSNHQS0m-m7Syn#o11
zU>cl-{ArpPHb0dv<8(qb>$pi^2psApoWv*Sy#C+;3c)k$_s_g_`_Vp?O<f0T8ko*F
zo{YF3qU(rlYtMU^Y-g_1dAeo++Hf{c1uN5AS{?6m8zHw<7lG~=0!x{dfI__~sFKSH
zIh`_7nu!0#twaYC4Bs@%t}F;9zvJMCePkQQWSc<GU9nH-UL4{JJjo$Rm@X!nG*Lt#
z-gtS_kc9;_5=NQ{(pDN!0N&OK!XnZX<rZ$~{C~f^KHT+oUmflp?(H6Ud#}7V&!N{&
z*8@Fn_vasWU*Ko-k@v&P*U$g^;QoCzef|hVyloYn?~u$}9w?x#@(nF|h~$zwu8~;8
z{mRQve)daDjOsn*jq|&Ve*kxx_{u^D#<@9^1C+?>0e~&@+13640)4s6{M=!v9tgZ~
z84CUd03w<!0}CNpJxHi&84mgwpkQAw1H&xN!n7U?)U>u7QJO#-9>t1$<TW<*GVot;
z+gH6Mh}LyvE5i&ZWXT~M&=#*wiM-)F<+o=V{Sn4vM;q4-st^gZu62p(!_z$qzdB_k
zISWlg8AL#=#%@RW`#X@jVN~%E{0g76%ujuML$IBL3zcu(T$-o8f(04p`B*t~JZE{Q
zYE3N~i@C+$%TA73MxBYDQFCmKY%ZLaPuKYZtBtj0>0C$RQK++wWNvg9X}!V$+q9a*
zDZBAr^@PLnTr6i*UDPhjN^dc6=B=Ld5xU4VhVp>D9%ykDbTC9Ui-H(yp(1aKP@zHC
z4njVt6^f4zooJrKz-6naVeMSAxG=C9-`t4c#yx=TJQ^9VGz0eJtqEz)!b{Q~F><vY
z{yY^UNcM<*C4Y2n4M#NAf#}`bL0Kg=b=V?GbMU5e8exwx&-8K0b9A4GculUy1Vrod
zeDsXP<nsTuc}LVx2$OKQfLr7owE*d#V}!P*&x--A@<Ev2Ps9Vo$ARs{RDYN;2HM3F
z*KNUkZDc!qHublREkC*uL}7$7_W@!HjE%pVFT27?BOH2?lPbvh?0z9P%C^y=t`7S(
zg1}tsnrus9QI#%9I{ReJ`R=hl?E6;>fcYfIP~EN#g6P135PvQMhLE@s4!*6cL0bD{
z^Db9ARc-3#Cz=C9?3TUc+NMMIFxM1HtTxdednrV_McsX|No18Goh~9;$I$sv8Az75
z!Ud^?JD{0?269ZSPoA(FmH6Iy)r>k8ubfrLATVCfdP;7DXmTR%QA|9PG9x*T_{yTV
z`Fb?iAf<U|&1fI0kpx6F3zki7ps-_-D_iCX(;bWdwY~WP$4=cTS;#9_yG><ktg<UD
zA2k?_&_P6<r0a$6=M#M0rp%qfE1LU;^5T|VZE(l)w?t5~i5BPTG}>DGXNu>VskQz^
zEn_I(m<KCtOYonrbU@~ANBIs|0*#d19^&9IAB6sq-!pg{;H*qa0-kh~dzsTAkk@cN
zxhV^*5%U4%n5R2UJV;NYac0W4A;c^O1pb#&5K!-THdqVI%o#du=w}>4+jSGdH9{L>
z>eZ$EO>#`;xFIdm<VP!a+4oDd%q-KsUreye9*T$}EHCc9U!mWrTUZ)o!Sg<-jk=x>
z%bx|=5U^`FofjR;a>k<eVs<fH-!sZWO}ROYO2vZmPmm#=ZOIz;bLo4kISqOW^$&i3
zYq`-&50UxV2-v#$xUH^$s#6b&HE8<GdwPF$RW4_BwXvS3(Q?Jn@K#OFhIcb@|Fq5%
zAltVeWek9%wj8}{xboM(GL6JogK8TPs9`b4I`Z|HY169j<wF?sKIOEPcGWsxGd<5H
z>^Y|_it8V%fVS#%COuB+Xwv5@Cv)g;W}QvxY}Vb(uOjN4PF=0Oepcr+oVr<ACS6(w
zQ}ix%`U?HaCgB_PEQfBDb0hoYcD<^hF4a(fx(=P`<F#6EjXKcBIzABO_^_Dm(Le^5
zhhJuVjuTKUq)$NmyH2GmF6Efue^Xk|(?Dd~UhqNlY<*Yq)|KGnv<5$cB%H?Qp$7^X
z`5w>0i%B$7Qj-z1+b~IZl4pHf``@Ft$=lhxuhvAaM;v@h9d`_?z*Gf*nsanshBZ>^
z;qWAy;cKM`E}=3A9?n_xJQz&E8OuDG&SwNZh!)=4tfd7&3Q<s`U!!L0U3Cz(Jx^Vx
zN_Y7tAUrAgice8ML=cq~P;BQoo=oBkgkRq#NhLy;YXQ3PeIc^J=B5}20XKeM0vweV
zaebO7nO4)w7taRKM!@%wI`WeYWRmI548nvV3v2=3Mj__?3unV9Ob_E<H%qBDR-m&n
zl$A3Ho+##pGS22;y^Y-rF81&#zA@!(eQV<T=WO6S*LyMf5=%rQKG?*BEE*NRiYZu^
z5E*OxU|ec|azr%b>20uM7s)t4B=M%0GCLTZW14&E13eA{03EtgHeQyDJ|#E*>0**a
zbCiI1ZdNn<pb#ib;6hOiFd56FpGEi#!NLV_Z+aff55zO`oAZJi68Cr%ScXnpu&06a
ze^Onl!eEw1e8scLC9Cy;X;8B;nMSiHMgQVro*$rsQ3z~7<{>x3MC%-4R&S4{#4+<Y
zGL9bkerk1Y^ra{PWR~JK8DgkR?C2ZD;Jgh0as_koCgwUsPET-i2FHN=dFkOWhHxzn
ze|b&-b(d^*Zr{^U-S3veyy}NMn?t{fu`(svt&vqx;}%+TpX*B$z)&a1Lwb2o!~?Cl
zq66&jjE(PCIf&ODuAc?zS;e5#1bxnH4*5Qfv;i+JE_xRaDKpjP`uYZzojVwwhSOkG
z6y2yEIF0%#^?Av&2GI<yN|3oHc4fQX`*c*%R@qzDvd$^sxUSW8^zWF91WB~+To&zO
zNA!uDg%h^%Dn!cc>h(r9m2{4GglinIHtkYp%?;i$z>B<{Hi+Vz?dbh;-pXwCR)>*J
z^YphdJ#YTCd>Y1FyeMxr%EhaP*@hQpu248rb#mqmQ$`IRLtDztS@4Uo1BJ7cd$5m9
z9Rj#+&KXGlCCDh&SeN{;X@6MlAY84Z?ittd^G<lBpirB}Q;fTgL8R#QdfsKc@XluO
z#dp@(>TIdMnBgEZ-?fphM)~IXGZZC8`4)a3z7H@Pdv6#|{fcdz#r9n+Y!Ns1syl>o
z^+vhOo3<6&Ijp~{s9Jb+s@T4xiYlrwY+DTyQ7L2;o`;io9wvIkNclTEf+)=-mMEXu
zP^Ab7o+z1aViPQdZ|%@%4JAC<r*$DZ4JYP}$-l6}A=*d~#0R$7`NomEx$80`A-Q-J
zN{3x<TZ6@h`&^@PUi30IqzP5$(K3C@_kR`~N0TVKyjI8$GTNji;5PPDq2{p!6eC&-
zUQFm%ltqQ8CITJ0#%`YYdWr6nlli37?_{<h85ncCPQoz^5T;mr`7|@8x$uucax9Kf
zGtsMMI8bF_=4&2w_1XuWMp^CQpl#J~wax+>Sq~zZW9gyVAhG5s`y)U_R5r1@9IKC%
zx;8c<;mLbJRX14lnUEkNcpTSnSzYxP2~nq6&t4uz!;Xrg4o+qu$0+r$%CQH+=7^GN
zfzaR`$0v)_gSAy`R3#XWYlBDdI7UHZU8>s`F{O*i@F;Ig{&2Egv_%SkA+kf_FiV>)
zMRiV?!+Mm@g{%2%=4#GeSa|Cw-4!)2JDx7eqZf9X4CRf{C$=j7EaYR8fNU50S>z0^
z?vi8gJRDA>x@*#2gbTW?&#4FoOyZ<$Y(WYN@jMUQG#s_F0xYeh_BI+9mX~Su3qJl%
z^eT^TeW9zGgkr>5(XP4K%3n3a(MptWkH%<dNSDq~(2rcRn5Dnk8(FysRZg_q19fua
z(X)cm@(H?Lkx(nJz994F6^y-S<wXPPN@Kk?jF$x`p#P0VRH%}b&%(s(8%8}seYL>n
zTS}6R+9uhPM9E8(q2Y>V+vwA1_5xHZ!-)%PMI3M25s5OKu%}~ZJp05%j_UVz8NEV+
zG)unx4`o!ljW3sa>-Ornvw_NCs-k3zY`)Y3PY`tgt%jK4DD|DRYYkW1%K~tXcC=RC
zjx%(qG}fqkS5=MC(!Y6RqB^RU)Th=NxmIKk?XEACItH!q@CO+T_i2f7mkkGCGpa(n
zYSL>MB{8WbSl1M?3AT>=*`pvP+c(HMN@pqL)1+cuPOgoCR$gU`rnmE|T(|}~TV~l{
zpElrHii~cXV#_Q_sOeQ?A7KoKKkLW|%()OPqU?EB&sIT6yqFAU79a;qJ~8K?F?IlG
zPte#4azvC4Sk7>FQ<HZX0rrx<cXzf{kzIX;ekv^Im&IwKX@o`o^54w$$f6THSdrOo
zRwAIcWEM=U3D{5)!cc!H-s+-JQGMo(P+TJO0ad*@-oX59D7BH}29_}QCUNGa!B`Y<
zVVlPUFvKzuT5nVsB|7UOTn?iY<#ImMsiU@>1}SV->XOc^Z+_U#l|w;`Gbp4UU@;Q<
zha@A<V&B0x*diHOLhq)$Pt4^Sz@fUxJt=N_*UOi|wgkz*=spFz<`QJ{Z6`kj$L?~i
zAWlw#S@cKf(a6V_xjWP)MPrkH4l2Nv5w|$N5jzv?=)bGD>&xw33#%3GStmz?W$q)j
z^E<}@*ApuY6I2XY!=-c-SBqpcG1;^$wgBzd75iOKx7DFdI;Ld`$pDfVIq;j)Ig!3L
zoFjCwYO9TC$c6<4y;CP>l10{?g_pqIk0-%t2cQ<Q6DpAOM4c_>(a1YqoSa<Biig!<
znaVhMIar(vVZ2fZrg4*Dhf6!LRlS8cSe*?!1}1Yx+cA&h#G3}Qlq#KHEV&S8e5mo}
zIzsmLF5gjvyf$Hpip}i)-nt5%ot;$D+1W`QI^*pM=lC<X*&xNdqUb(#UN_a=$04gu
zv-wH>fA+rqyNw%Hbbt0=G4XREDV0ClZnt*g)J@VhXVWAncDs9TnyWLG#`e5O8r>Nw
zj@$VC?GFGyhUAbOjwCxy);afXEr|q45CA~{1QysUSxAZ1XZZyCm3)|flKo=i?#+!l
z!z#T@<e^M^mrg*noTSlululc$c1<B`YZe)Nahwe<SV-#`CN0OOZqU{VEi3G>QeHGR
z{ArvEGm7=mb}y;zWU))JH?N~4KgD8AOpWgb0qfMij0u>KygN9bDuv_3r2{nR>%x$7
zS^0+Yq1)f@X0Q@_-28EJKGH7P?y2k<@Dz!UQ20knE8QHewAX)7t~d;}yp<4Do#;^s
zQ<YyvyJ&aI0ZL(A6_~-%m9`qdQ1T(z^Q9sPxD~5TMOj+Y@kWvp3cfFN`HSl;z!u9`
z8Pm7f@>s^`t*d&Ibz8scjKE@<>N7-zFUp_QXMDcLB8oRuSP=H+u7xH`p|KZ#mQrZq
zMne&2){18$Qw}xe8I#Z?q<uqI>mu)4@7DIEVJv-}A5R~<J`>Cuwh{Hv%pTRFZ8mm;
z56nx&L15=jqt(=A`>~VG8``C}<r>u=YgVWY*=VvgDUxhVP?>1?Q_VD$!Mw4dJduXY
zM{HD4tY{3dSsibZF`^^pGh~HIoHipiXL<y%%NujMu5DtxMJF`3CBIqIjGfME_dH7M
zn-ko6+dN|><!``4g~TT}Sm>1p8$INIl@-%<t{6wfB<ZKT#3V0JSJLaIpovJymlBWV
ziz!Sy&GTPNr?r`Yo0XQ&&~@{H7v|tk9}8wgJ<sxY>nHfiZJNm{q&m!E*8uupk|+D(
z!#Zvm)}psfoJu`*1>BfbAWQoaI-1c=P<>9PwEFTTSr$Fu0D&SOZfxu`mpqnBW9bFx
z!8gXkE6>g0<NiD#<U9F06@Ui3(=l*M0HBRUdOBvXUgA;U4*?PLmKYxs_atclme}>6
zc5%!GA(m)OPSS_rW^nIN9riHDp*wI#o9vuG^m#1>$Q3Nk0rJ77!r|h}XH)i6mH-@I
zL`+E*FImNDSibe_@&fnhi;ZC%tRqln{TEQv@gM~_ricMz7jxVNK{uK3m*yfz%gaOl
z=o~&4XIL|hW&USZ7_4NZKq?n$g;n+{E&9|iE1<R31%`zVlrM|}DA-G4%N&$fu~b(H
zTD?3}ppUa@^8whqPzAKQWMh!VDZ!dtdz6SR)eq>n|7>nv!7-t03l?pR{9)$L{v;-1
zWQVOw{QivC&DBat+iJZC>B)wyd4@JO7d!wRegLb^ir_qf1$@nKJT;fyPn+yoUX$h3
zAI^4#*R#}W5qQ5+Prd%yx}*!=o!0eZYEk9k`Y?1S2t$m2mW8LwI_^`f6dLb|?_GX&
z6Hoe`)Xz3eHknn{=98(%Vq==vUvM)n!y=DuBG`I!&I-!>xCW=0JOdt<+Y#o<uif3O
z@Ob!76U-nY4%)0p3a76G0M+xpK{5#NjmYMb6<xT))_YyuBop9fvW*Cc<XeNkcII^3
zo6Ca#y^giuFkuS_5~ItwJz43Hh?$Cq6>7NQi`l3)R8ML9R!SGZ+#u!kCf>9%`rp!A
znH76YU@Gb2rEP|fqnd&}R%0e-91&1U)_Sf&`&p6}6pUxNYGx~{jT&fB*S2x06t!>p
zY@AX%hIfp)6)!HrI(6!s)kIw^B0CJyQ7OmMCtAR8;g^_m=~w}}7G)I6id%BMCD*3*
zuunv=pwq720g_!^2uzqJc1!x73+WrTnE8nQCJSjs^UEMsrigw1wECrx-HjEsr3GPO
ziM=Eh<Cb(6CEd%=JJ&q6u4UQ0u8cpM`RZJDoYKB@E0#YCvE0nNTDR?*SX8Wyw_<L&
zq;T1^9Gr~z3D(!W5=cg;g@fC>x+!y-SkjCIwD~QeioKrO|5Z1s<`SrXYpfb)Yagmv
zM)o14Jllj*R-9*@fQL`ZIL2tHykkrb3m>?e_evozwyFcVon!SP)xA^y5w~E8$3U5P
zog%Lhw^^BiM<9f<L=YW(F~`?+Y^BY|6!kHu{%qonvE?BxGFudU6OdGdQZd*MFaIU4
zJgJ=heId5G>XW)eM-9aUK(Geq`nkx78gWX_i5b~_0mN_^^W#M@V>nuBf~k2LC~rJ<
znbuCuEFfmub+iFPjI&6MVlKMT@odU6T9-#C{SxBocl#6H$HQ4tpBkn4u{U3~nw6!?
zHF>PjN>}C+f6XKCeRvC_C8xls-IgZN`j<_fcUh|61O`7E56SIiOUv{I<f*{7c-GwE
z)G$v(j*c_fVS6Yb2Jj~s-?<(o@00u@8z)p}3LxKcRpl_=P}#7>%zyTT2bGoFajXOZ
zsPPF(zKA`?l2zQiJGDQaBB(~LN~JVI{lbd#bSiQca4eexVTs77bvkWDyN(HnY<&!f
zOg^{gXr6rN4`+j<z6*O_ZktSEn@lC;iv;UUM;1hhjx#khX9z7`pOcpgmZNDk*c~UT
zhrWG}KV0v=50eEa<Aj|2@6yP7v5Aa5OI#d*<IJ<2m;-E>_IXlZs!`wtTYb+Z^JvU}
z!Z?l+E%8gWggI8v^42b=1VxU7M%4YyTX!N9`xA8_3+r25*nj_AXts{Iu-qGttV<zP
zF-+k^#A^>Pg`eIijg%-t_}pnU2$H;GkodzJrI9*F{Gk(8=UAClv>$D`DjdV_U0L?3
zhp+i!xEgf!YM{b2yins0^FW2UTGHrZI4wTNIZIE^kP5JP+-NphG51B*P@iN#g0cJv
z{5j#k>ykz=D29IH#DHh6m_HMz8h@}%wWM`X?!7WugkC#Yg5#Ym+kTr?CFL{x;qHyw
zZ0#+?HT+@ab1rok<Y|>%q#W<eUHgWEcvBt)5@^kC^L8COHnby#f0$F^i^sb%b+np(
zLR5i$kAcRh0d-k{Nbx)l<@MEGPVCus92qHSe~Z8)MkZFU(1O;S5sW=60*=R@$-9rH
zPC#l<okoor;#VCzGjajqOZ8@6YN|OR!Wg9X;PZP;FIVa`ba_K^yJ{NUqyk4R^(mGV
z!~B+R8>nX0%&JZ=3!9Ex6KJdr1P<ub3L0w$KAT3Mme5F3@Q>io7#e8}wQF$LI6^dt
zxwHtciPEl3)MBY-4Ia&6PVJ&*5jHKuz6hJPQKxaZAXPPwI_<-K;Mc#U4HC5B+DKE;
z8>X3fDaWOuglZ`k>|uhEYNkhTLXyjsNBe)f{pb0I<v!N8H@@H4+QdIMl}gf^Kco9K
zo@V*x`yD()=N)5vYwPcS|0enyY{_@Vf1_x7Yy0cJZ$<oXY8Y*Qy|evYbh|m%@bAGR
z*w_`)`0r~)x=-2Wqqa@S=)2Yu-c)g(`o8+*mCS}4eM2t_zvVyu&<92SG|Mkwi%}t4
zVfO)cNr+fQcls`#P0zBNNa5!^IgNfy;BJve5BkY)n4SK>^|*br?cp?;fYKKo_RmJ?
zU>dcvJUvY@6Z*e@ecn4v@-!Z%e*&O>Ho$ZZIHPQG0gcY4Ky2TC|K0k|*4FpY5gca+
z1h$|?yrKaP!K*_A7Oab2B<InOhfgA27mT0@l)=BpzaQ>KYtII|5o4@q=evJ=zx7>&
zvsmByW*vxsXM1;hYj^9L|BeQ;li8oq8lTbl9hY{ty3!n{n-ZZ#I_@W|J#usuzmL-)
zmU4;MFFdma)%)3sw^#6@#c2WkRGWj8GQy^l*^rS!p3UGC!3V_9lBXW*WeBQucu`D~
z5!JKXGk$_?*!*pp4*8E_2$ryk3fc2a8<^$ZQqVqPr3s>RJk2Pv2FzkIo8o~vil-Z#
z%noIaQSIjfy0K%I4&5#iMN~|4%tF$hQBs$~4M96C+IgL9x=}GiQW;)E{aG>1M)2jJ
zb4%D3!shg}8_|ifD9Ju1(g>khMno0Lkp~#i&<g1x!nAQe8YCz2Y&eZr+I<#+i~4NA
zu^P(~Z+4pmE<Db8mY=mA2gggRttdtdY-RplEe+F3(W)|SX^Il&xr|y}dknFlVM@e{
zvu6-utu$Q=(4UaWzomg){bRh^4T3sO&WDWS1xWO={gPr5MGYjW<Xsy`py&)3G401g
z;GuXhV08t~;5t%fdn@5XgC|LU*fKDI=_Kvo2l#-U*m?l{;@m(1NBvQJ`ho%x1ZH&}
z>cQ`bYOJ^s8(95-PvmjGiio~>4_#OWC1u(~g9n8<j2kUjc#=AiB?rf1Vh#nCF>E=?
zyX4|P;H;&PNl%D|e<l|t#UOS>>*)L}$&*Nm5P*bbML?kCB7u|GU2_B)fSjvc3;N{%
z#6q~U?Q9Gi4YvVFDq;gWCcgBMXdwE*9H}x8V|mPH!I2g;XaO`B=LhAuEYifiNvuOe
zkti?*;|@@U5Po-Kqr);{AD40i_pB)AS`IzQ$#klYOzU;>H}4=g5*KY_7smD)SpSk(
z2NHHAye?v{z&m{gTYwx3^P&_~n2L(^P*O7%8TJQehF^<moa2v7d?GFPv*B!{aNr1z
zr<O4hTzZjGvPP_^Yhw=Ocbpb}g%%i?32_Xd890^x#9hzhae*g3;wm;6NEa?ypJ+Ky
zc%gKO2CR=mz?c9T%<*hEbjVoHR8SI%t;L;H6UId;OUZ$y$=ZMYP$UT*_^3kd?qcN}
zHsF(TGVM-z4{qgIHZ5gPiEfdr+CC{lB=8eu!~_V4TpgxPW04~SO!~8FOt>Hz<&s;l
zpW{NSl&on4gXutM1?#TfyOizJ4}+S()z$&wLy=ahHJ^V?+7IYV+na!JP`i>*yiQSC
zpm|i_6zOh3O`d0c+J(Rgt<<*I_)rX10+18Z24N{v@AyP`;U<8x4b|yt38E4Kfp(%o
z`M_moI%eq<@!SzYb4qDybcv}RsjRe}M$7Do;5F~McF9TO(6DkOI?v%c14jjN9^E()
zM3-VSlX!qDr>r?7Kd1^DtiKD_AGmJd$s&NjI-u|WoiR@ov8#cbaskH)NYeD=LS*gM
zWOLaJQ}GO7Tt+{?9sRWa558l(7<j3+E=OI>9BOK2sHc_T`?H(`Fsev{WWtjLao|`O
z?KDAc7k++H{;KN1;ujcV%LI;V8Hz&`4!=ApghDImau82rbx1Bi*Lvmg`$RTT$JKww
zGJ7DM_bLG{*w}Ib)x3}lppuw<&k-k62S~azy%(1<(>^_ZsD#Z_^2Ed9v@XH*00kLV
z-O9YReu;Tg(yg=Xv}mzcAHB-Ww`@o4c!HykV=4cg9Wreb9~?@HE}*TNKqeLMxutZV
zFoL0fdt-X~Cmq!AS8O(Blm3V_6=4nMERXXGE^g2~0NRT%3#4QF+NRmj>7V6Z=iO)x
zJx)0?@<V?4Sz{_ZBi;%n=v1v*#M#c!2s>?cgjg9xfbTf7dGi&_CV(82dYVNL^%eek
zhrW;!3iS#e{@einRp!~g2|Ki-Z4vx^vfX&6bmQ1T-akv<C!0s?2set}-?6e)T08|1
zaKa^&i|}N-!m@np5sSOKd7Ku>(>%}ec1y+U2@^`YyR@|3Xtfn>RJ=9Euy13Et$=Z;
z28FUKSoX2nrL~GTOU&P!$Y~;m5xxS?QQ|@eUje=W;9DJcHF1vlhaC5|I3C$3Vn)l|
z-O)QF3Q?93>nL}uuB*Aw%7DYE58n^m{$u9zqzV2|&g)5<%V|wol1Z1h;eu8XujsrV
z4s2A=;^~-qX2F4D2Sm*V3G>Ob*H0fGy?p&&y~C%k4qhL?pE!~tIShiQDN>T;qRpTC
z-MbgvNsAtS;9o6e@v|{m6@e}b3}MoQSz*Tk!xybF+VGO0oo~r-gw?ufUcVnafA-|y
z=xOiO!Q+1({QT_2&&yeuFi@#Tc5GMjfg+=%{CX6%P>i;sUHl`?TWTSkcc<^Eo>L9u
zwmZ1P>x3#tOL=-L;0H-D6%An!Xw^R-5G*?liTP~MDm+A_0yc<A`)Mh-@5f_g6j5CQ
zP9&lht7O%e?2&7@RKZvwLeo4#c=x3&P)wKR!~HU&Suu^Q98(I62unOuLQ-A>#Isg(
zJ7Hb>G^c|CyG-KgSz9iovuDGNa#Hbjdn-y>_UNy_{)!%#Wk0l);O$J8Vw5k}78{<j
zyNgEyU*A6&!ksV~m(`k-_Wb5qcy{wKZ_>6G^A-@^w2o)v0URo2wKCXaTq^sXuJimi
z{n4Q|2{*VsXAG?D<EXHz4#10@if<|hpb?MA28VM`o+GX>897Gz!dUXTWlAS3WKuS=
zJpK?|#);4=drqohk`hDJ6U-HpBLi@`Lb<-LaN#O>Y^e+dX;KJqmyf*K2`g$pmFp>y
z+H_5&Dl#xs5y78qn2s%3F1jNb61sdg9S7EtP2Q}fUwy^ylJ;Z}3Z{nHX?v#|tsV^U
zekqyRj-Sg)=sJ6_n~y*kHDM5~KGNsM9j^2VC2O!^Qo^YB*8Q?=4IeUFdRSVb%gLSK
z<4fZ?T<s*uM~EDp3H{w(bJ6}XSd{0~!I71n=<NC4J7Z&UTF?~8l1Ub5S04F%Hm2wc
zVO*Z3qr}rgC34yyIM{^c){PLIhKY2Le$n7a86@I!Z<YdThqwJ6FNNlRpU#=jaSR{f
z+Fle)q1^?E2U=}Sz9=pqv2739(u90ve-V8!;Z;((aJ(M&Sgr4I4=vR6!9IP&^htW^
zpRK(oh*q?2czd$>9vuFYUtXTpEpmN79jExtK0fa<;n8ImbZ<>$rX*2!ax)%c878<m
zSSH>r3C?rY=!!865S-snRyHQ@0?x_v+SfZSQ@GQD$sC$Q-7L!3)?#m-VYTB7fzWF3
z+KbO6P7`+l`-P5wIs7@kKRLlDBi<ZN?(^eSPnVPPJcWxg^i($1*S<f@3TodVVOYRn
zGWDJ&3u7lpL9$G=e>Tbn5|`znvzU5i69)w=IxC&OZFUNQfEx|IEoLKFEBwJP)NBP^
z)Hl|n?M@R7jt-$(_04?XczLPb9Z8Gfe!>XtmC+q;2Sm$;YMv$whusP#rig~1ho$jc
zy<s!Os~b7YI9)aqGsi>;x9VVtL7%%vUPo>ZhQlD&4HSx<*?hwV-D#spqWluWB@Qsk
zj7(2ozkd0;_xkD4Z?9i;i0%LV?|(;6vT<vQ4#F{LIoPQ%5xb86_;s0=>r^hy%)$?-
z(C3l8WAYki!>;|mW`p$Pf-{DSfG!2TXdVZTh|J#ktg&`o4m;T%l`zQ<KQ;yEF^jZ2
zyBH{fWK3o+qQea<!?&DvVEYanV7S~_BK+0D5z1$1d3R3Ohski%OYZLqi&<$yZi)f>
zg8XQK=^SGe0Q0S9<KX4TeBrjRa}1)WywOqF-Tv(4<TM#G?<n_VJYfz^>27U%Bo>Un
z&7=xIX)F*lS<_`<X^y*$xq}tv+19yduA7d#2u=`{Yhu8<p|;n4HtVA%;v8;b#RXSI
zI(M=GIzU65;zxZGUc7w$>%sG`crdH)ge|L4jp?2Zv#_;TS%}?YU)8_aGS&Ze+Sl1+
z0cHP+^D#y&YNd>Bw98CG%#C!NX)|2D3k{S2#oq6Cq#4h(*T$%4|G*XP5)jCX^W#><
zFEE}g6%~d<&4Po~H4(X~Om5YhhePQ9<4L#F!TvoOO8!%x?{n3Etg8M(yp-eYSw+gd
zY4-b$D~!a#U#{qg*F2X24@A%Uvk@NG=#${}Y7-^G;3SLMfCV;8SwHvqg4z+XA7`Uc
zHU=dK8vm4Mqx-z3dC@TopX;GBY<v*}Wr<=ak?59{l|Zn7xFga)pP+~&IobNJ^$|&h
zz1mJk=}2_?WjEa|v`!0)<Vr>o!==*W2P|K+EBeVmNpF<or)3a>9vW3*ur_Oo3EU3Q
zE-7Fl9w*X)Ezun}P(x2O6=7w~+@feU^I)-T-y6oo)Sb3X1#L97f(KRbr}P8y1;|gV
zKNt<u=@bObaXNKQf|^=J2Wa%{3|M7U;6pJ2%mUnjdEj78l0gAin-4MyO~JN=izd52
z#;YKK5s)z^e2YH@A&Z$`;3~}XOWc9uZhB$)(XtRk3wxphmxBU!C>i%JqO<Ir#r9LE
zXIfBUM+|<Y*8~)9&ZLoqUe=x-p>5dd)iCEoxdyQ#C9t$RI+QG{p6*VQwx^Hk+|~EU
z-kuo+oLSpzR;T3f^j=(~>6!_NcgaQJUj-e8(9G^8LZg6pX4v)Zo-d6@-^~n*GetR5
zCu{UQj8T^s#8gz-sr5guYZedgC@F{evu(xCXN4L~kth8b2%+~0oQ=|F&+*PpkBD~7
z`)AOQMzDc>lwF!(Zdht-=OY(f`VX$81Q3|?Z6>nOHXV}nkz?9?p_iUB?oBl+{w<H2
zbe?jWM^fBp)hwJ^yssn|Hm(f)rrlAFW{18Yh{6aN_Xzc>q5(e|8LR9hhW}eptpLx3
zD^V@qJTm7huD%L=i|d2Y(C*LWwCiYV8XJ|@BGm!*tbybB>MBKZCakO*B_AfkYyisM
zrfMf=X7X+%jN#=lbvjh(E~J<p6sWP?%gvDz2Ya}cg~nbdw_tz2|8+U|zz+cyaxoZt
z1~136=;MRrCu&n^AZ;}8wf*`emU54;1^?5PnC4ar4UxiffxcBofV41!K?{qeob{`4
zhmk7~LkS+rW?1$`|Ejgos&WmkK}fVWWjGma#arQuES&tH<WVy^?==`lAt9nW34YHa
zt*qG&LDJA#^|VXym3gfaDTHV`OuX~XZ(YdITlqJ_M(!pAjbuzRXC&aDyppaN@mZ;e
zM?28(4teiez&JS%kjBcos%YaNl%rbt=ptVYu;Y*}A(tnz`q{c5z8cZD@p43NG^I^9
zY86uuT2o9<+#gL^&a_r49w@sN66wC;-nC{?v`R5aMntP&DQH8Gs;`eV@-6VvL7Y;g
z-elTbaA(*Ayq7B0#B$tnVs#&p<(cGh{yT!*M6l5N*ja8y%naMoWT0(OYBZglSwb@Q
zU0`N39e}&Aghg-|V{g4(9^IRyz(tCdXw(@!Xb2*Plxm1UJxciG0&r4_Jah06tk}h%
zVbr}J;RDnuy<ryixoKu5j#(*9vE|F#D4NWUhiPAYjW77=AHZW4y>_R|-t>><H6!O%
zXwza#v*32Xw!;n^W<R{FJh+{r!J2i}7V=-&44*Pk&IO8hVzy`8v<vuYkdZIrJZA5@
zOf02i;j#v~Il~8b&9J1bSm5cf4ohW^H5Q)2>*RRx#gp@L{+}gIG!^haaNmr}HO4>z
z<9>3pv8Gd3S0z6`5{uFtUPo{iYk20cf?rx5eADEVcilCsWv@Bm-zdfG9>mLdJE#94
zq;ilex^E<+=b{O04p|z|23pK$h%Tk>Vo@*=k58E8i32~<lz;<jjuP8N2D7c4$PK1U
z*~du&a3)DVJxP;6m(xlz5_t&Jz9QBmPu{25tQcOP@JYwyP*Otn0^Jz=hacm2rI^S}
z_kwX|NSjRt)Sst=gp-HJhV1?wWjIASxOKXPJt|I%z@mieemCGjss8p__h9fOIg~O1
zZSug6S>>9f=SDDptz<B0DdsMW=9J77kBzK1I)NbNTAW-gZxz7RG6cvCmPut`=O0Dx
zUoozZ25Q+&L8evhVfB}Ta-Ll|v95JYB_)m9eT0!jz63sstxy72@&vu5$Os!PJGZ7T
zTaSBDBA3wHPDuI3jY|JA-`m?p0E{&_>G*h-4hIp2{WQTOrgN**q!KSk>}lym<_IT2
zmdPh<1gWH^*flsaeCObUx@#>;CR9%C25phP1BzI31;kbL#<G*o#;w@t&C^_D1P48Y
z^y3p(f*LbTjdsB6u?$L9HQ0<5M^cbO4KZzNsXE7oJJ2Im%e$$OFfTH7R-|{x6qOs%
zZ$)D0tGm0U*3gMg;I=W{XmO?X>FZ|)&!7GGQxT^7;-&oV;ON=Q7ad=oYY$bp6)k+f
zQ<hZ}zaJ^eYX2<hzbg|Ak<{dS$x<p|rVmWzSTHy9WRhnS06$GQ1p6lIxrn$LCzUw0
z)?@iICj#YoG8!-+w_$}{aVC_hlo645`5i}Zvq^N-!_a2Ic7(*}r!2dDRM<`nDz6-Q
z#`u0O2p^BV!EQR>OSM-yVtu#@y|1dR{Mq{7ahbG>ij?pb`TE3qQbyGj?CU0yfr+8~
zRYT2lM#m2e%>&*%icj0d+pQ`GLf?9RQ*<%Q<;KbuC1J0X6fVBBU2<eU!7-A8DQ?u2
z+0Q;=N$P51I3W*A0P=n%hc3A`G9{(x1eczIelL&Pw4k6>s^ZhZMUouqV%Aa^Hm9_4
zSO^q;!EBqe<6@dlVP=CG&Sso-Z;dB^o{zQH#JfeQ=9fy52mxeEqgfNO=#Cc;ZHeu~
zbe$@bk!$a*^BC8|iQ<blwV+(ie%;p@2+J3@6E+#2g-}DS3%z_}jE0-l=K;oC)ZBt^
zz3&EUajb#z6w6VFC<v1M#h4ev##H8twAn1NejgW)*;^@7Fv||hlClEhcKL2_4plm7
z;b(DCWUy1y^nDVQ`IJ{2tWX}H^dDwrFcwMaWLe>*GDB?T;1da8&Cn9l{ldnvGDQiZ
zw%$x>KW7W)QC&Va1oy!9Qk(@wfH?`rI}h>CQZKaj4F)lWfIcs#X^LFv>sE;ckmF)o
zOY9KMTS#@706ItNO8?%`(;zZmbba+-t+`{dZr@RftoVJx0O%0+Ldq2b!hDfGRwU|u
zN*^4oV6#;R!M^fM&(ghiInORj@WJzHyesv);{dxsbHdxW9ho)QShzB@%4IgA8N0#I
z?CLKN*T7}UTwBqDJL~I_nh;DN6~0_w-*5Q|pNB+quBoMXen9H1?cvi9Laor4m`(GN
z-+?=8GZ*c-qIU<GwfaNdHuIVjrTU|s0i`wCQ6<kZb)I%3iKot?x)t~hp6ffFmgOwa
zn9U=koTd#ImdXHb!*9)jX7_q<^@a^3?(2y0w*3~wqQd1ATzjDFgBT9(z^EFiX0E<k
zoZ#&S!7^N<O;yQFMPny6=6WF@il@k9->Rv`6_&T_W}!xi`OFX&i-J(xYr47Z7d~r5
z(EA|CEnj_Q8nQ=|sDaR!i*oBF%#}zNTH6xEibeJ!fo78nv@X~)IsFrHLnzv_bw<?j
zl#e1myi%3|kc#eI5iz0?xg3N&{CyaCWPts7hmj(I;B=a((ni4=I^t{XiQ3$Wa3V_U
zgs?;(hd{48XF0fvM@%o@^LGB@!s~EyVX3Tk<US6x0p8dklyz>XMlPTXzx5-GW`j6E
z{t?9J-4E;VTE!q5oma8x2$*}Jn#$$M0?H%pZjItN-_<Pm0^riB8(qirtJo|Fy^M*A
z*esd<D%R{8HjiejU2|qhql?bvVtJQPHzLARbtCpCX-VwQzo5+!U$^r%>(TZlVh<nZ
zxGg9Q%2Lk~*J)*SB?Ray!8!~uQg=Q`76ql46O`5I5_K8@3zWbM%9D9`RqW;M&9&hP
ztMfp;I%=jjH5hMweXrJ#FW44NNtcqjzh#d?Tb_Dpv8%F6DU8AHaIKbe4i7B>Diy@|
zt~}w_oC@E<_?A|IHyQWqt2vY??d*?FRc{f#^Qcj(><0YiaPUmEg|At!x24tF=|Ao=
zlfC6l9qViNAM?9$Om&u6;&jcAtVI{c=W&V;A4CN?9!GqV4Tsq|uN*jvr@W^^LicUt
zV<DjXHnLF4zjcgeDvd?zGm>r@*-H42hk8e<s5y!Ii6l??O<>30a#q!CP5s8+u`{nr
z9`}URzdFH`rb^u{*;d3Fukj?bPsdYeh<Wt5H+z~z{3lA+l8E0~aWR(YEyrl_S~oj(
zm+pAe3vMCD%9I`|H8THNsh6~xfef!EjKEF1#R%?fDaw7T18$9%l*DbGTL1?h4TeQe
zl(%$x{9s!8sX#S&+d}UonexB<Y4le+9djb?faDT*{Y0C^A#=zNb+m^jzM&Nfrmad+
zMUkm#S;}15#&R30rtMPAqQ(%U`HTCi3EFn5`p2*0z%}m2k7x|RgE<I6p7>LoCadWO
zi?OIyJdZ&SlY7Q_(w>}6-i!Ju-Kh2L#ukO0wuaM|u3v|te>Oe&M~|kHR8~@}#8jn)
zFRZ^RTF9z(^z3=>>5HRhN6(%f_TZZkO{X-6F&PE|43l6TNQ$jWvaUk?UBMGwpDyYO
zsSD!^K2ujLpWeG0X@a9`(M{?C{N|j_OKbN9=94F^Qhe=<3Ss3khi);3ZdKFR&bjrz
zC_Mrz)U3<D-Tu@5p%r<ZlBaCqpPNcTKlnQbD%yO%jdkf37-M^D>+gU6Ci)xfz<0)f
z;omn~UvGcI{^Sj#?VWG8zKw1-=NkS!cm#X9LN|~5T2@y$iVD;($+F*dXW^xeuYP$Y
zzAd6}C_?;O{?iYAVBu3Nu^7=qyA`G=vqXpyD<nYQfl_t`IxqhFIZsZbACnl%dp+nU
zaF03tfmb))XE3wLMV_9XfdaYx{rBIk?`&;-A05G^=YW6|)M%LYlW{?V@G{Am7L&;?
zs`Jbn6r0DzV4Z(JQjcCF=h2UcPon4SJAx(_4gVhhez+U0Jsa#sj5VU2@BaSvKfaA{
z7VBF(>pR~>J74d9^Y`7Yum3w5%uZ&1Mr(XV<9A#**$OvvtZYh@zy|P}Peg@D<U50i
z{qmY8SKHqBW@9VfUcn21Wh>)jkhd|r63}*1L%j-Rh56aiKy~5(nJ^$nuA3IV#NFmd
z-i>}BS^4|Z*FP+}nU8T3f_9U(t6B?{Z3dP^{YxoH40udor@23eeaEVRsNb;a9+jHK
zKR%AmU<ACG#%MUOCm}s#26_t6#zYxWb|L_rXZgD_PrN|j&c+tEKSb;JL!Pv-woW7~
zticY>PS578oQ$@S-^-e|)(Xj#ZM7`0W8}v)GI4`uK|$Whxvc`N-fn&Wq|{4rlsBzx
zIFO2ynG>X-x^A!=?R#r|S3Xs?UzDW0Uws2Ac9{K6t9Z@7YP&~$PCE{x4qc-%njomd
znwrVn>>%@PlojS=O@MASPkU*>psKz6={4(2=Zt-O@8PfIV{4Hjh*d}sH(YCOmE;3V
zkFHh2EFL6-c8fw+gYz9f*6KKl15pY<b~Y*t?;=rSGdXa}p0(uz+Iyj4kHO<6nrh9)
z50mP9N!*~tr)sL*!XO#j=8H205|WpY4<a420z|X{`Gq-;duLdH0tk*8x8&FK1iH7~
zqsy%PHW?4-I}5!2S&YXPAPM*11Uq?miagir(~lMq9Kkeuo*4pr;`QR?D|}todwg*C
zwD;4?=T9g_zcAFA+@Z|B|IS(wQcuA9jL93GW^9sY@6!P{q>JYzmA?I1o)b3MSXJYV
z<{BELc@NVC#9H|z%QV#Fy`Gtu<u32lL8<h`xsb8d13w-2%4D;Zr3pYidtpu5U&D+e
zCdor(q=`}IAxQ+BY?&0P*2-Q(+X&}M3}&HJ5Itrv`Cyh4TI0qw(OB#pe%%|-M#qdo
zja~{pp5%!YuARFJs?l=NUL`XzezhCjrR*a#kGq3auLBpY#C)=BRl>uLtHb1i2nGJT
z6Cx8<{Hsw4=$r%{p_3EJ{>=|X{RFfpv(k>M>OOLS{Jb+-Tct7Yp(M6%8>dXin6Pr>
zS2@Mv=9!#`1C@I)unKK&HhxCtsdlGw&i*#$*4$GVU3<P7InH9*WYmZG=jj=cNBLH6
z#sMaS4SU9T`K{%xZq=tCr;fu~5}xGAD1*ZpbXj`74`hHeR;(B#IRRZp*63?({?D5~
z@;}CJzrqxlRNDlBYxylsU=`8%Svutop_sikKL-70Jf^hP?1dw}uqN(UG3?{LA(ejt
z$i-w#)9*&B(I3-Qt-7x;rPC9`oHyI*sz9`|)z)Mj90~LQo+=(tW^J6JvI27Km2Ns6
zO)^kZWCz6n7mgQ-+9b}kSfa(enHkiWI2xn*XR8Hwz;klwKr{%p9L}YEki6dBDRjI8
z51HGX7FVCgOXepvUcTcN9L^>ayrC#J*67L66TGu;?P|<eQBW*giQ<>5RrvP(I2J+8
zETuXJQEWt*0boEsS(IQ=YIeiU&%(0G)I|0?R*Wisvx|U87C#e@ef5bsDn`7|(t-I?
zkPxV%j2*FK_0dTscNELOGno}<ZJTaYEt}@lj?B6z#Uw)oq)7ivvJ)$Cj1=3cK*rQc
z3fMLSwEqx;k{?+Wz&F%{(%iJ16E$AbGHe8CHU-?EDLk7nVQ>oOpJV|~yS~UNRo!xh
z90k1=6mVrOdr=jUg#s!YO;I=egN$js<Be&oG&jx!u0P-T1O9z=2akn2oA6&yR`@S;
zRBZYRvYJD90&Rhha@g0l*@X>3ZZF{gHi1&5!<w*MW1&JoRtDShhvRvt&?M%SFS%yL
zTgzHjv&oq^i#JLh<iZ_>dg*<+EqY_NWqx;Zr`tDX!P{%IFyYKQpFDGB;5TN0Eww4I
zt|0?kxSh!o%9(k+!o)-XCt)W7CNX71bH#KkX+#aO@rGNL?_kVpEKh%18;VWy+F)sH
zF&uQWwYQu{o&xYEl7`|vSx{r++~a#iOYn9mOVVP~x7JhAcxrRV(@W`$7iHt&1rh;M
z{i%98mNunaixeft;08W7Fy>_u7xowq4zF++Y3y;)wJ#cKXH)w7mC>4rS_QAKvtcqX
zmbegOFNh2r;BO(%Hyl9qCE|DUKLB!yLC$3kNqDD$D6A}|${<v~hsGQ6$|`>PZ?KM0
zoQ|jP|8VoLti@{DQ@gzN=JIB}N8C(@q@(nev8RLN!#wk~Oqbr~jR0fmaXL(=7wjqN
zO2C^T_X6wA**S4z!B0@MeBGFDN}wToBdDx|;k4*FhuI6?y|N@#Agw7itU^|!P+Dm|
z_R*Q$++2-5t&s(+w${R0Q5_22l<N#7F0sL7RkeFfMzIj3?+HnxK^Kx+gJe=HPx$J%
z;M4BW7+yp-o3LGCu_}AXxR3FVK3bh~ZG&EFJ^?qh52?8EJhIWFsPZMVf=;txcAn(b
zE}dxCmuV;f&2P%-F70q*j)7U8@KDaHA{aSNFDsK-FNJE16<p&2mZxG!f2Mu%B5{LB
zgdaaf=1(;jzu-${2@y@@X+O0Ul=C7?uIcTYRS6Ae{&r7(q(T9!el)s~#zt#JyFpiC
zckxv3GCmXowI&{~Oj-px-!b4Fi&7)cYXPVf^lP?kTRlJz@Hwde(r_(YUS3)q2t1bI
z)_oA_J`e~iod?xoh|EULUsINL^G+k1ImwzT^U0o7Z-9#gb%x%pO-f)RRbKu`OX3|U
z{sQk#wHE`e4%0jnX>epvNYtRPNk1!=M0?NVoMRQU(J0O@LT@CZ`8-3xfzi)X*GVo2
zR}5Ra&Fw_&ou)d}JX4(&Rx0sO2Me~EYp?|144aL{y38{e8HpN=RhpF=4kb>IWnB!7
zdzErRyC>KDpbi1rfaXD_UmXJE9Rf#LDi(qvhogcOwYFXYF+z8mMXQ5kodrIu$`b3W
zggrj<#ZN^xO0sccgMsloR4WK8>#WOK+-RyzbBglZTkqI99>Gb;tm3@RI}4pJK*4ni
zsa!o?9iqygtz#M6UKS8v`o7nL4&V6mILCOS;_CT8j&vnB34-3><egrNY+%D&2}0^Y
zhhu|3Fu8hsh=HyIBO$;SHJY(%%_xWN-HVoN?NiNA^%`%JrCe(a4v(A4CRHEz-i`M4
zvsz=fp8X17=Z(wlA9qEV-8#%~9p=~WF!vfC)Px~TT#uo_Pz}MMh{0&|Rs)~x$nIvj
zHm70VKK|uWowNRDIbK_+^;FX1Z5v1DZU@BuiU8et<8zIOTenHK^17^nQCGfOqnbyb
z-lnV1XW6#gDyGWUR`wEUioEMPijgY2RXs0l=J?B%NBg(g9Iht+$Ig}J|A_v+v;8gm
ztIYrL&39Y3`9E%Y{*Rs8{2x0vHU9@HzUo_WZ{80$Qy8!Flpl4eL3SFY2HCky4e|+6
zgX~1yjmDbDE!HxI__KqUSw%kUbQXs0cKgcq_LXh)S-!IM0c6PutbH53o-O$V?o!kB
zNuCkO+O7{ek0>q7pTs3j{C6zMIai1u$9%<xl&N1tRE8~0t-KyS6ka(;niq$c%XDv5
zFvR*P4*QzyICcz>u}!VTs~ncr9v|sOu5}TqZ^%%m9=3gKgrwd@oW$b`N7^1bGzj7p
zEBe5dc|4`s-Kev%<-&!P)dQauRMp0kj48@;0pGAxBTaK%Ll=U<DV>6H{=heEDG!-`
zVnA-$=)@?PljI~IW3({r?p6owxRM27PitBXC3h5?otZ95B!w+abmAMc<x<mP2#EE0
zG2H2`B-7~S<~x>&hb7Yx$b|piCg;4F_y6}hoB8>IcmLY^|MquZ?`&@w_y6th;0|@W
zIoEyvw@6aw&A$sA91k|nb5OLz_y6J60LCmg#2WAq)f(^<ppq;C;psn(JN}n^dnfUC
z9T)e1_%816cY67`erY$<rN8_s8J~*GgQ{xn%)1Ck%#~V>rWS_hIDZu(;eyU2{<IqQ
z$1-s`DGR4k6*$5y;FXu@{NXylEb=~HNa3&Jbc}!fiEpUn_xuz7*6Dc5#(3U#lzAEL
z{zbS>!tb*@VHbN;w$V8@PKH$M1N31SBAQJ^c@;*t!>n&Fh-uFWDD&2#8a4ef!Rx1O
z+V)5M9APt{b@FU>DFB^7V!yB#RQTc@{teg?@#XB(EKl(-pkCpgw8Q0FARCFDP`)TP
zr23`W(hmQ4M#02g)hp>pR8W#wH?r)VGbdE-+a6{AaU<l%J^Mv*mU!-iil@|KpW;L>
zlhV4ZRAutQEhG7-hn(H@%RE^qd!r;jl{q8?h%zB%ebqJ@MvR?WJ6Mn+pcAMJV>V99
zCQb*_fe@+djX>@q$=3j;ChOacz<wxF4e0s#`NsLzbjZNbw2gN1!~R(^ir3lAxu1jq
zFVfwD`aS33B5>*}u7gNxweg`Ccv~ts4sC}p>(<ukbR&Nb#LHl^cDw}?m&8!gW_7Hv
z{*&OnZir;I=Z198Q^_XnvIi9uB$QInS?tiEx0{)SOVRQ>1F_TFZo9Hw&&$}`%V+HE
zTgJX}#@-HX7sS|~>^LIotrsi4Lh1JDMGqNlM-Yj6eE*iG?KM!HOwQ7ab5_zVfTE~9
ztzGDpN6oE@Qj3ZT4I8Vc%T`TGJ)U0eb<0P1UHy?<m&f5*3Qi7^_n;NRm4uYUY|MgN
zGx~Uz4EYcAdI$bHO)2}JlwB5pz{M<U42{ae*t^0%(3M3B`QI$f%rLRftxW0AvTCJV
z5f4|&tAnUYx<w(MTmP=A@^)oBLXyY1!}P+BL!wh89{9su^nh_kdyTV61IA)}uq37`
zxio;W=DqvfGS@A0S(uBH6aOBmFr3LG-6A3J4^C!#$_Ry<Y6itpFQ4*Zb_fRvOV$nH
zpj)>24B3X$P`At>5Y9GQ76Jaj$u@_KI@)WTOqR+vGRZ&)+wjIWg>7zm<#XW`PB@B&
z5Y8)F8Vvry$tzDvl4!3XeJqt(v{V-%45M_oDNJ+AB{!B!kXj5CAe>FAX;|P3mj&=(
zFhJ8EMguANIM=aG7$q|0!IXm;<}8aTD?||i31GFnWYCRfh4kUgCP)(s6b!W{2AIq+
zhkLSNHyOr*!LPDYdkuFEP{2~Vl*Jk-`3lD9Kqrc@YF%Imovo@`>EdIsG<pxBZ)a3h
zrC7N;&Pm-9n#kLxUP0FD&6cZ#xvPgXta_%>)I-JR0<az8#O_loP2IGO_C}QVhZ^xs
zcliG({SLKb#9(j62!yp`e^(pUo9R$$Q0SdsSYC<1T(ZzyRB$@x7vRUO2v4VDcRoL^
zLxAeEErX}$5CarkjkG|ooh?krEXBoHdV(y>h{lzIhE+y*=m!{_yx_9ABngcunD<V+
z1YJdPo-eilPe{Vwd_wHY6Jhl_t*IchvsyiNK?7Lm<Xt<-fETL|v=?SS8>h@q?l@99
zHgm2Tq?77YTLr!6oDCJ&b)48F1y}`MqL;TM4H&weFYN_d?TKRN6c=Uo5n3vuIVEZ<
zwKwMi)GT$)m$8<57NM5Ds#}JxdI|UsMYUb8i{8*ULrLEmGr&i`;~L$VAr*7BAj<7x
zuq$n@hc<O^-mtm64b1DPE0w+X@o<(D^XQfpIkosc1Pi<Y=nT5R;{^NVim@AdyD&2!
z*@n0&0;#zYRwoJ;<WJgDE!~t2{Z!{psGE#b>yp)2tziDNS@rX94cbu9dBYxSljMYH
zfTc3uRK8i0fLV71He<U<(jduiUiJ+^g%fjC0-k>v%UZ(aydkYTjGf1wwb%F!yEeUx
zBNeSBCs;@~ncdG~81@7aSo;Us{1p6B(9%(S>bPC;QM$Gpj}~Mn{E@e&+eW5a9igJR
zg3x%9qIGc&4F)LZ;MKEFPTaVFc?p~Ky(Q|;ny7ITOJp{pWi|4698Zd~Z2FND=#TMm
zau$C)PNwlk+?`?KeDA}B{Gr%GOv(^XlZJdyl0ZXFP&&>j=p7K2&J~0fJ5Q8TP`Kij
z5k7%*uRfD&$`5cR+z4K1d@fje-}1nJ&|#n@OJaD(95eI>3-ndeXkdZ{o?=p5tgW73
zH?hhj;UUo);x+FLiPX5IMMt2-mZHG9t+Pl<A3v%@RCxx%pJ2Eu=m{{^Yp*QgRgE)u
z_!k&$(`}rxSz(++LTPM<*}27}<eaxYe%X#qqx>9TkrgD*rXM|uY!6@f2f%udlOp?`
zcgBj0;_p3wkcyVG-`OQZcDz95Xs;2EEH%c9SK|ng7pz{&4UrbNLc)lqqTP{4dV^<_
zWjPl5)1|pl9xC`h%2_|dEXqI@JZt+phI@bpa)ODC;d3N16RBAZs54wtH)>LH*?;CE
z!LXQN-Ki)(6U`0^neYfZSd*2}55dn|ndreR@0i;h{|1##POBFe;xX#<%!YiAl2{A3
zb8VYqU{p@yCoO~2bXqi2zbi`&d8BCR<_c@z?-;{?@Fl2ECg*w4Xqj9Euq#t`xrMKj
zA`$vnG3AknBAbhla(14eG%|dPV&(u$ML=Q_ou8p^ghMh?(HYy^2kDYO=3}+jlu8XQ
zMN}Y!PG52C7~aIiUWf_#9{QYh2`9>bWO!MVG$CbZQn^2FjntlcCc5)bf)A1bB_%jx
zny3blYN4p4)hGj;TARA@LQYqq`cTJ@GPgH0hqnsr+bf<Z-#PWwU<st6Ml6(}b|A|f
zEBDrVVWi6!pplrOp{Q66PkYJX%RCCsaOWRcLnQ@^;}~vECv|bk3rnYk>@m2|t}EKE
z+%ttZRnZe9W>##mdCSX0bd_0%LNgHg2steEt5c<<gkDF0px)zbG(u`s6X+r4oJ5Vi
zj<Ql4;-Nd($7-t?CDXHP&`UnR*^cgZXa@@iTL1TG*qST;-VO2vinwLMe2<KQ0p0Tf
zB{1vz0!n*6C_y@cl)hA0?QLgHfdNRw4K7|3?G70&25Hep^_V0dB?BRPV%e-=dT?XH
znq3L#*GNGZN`w`P9!E%kd*XKeh+x@bnB*utR*60uXB(!nu1Y`q8IxLqFfXgoVSLy!
zeu;AQTEf1R`TO#dXf`121Qj`cxShvVRNRO=9r&wt!Sd!Is5fir+nOXa>bwQ;DI=z6
zqo!|bw-s$foL@L6w>xh;(W9D<pTjDmT~|3PT??R^lVWpR5qnp<cvyaA&CXSo0fL>T
zB?;%7e8c^4%=-<CQxf08G1PX<-&?A5A#VC4oD|*kIo=RH`HXqwn)zeV@XbacfKDZs
z?q<_W)(~~8!WK=Kwg;a=<#AM&F?DLcOz#D(E5!hySJC8J_wZ9*>(D-CRAS**useUi
zzpw7#wdBqw{8t(~T2!EAlf76@b0Z-egZK~|koQe|teQ61&}!8byADQ$ZXfEEZWR;|
zzP0+vR2Y}GV=2}(TLLEDTKD~2w@q%j_O~V3-md;)+{os(l*`iG*RCedEZk6haqCT&
z);LA6du?xx6o$lzdkY!u%pv>(1f2#?IEzfB3&HJDtF&zuGS`~B*C-vQquEI2PR&lD
zVv_XJle9Dn3ef?wg3~*Sjnf&xfwe<Bs?%jJTT`-pbe>92pE-&6!>6Bwtg8?{I@$~D
zu&amdW7$rcP`R~9W-wcW&A|VSKTv|E{%|%(>O3~~gR!7;Ikpfo-^*Z`4~>2o)6$#3
z6xq)>SL3Jn1OEvYuwr@h%SuYIbyW^jm@;OTq8~+ODf-ap&G6#UcgfUe?3L%2V(z^e
zex%CTWrw|BngR`|+i?4u%EuL?Zaff6-zS9w1XK#6I9!)Gx=(-O9oh}O(h|pwVmg&x
z4aKudgD)j@l;xO6)=@D`5zfr|I9@LsS0#u<i%2)aM|zq6h6zRm!$y`@e40RD#oLKf
zjf@1updy#3l|cnvs)@R3{5?x!cX~zl5lbCqP?~*&Pc8=}$tY4_jxeK;P@|j7)VSP6
zOpP7pVQRu_W2WZ4EKGgVxSH_7-86G^H7%F8n%q~nTs;q0OC*YCS6?tEQxut^z5*i`
z-hd*}vfU(sd#N(L^~?t;S=FPkU;_p|Wym7D3~!W;6W;{k0#vk{hS+P$ThrhqKedUQ
zexuAi+I$p3TvVyNYQ=IH)Z1y2FHqe!GX%cwS}iWUN;y4bhU`2U_%EpS9heDL-rmx&
z!eDCkK6h=fvk4G#ySxi3FG?1=69UQ%TZ~H(y6<@AsRGlhT1Jz}8@daUtcO3G5oM06
zpz@+$ws5}RFHs`?^t{b4=NEd>tWi#MGQ_8mRQhj#e`Aq9w?F}2?Y~>!pUjH0cCYu-
zZ!aDnJ$w10*8`3?k8`XC-s&nBOx%xpTU7mYEOtsh+%A!)gm58ZAR-n;(xtd!45`7X
z8J0MY{I8$V(jU;lkli3UzbaXKlP~ZV0+3sxpdh1Etnm<gpXS+YV(p0=sNxL{VG&|Z
z$%IrS%#M{$8fG)HnqVDchXP}D#D&UuE~Y6;Oa{Q`WnERDxSywQo`A$3;eG`6V<(1o
zP$+g#ylm-U+$V>Me&-pY&hLvoS(HWEp(qU)H06u`)bmQ?-kWrC858rKVaO`aB*$Iv
zac0c(_F(&b4>oNpRSYiYM5`WNzsC8yvYa6XWA?N0$uRBH8zS^9G4B&^P;aF2x8Qag
zdn36PZOBMakMa0O@BER@kBVDSY=yUv;RW<uuy_yYvYTd+5UeM8Hqu^Ec|39w!Q3SW
zhvvTk)3U6V;h?KZ^9n;LM=GE|{j}tZoNNPR0$7~&r*z_*E=6TB!n4S}TCtr<UCW9j
z49WnycPq(0Gf7r?Z*eQQno9(#T*-Nhs`<G&|Eg5yx|H5zUZ>x2g4Tyhv^HJ?w&hp9
zE6cO1(T)<}m9KAAp<4lBPlf?p_e3h`KjSPUqn)MWX)|t`pQ0?Z<b8I^=h(tI@*Mg&
z+s-XfHXuqybjnM>Zs3{I@bKW;qUxFDS`7-jDNni(JAJymKc<**_Vt}hSFRIlT~q^)
zmQBE8ewss{Udo-}ILn5FN6;-n!%T)l7G6-=%wQ(z={TeKWvobc63>RyNQf@=f=|?B
zi~l=6OJwQ`oT^7137XG1IgRmQDS}bPZ_5+5BcXDuCE>VPNqWCp&y^50UQpTg@`B+l
zNAA77j5C4jhqfDo2}-WrsRk`a(+Lf0Anhb1Qo)rai$Snw$1==<unP`TWy<v-_`}`%
z^D=a%g{V^|8{NAX-6Zp8NsA7ukc#kI^96?vN3wt&j{La}&Nb-LBFzy1syQ>c-1}JS
zaCUi4(lp>cw&0D;I1_`y!|VMn^(UP?KsYfCOvn5ecD!){p$RG4OHvsjI*VCc`*A{G
z(<vpH0tBg%^V+|^et>b`*);jiWfx=R;;5uH(v}7TAG|oK(7f};PUASNchidro@BHv
zet_B{?t>0Em0RcVrv<}qbR^r~>A|Y$&6;vcquLs^Vn}<hhY!a}2t_oSQLe`bZW4mH
z3frZALE~hI8e_9jD#E(rGZvE(<Wf?pq!BbHD3sE<aYED?Zh9-2<`Ya!B+75EpZTOo
zjX^M!_rDkh7i>*<;U8@OxnWFQ;n}DyagrzN<Tr)}ojN`Ye`^;Mav0P&Q2DV&nG}9j
zcq$e~J8U6;x1TGN@T04XN(mv<;A5x}6>4_T#SfT|rY@v!tRgM_NhaC*1&4@b;nqx0
zPcxg0PU3MhJ4OTkG<R34W$dy!n+5@rj+kpsv^IsHR{d75e0%8-w907n0=v^7D2JIv
zgR@@Q9$d^hq_+rY6F82fPvu@Ws3_(d#Ae!WmV3kj*ydge4Bsz@Bih*~B6hayI8u=W
z)wiq9PU1`WW2YrYViOl2Z&gI+wv~Ct=o@bWFluov)PyOSu8g7(_$Q~TMwC@cUG|hY
z&MJNuLc0uoY%4AuAH5Ef&(R|FMfpw|nb)eyrr(I;HQdalb>1|?&7E{CEbDB|7B9W@
z;&*sBRy9VKB!tqk`TI&u?XtuOxD>8(a`PxjH_C8y8=7)`Q2^SZ_9+6`nw>K0{mE<l
z!)Sq!cAvNKuan~xIH$|-C78?VCF*A?;;z<ob}QCy#o9oA(~Z73eY)PrdGqDxp`?Oq
zQ-znV4S&fZdT}lERy5yi(X9H_N*sMg@)%W5EE_e*&d0+n9(=yC&#6BCrz?QBQsh>O
z%q2zU@Kb+cm8~i!beFU)9(=DZZ90x$qgl)Yebc4PJdW>M5p#1yOo;{cRoC1?h4bvo
zNs`C(c(b@Drpd@AD0nCUsSxrVjJytleoS#%N|je(-g<fH<m#7&re)VYC<qAtu)f-=
zJRw*-T>O?PK8vS}nTECnSmXe@rqiT9#kvZkcnY6b>5gfVkC(+Nu`-C0X>caQHhl0U
za}I~fn1_G3<)8ml{vnQ0o@)m3&LJ;|{0{5UmDP~DQ4F8qtSML~Qju3*Nkb|itmB)2
zGA@<9xWrUH>&5h9SaGmG^Kr!RV|ID`oOdbpU}zQR7iM2TxU+AO&GLRiSM1o<z1$ur
z2yEh?L%H!`^QeQ!E4}K#`Wc8ECQM*sGT5b@f?au|fe{H@#wVUlKC%^lWOMvjPWNNE
z{Euu*Yp{1Qqwqm@HZ!Hn5Gg{9#F)>cj#=v@`<0xjS9@s%**X<YR9LVRT(DBl+hw1w
zIwx(wjypw{MBnf1F16F!Zg-pmmp2b*A!lr`L01zdZ>+FnJXncnU(MN&LfCVOzz)Tj
zO+jdfXAGz2Z{0ZZL{k!Wf+{a5BJOGmFUdknz7s%JAYyD~U9x+fX0F}P<cuos3tdPS
zS3&YJ5MohwUNiKyJ<lQ{N1Za;Q`TCtuOofSYt^eu7cDP?)h#w7{;Yv}&5F|f%+G94
zWpXSjq){#$7Wp8_Ww>}2rBj=YnGIBcMmxL^5DLZ(XYqTf^MZyrNNJC`QQG=^{^NKy
z9NJ0aUJthWF`KENku_A+`%_;3)=DvxhUCH^I^&}!B32wFHC2ye-zf6i8K@e=RB(OX
zFyFN}yab^#t2zRo1XH&^x#Zf!89#2kmN0wq*W>nIJD|L5n@_}D5y}36objjDng#Yf
zvFwE_eDwf$BW6|0c|petHz6w&XW48x(C>h-T?s06gY@Jip)PJ~?E~@PV_z1JbQg}K
z@Fh`O(mHhPw!8AYng<14H_xzKWTjT*8k#)si4CaorFnbA`iczC^OldaUt@Et+|9c|
z$$i-BS~2?>R~eYt2eCR#i>W)Q4K?G~RtIPPwqScibJ`;KgZW6vqPNq1fmsSY&$FM=
zsEk~`SV~zoaWG0~e$OVF7+3CqQp>`7B3YKo7W@X;&jwOCHLl(-vZ<oL3Q*!<BqayJ
z9}1K!BEeG3{K=JJd~uLY68e!AF%dQM_#aJ5)ZS5!Wqc>=Y34brYl*CeoS7-^Q`5A-
zUl_$6tGHJgK$3EB$}T3b&={DW!kvg2oJfNl&qXNVU)s|=(kx!mETqq20@OU2l1Wj-
z7SPt*7+Sk-Vk^gk{VJ`(A&K!AF1e7TzdMy$%N)yh9J9hfwYOhtz8%rqdwXrl957%Q
zV;FR-VnXMcZZrq4pusdA>&e^7OVTlHFnI~kA}U^oGud9%0zg^6G9N#Y%SVp`A9aLR
zzr6C5y5TD2W3jq+qZ+6;LxWJRMfsbSd8sYjwP3h4%HPT3;^!2n6;;s7um%=i{Y(;j
zc}mc$*KSWUkIeOm1?#&_UlFhBcB+OOLw0n{bJkN}%Oy+7uyVa3OIWy(`D)aDAHFX9
zT+<qF1FQl9tg7PqO2Vv~#a!Kxd*hXcS>4LJFnQN31nM&rbPFzSG3_!l!@wG=m@f}q
zp<@^wPQGRy6NbJYO+xXq0hPg=s^rVUDXQw@VLlr*GAo*Ek<_PNiM;X{xm$@ACednx
z)IKvI)_gsS$t^W(uDQ(8db<PqbODB)78hX{%2yR)P2&1K8#zW)&{&f3UiGr<nxYnO
zC0dw7^M(z6X40(LS{#z>Cy+`NFO7(g=*prJGn8o4EGi~RKRvmKl9Y=asZzm8rfEO=
z?e#OVq#NdQ%Dt?5ZOHkHL6^c&!}C)x>f0;{QNWk6f>WH25V0F}(fLXlg@!%>$s*>a
z&n#+JhK$M(Kbvqor2elAFVM^Uw>)he7wE~0Co2XtECe4Mn5BlqSs!$GLxjU);VizK
zz&9r<YP(u&b1j#CnJBWM1OvPS82#sDjF%{2y68R8B7++N;0O+8;Cksm6<PuxYvaSn
zS4+muC#QV4$27|G?DQ#)frSjFiBoG(W2|(M+2VGhN(I+C5i3wk=dV2ZcqnRH{_K>o
zlhoA}e{ys)zHWhRJWhw{^ujv*6852JXFB6s13;xQktgs~r5)%AAj-|A&)K(a3O_S?
z(1!5a7VXU=@yD(L0bTEf>HQCTpd$2K;T}Q>4C=E&erz~kMyt6nn@uOPDV`5Jhqi;X
zTzRx%u*ZUhI1%zG@fk6FmSRrq$<X{Vn(=0kl-4@Dk;KPp!tg2BLcHe5<Z2(u78U2r
zsOkVAc~M^i)pJqtY7b#;f)o#9HvrTL4A{E?bE}CPbnS?TfG#bh!(-!{Y&y%7isu$d
z3fai+y(6NOZ4`n*Kb{3;ASuT2v=1ZoM-zKbWiH(+p#kx2S;-BKGL$e6`Q+<yqb`8@
zF2dJuI1I=BglaBL_uZueyiP{hdlqsj0pi)80z^k4(mo88OF>(ScK1{#S4E>ZC@%kY
z`|p$dqxWgs8{cniZQ`Gs{POY>TroG_?`+cLB%WsZ1}MDqj<LP9_4mJj6a5W#`a9#l
zQMB{z*48)MjA(enX#4A(?eC)7&AEnu4<5nBu8=6WPmdLQ3I+7u?{rmNUutSQ8(ZjM
zjt86Pc{)u>r!E8Y%d0ZF<{P@pf6IURp%3cWX$E(SD8lmfD@><j_igxxGobI{+4Kx<
z=lJjEJUNYiOkw~TJ?JMxkQ_h2q&LRNbf3Y@CKq{ndNu{h`TqOw)_1nHzK@PTmK_j~
zf*NuC7XhA4r<2{y&1?c+(2ac~%TG6XgJScz7_9RTNcGW+<UIQE@JYmVWr8LU0skKV
zehB*Tv%zkpF-x@b-FN@^$F~tqW_|1H^_}lva=Sa<?|!}g-_c-pGW#=H;}ZkTmHp!r
zL&R+G6>f6mY)Z@&>A0V;_P9q;{60>HF&cB(FWitCZEt+Du@(Pg1tquGUseQxUGunY
zdKeenh;w{lBY<c<8e~+`1{y^JI1&2O;YBw}r-auc!`GU#e3BLPIEpMma8Ze{Py=j%
zMW_&VL{RuBen*y@Vnj)uzEB$Bd$Jpmq+N8|AJd-I?|ZfQ1&{*UaLY#bB>ArVRk^pl
zk8`a)C{qUT+couY-?MhK3}yp!;_3Y~&$ApZ!TooZo&|ny@0^aOmJSu8TUa-w+4*{c
zvImo&CiZ^pPV2^!Xko&Zx)|r@q<wE~aso<l!N($yzaKn*_T=E`Y463$*S{V-cNrol
zC*+qAyP*E0%$|V`O|&yPArrxY`4Y2g{8W30udD5~4bZxjzf^k>dGN)FkB(L}U81#u
znM8D(Y}=gpJ&q8%XNW)lYVyp{e_8LKTjov~^k`|()GJnJ9Z({fmCM=3kH!ruyfcN7
zgTm0V-0+$L*;c%=uG`l*(_fXh?Y=k`2ZavQvfi)FyhtGjhGmQ!;6G9Z4gIJ4<T4px
z_{-)dW=?6*6O_?xI87(Rq#GU2rp$M8p5^ZfI0wgxVG^8;Msa>&0v;qqKTo;iOaJLB
z5c~r+ARM_oQN=icBc0y>;Zm3M-xbD82XIRsVgOBL4cHB~U<PMF<+rnBXz4;$NVDlQ
zt)fossM8K=H(RdnKLTXK{}Q9qf!wm1E6ttaS75>pxv1iys{SCBM2w`eeBmFjZi14W
zr3uI~QH$jVmbC@9FNfXB*+slyaRKZ!-=^owBOstrA`SuDKcWDntrRGLYO!HX5=DUr
zFsFIkPtfai5fvD7=?90ap&T4ZK8@8>A@V7v`p{ZV5qjWq$+riqGZt;hWn;7`9XcQH
zi&QlR(U%^Wk6&q?6#7{DP(HSzjj9*rtBM2W<5v~;%SY*JX+S*Ex=~J8JNjV1)ziyV
zo=pEAG&d{uSZrmU)^EyOIt%oC(?a!BCSP4DC|-ly0+CCL9&u!zv|FS<w`@u1<{Y#e
zwH^c<D%hEyCr4TKJUd@tnR|`SYv4hi<rc13({(Mdh`B*d(quR&G~!_?7~drqJt_!U
zC@}+Fo^!;Nbc9wVTfcSIimMLMgPX;4lnqjt&>(Cay-Sn9{*U>BDPT0CPm|%YVc?3e
zVPmApLopa<rE2EX@k+&ZHc1DEpaP8I-^E3tRDbxG$OjxT`>nZ@%49T|Uf9(_Ru0W+
zFQ3Mzk1566kI7R4!aCUXHZDIs8Y~_bAWR-b^jEYi<0bY2=gYI~1W%W3+Md&A;MU&X
zNVlv_`g!$q*%2s$YdKa$-Loxr5Dm6T0I0-V)X+n@=*7kgr9YukHyKa#nP)szS8p<=
z+HbCLQ44Q0Aa<B%B&KXPVrlB(;SwjM(=~$l!$-`#RrrLc!#wjblrh(c!YK1ZY2Kb^
zJmor4KiXs2xII^ySFZ8eV*xzqmlrL2ZXNeF$c~-5q(0u5201+JPny@vLZ~;t&Wh<{
z=m{5_Cu#1Ui~9&{ntn)|C{81ArVMF(u4o-xe6rO*X+cB3!WcLX=omJuooFUwk}QUn
zwUam<ieRq28XZW<Vj5!MTEn)5{SNh}1ZKSJ<rE~&VuB&eYb>A}zj5V;l4EM!eRNQk
zon>7yOalLMW#&?+0oRDkNgC=_h{fU^8;SXs_<iykJ|Dqn4X+HKtCBC@tT`(5R%h-G
zPWAU=TAQy=-NJbZA_{=i@u+6X_0*lM$Ax{XtGbWAwDQ8?Tb^%eGNgEpRn@QPGB{z|
zWdJ90Yu0i&nSg!PoXl3R1Wx97WdQ&4IGN#5&2#-FaB`znEtiw^7eWZSdBPo3O<e3-
zYC2ZKCUzCN8mjgsLsx$>JJ@(zKD^<cmZJ>*=Y28+#qLEmJwRJ{GHBb4Z{EikmW(|@
z1Nw<;XFe^-@viNT;deZX3+{KUt_&H`ba>{;DGZ!nkjJttzNh(J#n++^b5)F@gLrp0
zWka*@O0POP8^0T8=i|EZg5zodNfYLrrLkEUy)>{3Ua_#m<|cVZ#1o<SB6LBf0`Erg
z@I1bt&=##e7%sVNzhQ$+8OG03Oosq}U6futrTl>$X<%IypN)N8FOUCk(w~~xldH8X
zmr;y_TX&dnnwrdtvv#ld({C>xA3b~dqSwQRD7e#}hjQ#pr`Kz3uXt4w{Nf=YgMZnh
zfOwR&J0bZrv=XCEjMPCAgye1Jfg)xRt={Dey1RLoe|L9PDS$D_(P28gkRcZXdP1Ac
zrjgCfRJuJ&uaRviw0GWJzss$<cUN7fK#06@p9LiWt?!q~*XcG{V%{>c+V8z$LB?nY
zOKUtzW;xUAl%BAmKk;8|99?QzqW>F4tObuTrw@x$J_qEXg~t`4LOphwqXqVj{tINW
z9^HjG7qDTr{kjZV;(45p)A6ZTB>%X;GC2fXDF3t3QhA@n7JKPU)_!7*{3*Y2AB}tu
z?HOpwpqzU$0?G`5dUf#lp9eobd+{?ix>F4+@;-n$aXgLoq^(x_$K!Z-@n`ZQwH5`)
zEyw*lK~M9k{J}d?D_xw!XsQm!z^k(f%AA0u&o!}-6)%R<K$TjbtwXsEUaA>+r;OGV
z)Ry)<Peu_2cnUv^u#|J2WmCs{IHAKs!>S&O0VtNb42mK0U2-9>=4e<b7$miZ1KkDi
zCspT$&(Mv(PObcWeulxuZPp4HR%QmpoCo5|UTIG?=gpvxlMhwU%G_sg>jB=z!a#_1
zk%^6euB>_ucCA8UYooNFN?ldcX?b{*k!yHj&?l?hf~ned`Iw$P0b<`^8-M;oGh8Ll
zFrxTSOo7kFa<$NcLHcJ|+E1L$fnkQx<1T(HS8f2K^|MbMk5xl#F>i{OZhU&=yTE&P
z-2As7aV;|RrF#JliLuh(O@~el<FSkXy<=ipxx<U^#U(w&PNXb_KWkHg*Vus6g*Wc)
z<02o%{1zww&Uy9}1;)J!D;_X<6S(aXe+wb)o&^$QI-Vub&Ys5t=Hroh_azKdm$gPp
z3oQ}PRlld;;rm|JlOo7N?e!>`i`p&&ZVpV1qB+*-OzD`E`J?#sB}Qeo)qUy`hx&=b
z?K*6z_DNyDq_$V+Rt^kxQz=8a@omVKRtQv?$X>1Sc2PXm<1&b*LS<06{JC5@#;Rmr
z+pnIzD|8TIalfWbTk%QMrdN^$j_QD8+F}I?&@h&y)PxLmxe}yNC={jW6Tw6>2Wihk
z*7aOy*^ioYokeH*Pjx%(T{=TU<uuFW>FR22RRRYY8o|i`gNautiQ)J{CY)9ZqS^_Y
z-RZDYl*yIa$gY?rK1-#i(*rb*5GWmfHen0P=bjJCG99C~?vFES&E8=ogXk>Dllv{7
z7}D5IWgDMQW*Gxtx(o0jc{=O`H5w?1hYwaufuX|57hl$>GxhyjeA@BcX_Z#~OD&hR
z@ZUXmm>IIYD~Ldo&T9tcT1K>8_KmwO?HJ}#VV;oq)DvHz;zNymfX_Z`R!6Pu08N2?
zs`L8uW`Av6k~a3J{%&hXI+*P*aq%KE2#8DAdhd~>F#lz%?yBPn188K_p9hzX@n}$}
z`dX613Aj>M_u*FnnT}7{PR!8k*K{w~;N6f-xm+-I!781s!mCp2wIaL}OBM?LO0wEy
zYE#0L6KRqree!iBA11?WkhEJLxu}JG*ss<hL6E8q%c0_xWW@(STB1MgK}{M^uC2IC
zb_~qk{McP1jSI(sWdhwA{uur%(DGMIV=TY8-?HOFx!GBuD!ODbJ1(Yqn;m7_b?O2V
zrM5Tg`vIH7v`nG06ldv)0A(PJH81)7A!CEuL{8c$IGeq>&R=&Ru1UtqV`t&GSJF;W
zzCy(a9V^rm@OsD+`y-zx;j<$CVc!_z-lBt)Z-!|Y`EkGEAdIbQ#UxKod!z=pTbuv$
z$Kb2>quoC?;J=;w@YkDo{m+B-|9<<`AA|dyM}PeB=cYAk!oPeqpId+qS4lqEZ2-SE
zeEwS2i?q~it=OX*2)F);z}WZLN}(7vYut)6x}_M$lj1DHSCcJzE>G+-oSem!d^(xZ
ze-SJ?fJ2r|i8N|A*gnyvE}szUS^83!>)GS#q-yRaPBExGTkuH0pxSwsv=8+CtVnWe
z#@|t#4sAcgFw6HQsE)<2$MMc{Ikc4Q3@nX-Ovn(mcn*dRDFu|0+J0?v7Qx0ob}p^6
zB$(D(7jW0jNxAU2y3(o;4fRnlb;kxmp%>oK216A5x3wP-z*3h9bgmPNEzglpxMq&Q
zT=42_LdBgh<vixLG>X@|sxnkH1U;_-K3zAHG++(CYWfpaD$kMp0GIdBGOb5|0Q1ZJ
z2a~hOek<CA-_$pE`wzq;d)~s9%%^U97<!0ztl`O2UxB^XUs!p7FV^`tTkGGy{mOT|
zddBq}qLOYNKvz<66*!Gjo3ehev7cn!)^Wqu9e+^PO>mm8Th@83vqROiE?1;hj<oj;
zdwF62qj*Srl}y`C*>B>@+`p)-h}Q}9P*(Sl1E77Z7MrUNzw*mPH5rGHkXI%KmCAWd
zMPwrh=8=r*dMj6=E0A)_mT93&<08*aayLN?E?ek@BZg$64>5DfNtL><9zp)mmVqc`
z1V6&`soWkgi*NBFCr9x9mIsSFf?)Xv4%7S<W&AYHW<u-4dR<Dw9k-8+Hpc#>(rl%a
z1G7_1&FNNm`DGX2N-8$_Q#rn)L2cqU<1qAJ#jbcYb4}K7`28dsCSGW{mRVJ4e5#F4
zjrrV(;i@p@RtAHyd4HVo2aH!lu1?Y8%-uy=J4!KZu}{_ur2{GSo9riFamM-dTpEqU
zsW6&&^jn?}?A|?_+Kc|Fs?JwUqvckAObE)U?TS!=8Nsnou%s^dDx9Ba>G-tWWToz1
zE8p(px&fWj3}Zp^>dzF()uU2jj@iOgd3%w%2cP9HXP%$O-J`m=8)s{|;!B1L1Iw_w
ze4e)n2S#qM5?{hq!m+uZ<Q{Q2JD%9D60TJKwKtH~gF*uJnue-6g*)*^36dQXuUOxw
zqN`1-z><Qh(y$w~T4Cp#M{}-DsF3N?sMFjtaqf{^q={?cZ)xC)X|&V;wb$v&bm+4#
zUDl_gI<@`UYOL3~0KX#cTA-64D_d$;k{?=qTau+T{n%djO+azWsFnlX4Oi>0$pN=)
z^-u(%;p{OAO=yE(sxoL_FEZJGhU#Zsza~s>mAV_K)LFMp%J?f#)m|1?5qe>(Ky%-A
z;4Tnpkrg$87TCa^cBPT1w<ao3&zFbJcb)c(lL{VapjsN~YpUSC(&^d3aQL!ln@7=t
zq;Qb;&#r<PCh>Hd<m0QRhZv?`LlLaWQetnMSbWAN_E<~|--y89Wu4!~_`5$jo7ihM
zS?kbbm5M_5aou(#H!8cZQhm#!uB&MU1~ZJ1mKn8_l|?OFOw^+J`$GrC^DLN>FII3Z
z1ybaNhDF1@x+hE6M|-n`U$~+L)lt;`&9ZF~0D3>cu7lpkIE+yqs;CQidHmO^q}jg+
z#3eBQ>SbFD*%jA7OCrWv=SJhPe1j}Y!0Bo2o3f!SlT%?h{us3K1Ko7i_wkrm-#<&o
z)7H{ius+#;)e*5Uqn4Ne1{I5E>{(DbEj-lRJX$~JHzgc9lM&g=Hbnc%L>x>R=x^gP
zS5)cov?;AM-ex}Umc_$W%U6vSQawBLpS5~V-J5|B$2sOb)9MiF&2!g~>l$#MO35xT
ztA@T(cG+L8e-A4TPgzx}rS5`$Cb$mJr7)`R*tH(PbAhi<e-wI1H$Slb1hv>fZa>uT
z1Rv^-E##wyW;m~d5|&@x$1A_(!<TuPj2W-Fjo=V0IUjBk+zSSA8Pu{?t?|*_5|Q;H
z(=l}oD_>c>MX=7ds*Aei<{xvX>uIVu;6Hb!9QRm``;Bqr2HtUQMf8ml(SbC6<urZS
z#9kY)n=QJt*t{(CLlH<60*pIV2?OU$Rw75^+s!`v6PASd<veO^jr!_VTb*eT_#%+B
znDe_P-EzGdN;<>o56e|fLp4hz%>nK15~co(9Vyp61E$q3cX-%5c55K_5Qqzj%`4Ds
z*+iR4L$%kf9{T0zp+v#UQby;1z}e<MMVbA=(S4m7G(QL;T+72%UpWsO1}btIy^X8;
ztxv4AIPJG;p-|I$%PNk#3p<tdNcXITMOh1Ll_m+AOJ(-io>5(xM$4o%%oVCc>hl+w
zQHw<*lp#E}3=3j#kK`_6ZOT=uPOegh3V((KbnjkNbx-mM%U1TF153<}!I}2B8;joN
z)qVs*%L!FOaGI`=hrRd~xa4R6i5hp@&YZD32IRd)8Oa(Ujm6G<5~MkUf94DTG9X_a
z(v--JTEtag)<w(cNU}uDSl~4CLRx^=MA0mt41%I*t|X#nsb?3fp~Ff7))XS4CaSxc
zl@Vk$dj{@$jz&$D7g?olkEgn}UdgaBR{eBrN2f8PgX!}mE~Yy{^D3#(KA!JL6l;Qw
z$M;D!M;V*ku|6p*e)%I68XHq#xH(hX$a0IK?xYB<rbM^t={U<1<=a6@x&K;~*R^YD
zAyQY{OH|+CWMk+CTDNL0*T&T_11w6;a_kn0uyRLO45ErbdyKiy48#qv!Z{xoR*MgV
z&KkAm2om?r0Jd6;{^&R^5<Vj=7HXRc7I_lwu?}mc7kn`qd|S*$EuV49Tg_DY+EeF!
zb2EZ5-zQOaauO*;0$JrdSzC}PZoqy~90A}c!%WZB`^j1_8&b(99M>L+qfM+nQ?Q_E
zu7Ars@R*_)2UB4LB|BFTg%f2k=;NNNF+*S3ntcvTb?#ViRRq^t?$$&O@Q1p@!3eq&
zE}BHlT$=N1<bB@h{;H|CqkO_P6qQ#>mPd5=U>^vY7`Bc{N^t7<beV9hkl#?NM6K!@
z|8EmCjg3d`&5xj2bUywMecJqgUKIoQwU;N8VcbvJtv~+2i`gcs2Tn{oSOc+2-l7;-
zGuqgQCNUQHiePz3f12eNSci23>wcAA)x~sUJz%o0x+YUkSZldfwA^E9=4<ZC-Kk_I
zRp<!I9pqTb+&p&Z=Rq&adu0JyN7`VcSfQ;zF*Q3;PBOEKFaM?5hXZqst@4|MFDf>3
zu66n-TpdaU+|?p5fZaI&sy_IqeOi3YZ|E-zxxBTi0+;@Cf^TE%ZKtk=ywTnpCuy`T
zF=r0i?A~I6_2H{R2DRu5x`m9h>9et<OBXDVGGdkig|C{{rK#LU-P5pgY|uhQ8f+f-
zeBd6XGjClT+uY{eo@TJ>s@YtwEMX8zeZIZtM8l#-Tip>?nO9u64!8vmI#3Ev5@^*=
ziqLC39tZWL<zK#Ig?mfL>0gzTwDsX)k~a^LlDug}NQx2Xl92-FjTVt?lAo)DWE~I2
zgC&Z{%fPBhhO!oN$K&=*VLPe44~k{NMdxsOF(i}6i)?zpD*4zXr@LI)<%*wO{2CeF
zOkvI-m#|&!-Av=6Mv9pRs4Rd({G)aG%XgtQXh6M$yU4@)48+k1i?m>z+eQlpSZN|9
zdH-$Jf3sC{BG6SXEutbDB|sB!^B<<~l4x~fbCC5n&(GkF@jl5nrXQxOO{71&`ndVB
zdQA!A{cAr~eK*Ht-yp9MpO?#`aWrey(D)tGaQHeKCe1+wSTScsQUpL@cWY?pjEpM*
zg@+6gz~Go6F+7)N^l?d1Lku)ZIQ%O(W(XULO+dW3_9rlsWNlPnskGJ+pf}>kEja{X
zMXPu5KX+H7cs$^yN0@kMKm?gs1>n`Y{4anu&7$KZf-M}h_L_z~F(fpPcUl8}k4J@4
z_6Ctf2aJl>W`Qp<icW#UrnYxAK}6TE3dIHl0{9fp<osfNzY#!~WFdV%C>W2jL#Fo_
z!G|zl^FSlEQ0cK!f<P2Jlz~;vLz(E&Watitv6?gx!mQW#C$j=hN4Vn`Q?9(Cz@^|z
zwDvQ<Htutmm^5H2m&-3QUOnO*r$W$Oksp6ux71p&Cbr{bbcqO0jb2MiQS{4H1+Lw%
zLf%IAYe@iAra0iP$qm$P&^)jH8Zxul*t%%@#CRn%b{(Zs+B^@!ET`f;7>>$fn-88p
zdvb8}wD;uYzg|3ldGO@fi=SaZs70N@p*4+*cSTJ#Nz%3`dKelLTLKl$YU7Bpkm2KD
zTv&|JM*yfz;A+Lb;d|#JD}EmOCRh=m)}<oAz%54+V4x9C@56KwDni%?fziYALp}72
zx62BkggTHSLXG?PXxIvre<ikoMc;SzV*pc1q*%xm=`%nY>9IU8>EM&PQp#3rIweGy
zc7>L!GD;_U6n=hc{AZ+gTe@%!Io$&kW?X-(q1IXhENl<wQk>^ip2JSlMU-emk!F}+
z)qg>%G||Gmnlp*K)w}qgMKtH-Y0pd2pso5RAyLu07*d<-T#IVbb7|ApxS}O!)mN@r
zUypX(RKpI}vV$~jJW>=*dmdT|*2=@Cez|}uA@hi{$Pn$k)XvDg>wObh<F%<+(Y-17
zsD)ztc6ctrrsQ<EFFGf?!#QYD9+yGrgidt#00TMCTv+7VGN*zNL#sDbeG@E1qu!4v
z0?9P@16#~I9y|sPwF~&mXFC;18`Iojkkx+)dJQVBk+w)J<};|4B{2Vaihe2~s4@h`
zzU>w}dOSRjFA7vYqH)Ij5is598S@TNR1jVg<00U4Z~>Z1GLBA$n5%A_4E(ZeoSe%@
z-Mt#ETHdq?A+>KO71$2M?k%Rq8v`hJ`o_b}nG(#HK%>YC!~9={R|6zHs=6x&T3&|4
z*DTXr+mrv=M#Yn}iMyt@NS}wqq%>?4avhTMTt#2sp6y&_@|(YsZmY=q`l|tdTeotr
z&lM|<97@n(GZl@Tw@h_k_I#;p1t4EYdq_l`yryz^&d@?-=H?W_Jk$~ZT|1Lur)gne
zUqPb#X7WvU!6YGSZH0YU>PURVT5iOCh$>)a2tY0Q&tyE{c>n;`N&3OXXCkX8YlYGe
zxCSV39>!B)`gamXR2uJj^@&ATT-{i_OoTFdtta<NnSEY{cbLIz7+>4A+U%cR=JyJK
zdM7}gAZR8G>J-Khp|FTxXeJz3Yi6;X<q1o}B%ZhcxsN8(_5DZw5@HO-aXOCki;&EN
z9&u!dB+`gfk>RSsZrZGp;hUB|p?Vcsr?zT;)g@qS5MuGPcGO6!I_};a?l_IysskeF
z!FQpa5fO!kT^i(N>ak(D`H8*d;~#9#`4)9UHj5cGP9i*iV7j;GPxJFfD;c-a{CcUK
zUm>f36Y14FCsLj7M3(!zvy2mz&lDQpo||9lxp@UA*}}QxoG*XXJ1%c@d%wN<`>oiI
zu)D3HWZYg*6&_-kY<4-VU7{I$Fmxmlu`Gtc^Wn@>j)L^EDo}^#aP@&$$bO~hMp4Py
zdO6n$%S~`EjQPWH>asNjkT$dv8W5a?2ZAhwoA>XtAMQuwVTb=aOY#IA-(-nov8hsO
zMboo9o1LCTli}<Xa4Gu!K;F8D>AL*OO_vFhLfa^iz%WAc<1`)jlvsu?3zT{$^3C?J
z|L*Q-G9^aBPet1ZVB#9i5u6q6PRCX61k>2^94kjz_B=apuf1m<T{Rw6PiL?9({C>x
zA3b~dqStfyIJt3$17%KKF@jNPK@D%%_%IrlaSXWni1&)_@;~n429bk0f|F&E<im?@
zbe_P7NhR<>j2~@pe7~{Pa$!S;0iC|YJO}Ny?A<gzMF(u$pU&bT5_XnNmx~%U2E&XP
zuf@h=Uy89?IJR($!z>K+J!6xP00K+X07Mks#g=!wAkRSdMGx*WSa<h<oF_?tnhc_B
zj5#2p)w^u$yQ^;Om`+HR!E0`0$Os64!lM=tp0TV4ckx@8F%SnFv5X~Q-oSaF7DT7R
z>^L4qW#)n|tY~;4ey$LLYNgzKpk3PFGuj{Z@4DoA!n_9i6k9_H7xrlkC!!3G<V`@6
zP~FOW5p{S{5K0(eyU&rpkB}NXxZaX2iVAb>FNcHm0te!|gT{den{1<WbZkV?Z*V)W
zESBO&S>6i#-&GR%4_EPjS2y>a3j~Jw6?83-_Xp%~n_>P1_!0#Me9@%>MN=TCCG38D
z$~Pat>$8u=*j!xD$SpoH`%X;5=!v2N2q!*8x*12j703eq*WFceu8!d#6l1`T@^6o<
z0GPkT#fyyLr4U%T4s<kKxVgf@fr`3Q<JlPNqs7BRk?DCZLjTZD$b{-7_LL99evZy#
zM&PH(ILTua=*JgPnL?5skU$Svjv7p!jKo(g(@!^IHy0V8Ubjj;FrPg%>qb^prtz-o
z3#E_}`63e<W6S`3rXh`|C<c}&T9bZVSaUKUBLaXda8AG;Kq}>nzSX<%H|H6SF8y6o
zH!9Au*>HdXmHgbLUy8dSXfL1qF|=PPzUNprr=;Tqv|>sig^xy8k@9$~Dtz8p4Oyx2
z#2UqEan;lna}^9m@-AJReQ+Oq2(l0qrp<koiP$=uuUn=ETK>*T#<6YelV$It&@g1_
zbL@gREK?3FQT|JiRegx0J1mANI%4jm%5}@|X{ItT#lWHll?kmjSNG8dz(SAmf}Zk5
zpjM4QOR7Z%IxjdX0O6km6KGG?vA`E?Ut<Lo;fuznA+-5FCQnC`DSIrk+%w;^-Hdjl
z1V@hA?1#<$j&rt_T1L?ty`5gN%HFk9*QFn6Fyq(PA_cXq$#D@$9e?#Mc44dvr_Fm<
zEwCw^>9c$oy?kBWJMLmpl$<Up@`S5wdgeq<wRX{Gf*GRr`A`!?DQfzAHcwI5<64me
zomr6<`i6~fbfB36V(3S}%nc!^FBE}SL3cdbUUDMux;UP+rxpULvHIV5?nyCUxDm0x
zJU60o#&u|szIo|ae$`C)fPdI0(-*(a34@<RFI|Dex7;eQ<FN%=5-%@%5ihdnfu0bV
zEdlRz%wUHnwPJ{obqP*jEv%<7n7XOQnXh@-%Q=`vXk-Gk%1JSHfYX>S6BiU4Gj~p$
z)BDT(H*|q7=iKohEgVHr`3%k>7Gq%R6bUL8e9^5JePa-P=@6~U$inbfH(HKjM8E_S
z6I`#Zbfj8+V2hXqE26Fuvy9N+clYb=EP}m-6lZUhmo2{Of$@xg!-g<c#OD!_W4vMs
zW$BG2@3-#~jJut>)zK^Unza?!MtRK#pO0B;h2vxzQ$@hx<c$6pB<~aLy^da(DW0S)
zO9pHNPpJi4#W<c6XW6vn%Ku(W^J#`=&Rjl1$HxkJzY2FghlR_ZWAj>z2AFU`M$KDN
zV!wV|?h~!H8>LhHDwZ2I$%^So`T?DM7p3>-_2ca>_Bc+5=@cJ+0J`nfT$WFNrZo{-
zaq9uwFq1wH<utt%TCPUYXje*5ZZE3n5d^E=fK+|jt|U4usiT1VK6iUl86AUg`shO-
zi`vn_;Xiv%U%!6&y7%j|!^3AUe(oI{9ld_`W3*fKW~V?BW-f1Tx`Sc1-;%%*&tTac
zO>>kbNjHBLP4Ax{u=mfJK&#rUndOR%{mh(W1h5?EN&IfFe#I|dvb7%8FLqh$vRbJZ
zU&+5-zmz+Ni8y|HI_Lfoy%yz{UpoR3TIaFSYG;{SZ{6=RZq7K*Gaw0;0Auy;Ioj=_
zmi={nOUG=N`%00dq_dPQ7gXT+(EjWNB|WLfHNY!`m|Z@vXzN7Q5mxKtq#vW#kJifO
zP`B2(1TL*sd*AH3{AlvaCb{OZC;8FnxCrU_7AA2~Fuj&gsd^H*#n`Pym4z@LJ3`&A
zL+L$~vruogs_Khp6#0NF5qxkbsT@dTZLL5|L1Lj6jc{-QsAvWtrjS<TlVRGQ-Z+f(
z`NWFND?&wG5ahzB5ZW0RF$`+Oy2^h5p&_q!b%a5S*Mccfk}8k1x)BezP`^SWQY8w5
z(8b39ZRyo7uOg+6sRMKVxb;tmH&W;vSi_K}bUaA=m>=u>ECp3eTP(_G-fK`pGOk$E
zPfjoe9H!~X1?v0REbn6`n}IY2lw`vfOiw_NV@B}>=NQ0T8Na*l<sMhG|MeiDKDx-D
z3NLDyD^6W{-Lkc(1E2SjVJYtA!jDgq2|p^3?zugH-W**=@D;ny?dl?)<{n26aOz}M
z;q*^-q<DNG?zfcE0Mwv-L=~9aY|W1vXn!+St4yeJxXFbYi{!y%yj&m2yUMA_f8?Z*
z_63Xr)zMfvlAWjm{BX0J@I#Ub@mi6?&E=&-vWIlqWhXw_Hzq|g8)WOEWex{H{+=6m
z(Y#nejD}=y<Xue}yk%Q{ZC30;cQ}(+7il{v$2e`KV03ZNSJs@4sTY3);aqRcL&4=Q
zSbY#_TQ5$!y3FZWOvbIsGGmI_O40Z%%wE|EqZOtgZI-%Ht>K)<pZ<g{g!YmyOAVug
zRR7E%OPHOD9twEO<CQ`Z%QBExf_>^k35+|Oayjm@n;y5_X&#yyl}x;Pd6B(}r)P)B
zboqqI<eez!$GELP-vsOk97hx}&qz@$0;~G9Q79KO@{NLZI&S;8NQRDAU}QEtgmh;O
zd$h2e%`@WsqM$esl%aY`ag95<8;8zjatuD;Qkcg#*J@Zc6qH)#4PX6y%fnbnVTCyr
z<-3;~$Q#uMxm!Y+gf)GToTQ{^pzLK|s>v(;yeTXU{{qT57!F?+?JHPdRarnuQw9&x
z47lPr97Zn>J#JkQHkeE(K7qv!UWau=yfaZuBNQ3Ijyqu`@!U;VrLm(7{^xx%#JI;R
zd>im99}XyCvQ7i?#~gHI<69y9dBD?gf0(gr=E#~qwM8y$J!Y<Uu|`1aRUgMMQQ1OU
zb@@;OFCeIO@@F9^Ax_joyXMtTweHbXui>$Bi9oly>jet!WB797aXh^EGpP%P(8`pg
z1)bcEy4Xemq)R&tTWmSGXN6`v4{+nv@=580#Us4a6eflq_jpF7hY?Sq?*?CjSOevC
zlwp0^adOU_9gpc7rO7Zu4}@jL@WW}6ccMp}F78==1>%7}07<)+7j%4d(MB1Q`%(hx
zjLN2|^5(iMQ@-aaw2sZI59Ku<4r^lolR#|0#rNbL;^dx0nyP<UGNLO$%J<1MR$Uc!
zWC~dvP1)s*=*hF!Pahw>eEna&!>6wfULU}pm}wxS*1CSpXaaT5o#>RY8enCs+Q?o+
z;nHxosmbcaHUVJ>v9sNcRu4!BpsH|eMEr;;uA1qBaesDqQK~&fDfSBpp&?paXy2Gq
z@AcE8-(J5ki`TLo`nc8W`zLueIv8KD{cV7-sw-75obcl1>t7F^+h?3j^a)#P=dzY*
zK@Hsr^lMSO1*j!d>{jq;hB~Y|GLy?p(6)5VNb4*G&XgGWH<$}Xo3uNwlH&@SIx~!D
ztVEmy=aer?Q3#14j5n=OQWQKb&HUv?Lh9^Yt~k@NxK6-VXA`8uD?Iudo=$oy4a;45
z??2%%ySI$fjBO#cSJHv7qfIYi?b?LO6AqcgcmIJU!E)_p=*O!zhdo<j8rIHTS10_4
z<vuoB4PeV5dJ<PgI*F+kPwcG3!>Z5lHnw!T^But_HYQo@{B=c#EbH*44V0NH5FNZe
znDZ4TNFnwHv%_ixm8+QR1kw+8TJNg$Bq{Q~&Q4q^9+DI4aW+U6!YGAy@-duwrcBc8
zjglPAN8<akD$emN9S*oJyEtI07SQKP0cC`2qVa%~lyOzQ2&<MVi6-MAG%Tk1Fd4&q
z$5x(_%R|0;mt4?I59^28Gw2Z8<Iite$%n}>?Wa?bGtt_MGPi6-#k+JurW5p^jnRL2
zmh|5hB1yQM1c<Ku0wlH-26HsAFdpiqSg)-`XhWC*pIgU$z9@^<#X^7a3fRXwN-bxp
zX~6RsqsaQBNn1RWnT+XwhRZ29R)2Lrk8?DwITA2A&Fp3%ZRPEaR<vX?cGUMkn+v<x
z?+U}7jK)E&l5r{QADPaC%E|3fvXYIxDuBKfLQQh+25biWpV)`i?rw|G=<Oz5(I&Zd
zT;tf<bL4bl=K%{GQDY1;CLvDK_sN)|Y)VeQZ{&31Nu8pf6yGKGHG0YB#~GYy@i;m^
zOUTcFnWXqEWT`sg3yp+gC4unejSyM(JW`g!io47BL?1F$%&OW8C_))ooo4TnaSud&
z502N>&is!Bf(&~^DzB6j6uXf&fp(`{C)xRFnkovFP3+PZU}zAt6JqrT=}09yTVEff
z1-{8xr%}>BlVIglM;mz;u)fGq@5#%@y~i(q{q^aKqgDl7tex4c8y$(iJ3(VSdvWyi
z^-l+npZZ298+D`g?Lff4zIy%?=W*zTT(<Iq<`h>U8bQ^fj->*?R$7AHSWYI;{D+fl
zf@%e$=+%7Hm#@FJ`uqu*^8wn#G|VV7B;6e8udlhE?W+cb;Sl9OpGR*>YArHMKZc=-
zeXK`Lr1>u<k_$3g7iZad1jHNBdrF|~Y!q=5fuflqnc}2=(Ah%Hw`099P0l7gVkZox
z_GnltGuv+$flA=g&L!X36n65Mr_W=`vBJ)rtPcogf|lZH#_tgMETp~Y`U>Q=@ZnLB
z9uF^g$SKP;M@Ww3Xc5}<B6)uKj<3!8s+NqmPP%EqT{e0U6(E_ilQ!S}4u1R9SLXiw
zz_K4w8_WR{PvN@yP|(bqwe+nmA*)QkP0g&E{yxrogBhwWtW99~qzS;Ca`Da0E7Tp6
z(?*t>I&zpCW;ANE1$Z#V&pmE($=>x4Z`$n?OQgZz%(18catzw{J76ByZ;AC6P{pUf
zOM|R$)CF4W&vF<FWCSl5YyFY3Go1i%Z*MvB`nIKs6etc5@&LC&86+@7o($MXcEd;6
zNY1yWofxyG*$DKVY+!GMPI&L6sDXbViVJqYPe&7$m&E?_7}SM{qv!a4XW29nT9fum
zxt+#ubF#2*mo6FC%9ah;-N~n{hp#K!Mi{_S4eN5HdUxe0bEbG@1LC{Z)fOxMEWSAE
zJ$><{_si4QPeDJL<6`71Oy%Cmd2U_Cy5-YIF5_(GDVW(&?_a+>J9>Kf3e+;o`!4?k
z2tsSGwd*WUQIe$3MNub9YTH|7i~oY^c>h)|Yt^zWj<Um}gV#rbD0b`i)}Cv=ZhTO{
ze|!D>zj`lUJ$>Pv$di}PpC7!YHoW<duVEt(9UWSKwRW}B<g2gt<n~58E=*iHHduwU
zzV5D4Vn0nDYW;)A!*-VW8_!7?+N@0?n`7eFOxN{W`bH3fR5`*(;ccZKY<xh!Huh7L
z9~>=Yo*knfjuy~QxobMvvpg#QKYL%_6~~S2oxk}MZ7z00G7JoUOTczQY@GP4gMGl+
z?7i5R)66u`*TeK|cMmp6cs~21D!r>EwYq1pceCc+jbTPANu`ohDpmc;zCigZe7Spg
z=-%M$!hH*73@vR=F``A9lJtaLgKpRY;<1MC7+f?iaTFM<bCXqmL$XKG2md0;%9OtO
zFNb#F?J|z&?ecPSDr5R|`s$Zo2#>U|XF}GSl*sv&`_k`TzD(-)Y&m!S{k`9u-|hY5
z4N+PSo!?7qiDPjnmlvu&>~z~^;G{fwvHz2M`LO7LV}yV$(p3l>IKJdCOhi%v^9U1)
zG%pqYlBWWTpc3kzd!8D6b~4U}&=$ESUM5vae<epa;Ep3S%1Mb&BtdDhW3j<NRjKU5
zUx3K}Azo{y;w}=B%BsuW(bhx~HDs94Skh{n5w-Rx@Gn_~_vzg|N+(0I$_abv6Bxri
z@EJ#RLkU`DO9&<q@U|J+)bGblIl4l&E9;g;hq3J$M$8{*L&rglIAA}Q;~0S(EgekM
zIGV6M%CBm;zj17gs9MPl<}p8FTPc9Ju3PJXs@mqMY?>qx&qyb^<H<s78K6)`f(EIo
zCZA@Y(yXG7ReaudyyAfI4p{DrNBThC`A6<-mmPfGMwv}!K`ruKu`yq{)>@+mXSp{l
z>m;_fvAfIuHCr=vnZrJM*DPep;A?_0-$(?Rxkn=?wHQ%{t~bzi7$NmV#Xs((Qo3)5
zfouN4W>O3ib)s>47nW);Jwisk^BO-KqjXr#Tk4&E-#vJ-`{T>K?Hg=Ec`$XV+RpF!
z#xO0?v*QbRfLo1k{qM%xugU+Fw_<KT^>SP@{x^uG-WER5#T!4MmHBP?&Fb63Z`L-T
zRY?<Yj+*b9x}BQ)gwaod!qK38M%U}^Gx95$bHenOwwsf9xK#|<(Rwt1Otw_S6;mj=
zy1PozJI&|1x|^zZd#(D*1%8nic>4w;6jeip2JhTvQuW@-)C72uK<if(x7d4yM$>xp
zb*-^$n`Z&zj^zfpOnqL^<#$;=kn3ekHJcVRKXp}-DyvaXe&MRhln0|8`_xrQ9Ogzf
z@wrh^oe``;_s3Codb%od5tggk%t7u)x^o(<csZM#r$ttQ$0%)|X|ZN8p-|IO@^4vi
z&E<IZBY5pbNwmzJP?uTG9&{PN$2L0Sn6!u2s{3}W^`q#`Ir=Y<vxfVgflqM72$Gxk
zID0SL&|uHoHayuhsrnjsEqd|#<?1QApThWJ6XJxqrm9YXF|WW`ip2W;zW8fRZ`yE<
zqdgW5*er_?xN0dNI8kzv&ngKDq&nFprOGzsg@tDk6~DgO3AV;A^K4{(l?>5WgjuWf
zZ#QZHD{hbM?(sA=JyO{mgg-S6D679><Mz&e9!DqS0H-b)tXoI1vWI9{;lbl4k~Ph!
z76@i>xdTPpx{CrhhD%Bf4&tI?<`%^g%v*1E)RR0~rov0hEIZQ>D?B@bn)YXQmpAv4
z)m>lEiXJcd{FrPmwwCq8hUpxF;F7Xs#qao;<Z$6Ky9z$_xWC1=USl19I{~McZ(`Y5
zpiV4~oqcW&LXzSRB~Xq2ZXK|G8D`gcTHbO6<}xHMj-vjuBb0-Z`eXANoy3o0?(!`>
zzG;D;5ZXWgv}+}8#Ing(Az<Deliet$!VO-NRQ~DOoYEkUcqR{mu4An?&J)fN|4yH!
z#cu>WCIiC&c%wWN;Le>$iv*D0`=bF?*e!&bHi&vMfDl=3zK)i+<=F!oJp27^qh~!S
zJSD}JKf%@(EHibDSM31TrmnyG^7B{zfy?DOreofKUpEx&gN@5Ue|kQhzm37>=7R_K
zqOXWRJv9D}qQSkp4<Bq&Ib;Q+!Qk%ZR`g|ZKEcnU@5vM|;dSZj8v4cY<)EiU;mQ2n
zn@bU`^7Cs640#Xz>+iF#egOE~Ge~I|MUdcpiQYcww#e)n_*pU|r*?r7@KceVML(v=
zCBT9W)A2Yz`+;<@KS`@6lx9A?DzdZlib%<K-#uL4+T8pOuVuSPq{KqwY?w|;Y~;ME
zrrR4E5X(Rn?|xpKZLk96#z{F^XMcdKNBilA=*Pon(M$RnQsaXrKTrRDxE-y$7;Q&%
zZA4oSAKd-+ZUntp-`rZ?x)*KT-M;(X_T7j76OCr4v)`i?)}zULw%M{C0Z005Xd8?x
z8-gWe27wLugP?xNWs;2{ekP*d95A59LH}NVGZ`$w)rd{v^PJhAqH_i|f#0&EMaMZ*
zk8!P|&FT<La?lZSf#4+Y3mTq9j#+THN8r#Bu>B#SA3x(Jc?41+V1ltB9=$?^Y4_>h
zc7NJ?{^I4HNZN4xk6&KGlNLFl?yk8S9TL5z;wWO!2uqh+r2H;Q7*d8b_;h#w&G9e0
zf7>J99USf*kY?}Mn+2N%IurxySDAbi?Lt40r9lnSX6PTJvHPCJKAfi*>RK>l4%8L`
zxwyak3j`cJu#-p1iLQk(@DH>}hBU&=jJ&0XO#>nQFJ~7Q2}bzR2^$3t=J3~Fe%U?v
zZ_>)Q_Eun8C~-htMF3Ag4Z9%vE&N5cq=<-m5bu8Z_2ruvFJJ8MDXo4NFgBtX4T}uZ
zLQ??nl-%vBzyUtnJA8WZ;x(ANNppkEfcE$<*1D~iFP`r0AHtLk22JfG(Id9MJrTS6
zWOi{vmKqb6c5VNC@8FP)acjP|nen`hpel{u^(+gHa*J7llvFjLvifHC4Knv$n>IQO
zM>KT*<_7bOHSyqv$HLor=xK+@Ja38!UP^HR@!ceJOMLZa4<aQ8-}+m*NHPSiBr?~!
zjbC<O?7t!ZBccW^edpbNWkWo35T40to3?)5-GBBHc(=8A<82+hqAd+tw$$R-!gkn+
zvbEK+os@huZqv{n`R_|;>F$m3j!U@4z<b{26wFQm$OVeD{Ja;P%&HFDeYW?S^Y(sd
z7g#F@zOXude@0aP^Jy<it6_gFyxBMZ{TiEn(6U*w;^|w%>bUAfka~iA(Yp16J)Gr-
zt=S%*Ln18R361USNDA+SJbt#mZNmkkz3`V}-jP;Ys~G-w9b1K|Z`mT7?z@{Eo6J#<
zO2+J$maV@+MQRrYeRt4e&WS?&{!CkDaA7sNrs~Ws`^DDY-K|z!;aLhEFQ4Z5vYIOw
zdPhE!;!3W^SxH@MS*4I3{<{CS{a3&3Ll2*l<76MD<!*zD^mv(cZW+5!%i^o(r2UW%
z$i;E|;-~#r2Yb(;1HMfXMDp=6*@$Ql6qfO;Obfk~&5YW%e|MxnpEIHwQ1R@r6F+^m
z|D21%gHO@e>w{Onyv9qle;1^P^Amx50@1CtZ76Sd_Q6N&=)3!Ex7Oh($b+>NwL$N$
zCs4=|IMvjLY<h`=rWHhivdyT;kqw`ML1D9FAByxcO~$2sVo#}K1JD5z3w?gqZt?V)
zA&^g0?#cP^{KY?@pWe-K63vV(;}A>0QMuY|G;)`@x8+yGF*AZx!cEa=Ar7F9-@6+i
ze2NtW=OY;o^J0Xyrd;51s!j}TR|0gzySJUEg2OCD1Y`=pM;Kg&)O<(&pFKwfnYk#-
z|Bi>^J^%JbMtwh0AYs|B$bItNy=Ya0l0epwNnAxA^5T6EBQV^A^x#3zOu!tob`>)-
zC}DcKl8~11S8@e>{_59#*yHc{_rXWxOi_;+Jn~3`%l&>Ix~7J)U}g?lAYE=?17QHW
zi$Wj14KdH*pjjdX81!WQ#o?><Z@<0&-TD9|1){Uku)S#?j@ZLjAP#szz4zT`Rf!2R
zq*i=?GssrS+8U<`ocovQIG?6PsOf8O7pDIHpi%m8FFhgZ)P&^-TkbEnUFht5zYlvH
zYfPO{!q#M3&c?93|Dq2f>>Xk|!Y9OepE}T^E$FR-`mR{stCs#S{r~I^Wn>gdK?%rb
z5Pucwd<NB4s3Y@E9psKF=wyoXlmAPHRgaoG0XB`2RB$cnan23^;3uh@end+*YyqT+
z$tWp=qF>f~e!v<F?>FzBrRx*cWvUm6-6)9wWtlqG(67+bJ}p&D=Iw1jNhZodb~Z`K
zF{X2w(hct<#b>T}5uK~${Y-IG)S5#ViSX7KIY2P4H)*76f@Q6>MKPUPH})K%*cuv(
z`qkO*par0xHic5<N$bY>Fd1(!Y*WdTx%-zC!}ILY(Lbb^O<K&P24!rLdzO+z?SkyJ
zr9@~vm)Z!b2p<x#HfL2v$ox*miTUf8e@y|OYSLi1lD;_A2u6Y;5pKem8FKD2OT-)B
z!QSDUUX(%ZpYfQs#nypAdEGD)@K3o`r+=y?4Ahv(5Gq?RbOI6O<5U4)sm&5~@CDMO
z<vNRV;pVDre`31=a5k3S)wMZN`V8W7pW$#)Dp)Y0n=@&MQ0m(~cP%@&Kk1N`phI?w
zAJZBo4X#~}JSo!(EB`|A{@$d7nS|5A&-P6Jes#@4s)o;PV*9hCI6q=?LVyZlc-!Ux
z>tPr*N@YV9@@5hxV$+{yXNYN!`AZyprr!diS;6|y#pxysp(ipwh*sB}oj6GUIZHv=
z$2?iJ$==wA$V?2=^L#u4ZO`h;53UVma!Iq8qKxtmnGWWMX@%cI*q1P0;ps(p6gnd#
zt4!M^mJHz~A;!VeM=agz>I$Ro;;M4I9L2}bA66m8=t=g6D|mrB%F~|xiSuml-<hL-
zHa~d7x7^)BSMH*KsylAPV2`wtQHT++_0wMD;ZpfJFDo|9hxlq=b|3^N&q4@+@Ssvd
z79q<`VVM^86?m^=awEDY^N%UOHC4n!1_M2ng=@O%s139?6xsJAMX+9?NP*6chigr>
zvuAZ+Qoy<mdjeP8987pEk9L8T%v25+Sh68%&v}vu4a}AoQq&hH#7TcIf8AEATBJ|Q
zy=k9k>*~SmC2EL<(%tO_iPy4`+1re%gO-E9t{k?DfQ3VLa>|m1DN4s9Yb1?=XG#l!
zbf%c2M1G*j;w|^CLu<Tiohi+;8!?hjNqm+SRgprP2cmR4M(ErmN3^mhaf`jUEnw(+
zDXi`h_Ee94w1@&9SIcc*jtF)iG<>xky6<QZwYr@O@Y3TP*=!OpDmz_F1V*FArnZ<d
zq4B9&w+T*KZy0lUWO$#nD|Igfy{6?VTXxPkOZn^GITY)QdkcYl!R^mAQt?f8k#?)O
zM`NMdimC{qY9)c9Rx1g#Xkw~$!BD}foC=dK^pK~7UbUu<n{NZelR(*CtS5!7gKow-
z3GF8rO~P9TEO(!MZG}Ljglr`QmPC^6gy6T`gZ&r#Kf#?ohgT7LRnAJX360_6ewEK6
zctMLG*$n;#FI%JBcdIx^K8TdnJTqg+T|x{7w;TFLlj60g7VOty|8nnmA?bD(ne!S_
z%I>zh-?^`LtvNOvlYRRa>8RM|+*AA;oo64J5g+x2S<zc)Gc#JvuIq4j1i`478BlTE
zTZd;OOgse^g8VcZ%^-tS0<NTB222Yu7^fpN%5ze)DQw3I6|ldfrC>TMrn%FCm5fG`
ze<ImDbsOyQoINY(uoxsd8efjg&_5RTN6FKWKHgM4H$65=KfzyX$%NKA$|U7g=V8+q
z{+b5Wq;2c6R*&gb@&L~(s%<9KCc84+wy`G|a+}fcYw@`are68_hzkHB_OO20Be5B)
zSF(D@vIU*{+L1hz(Yf`QU(SuTLieB}O2~vv3gD6>0`{2bQM0rR-~Oyut@hJxu82_z
zy17b(O-i8be-W5}Wr0yP2pw{$rAhM;0w>xYu`Cqg7^5y)9<oN=&Pou`O=;g(kW$b=
zX0#15g}*u*S#S$obkk>Z%+IL%^o-`49qcvW<F#YkNN{a57t@$aNLRiwFO!a}6SX^Y
zk9WU414Y~O^YD<yOSa`93$tv=J5j4M&v<uN7^xt(iDq%3(m&={sxk_*wUJX+ZEL?&
zYj$6+O4nC_WDxtbwo&592i^I%50Q0U*DQwRbzHHmZfEY%j;|n@R?C$&46MUn=aIc>
zXVwAyUDsm*t9HFBAAs>(_d%H!Sx(cTj?nKJ?$P-qE$ug5v_x2k?$PFqVcS_snty#h
zC8ULwg{a%4rqd2@o2TaU4!hvGQcL6<cw)1maRMQBzfQ;20^IC_g}A-QJ!INR95%aR
zXrm|p712?T$<;lN+w%i_o12FF-ku85Og!9)BYXg~6#vV}nF+NK3KSiVAw3!YfUMIR
zFer?v$-;KsRw9t9bEbsz&5h30B4juHSl!%Y+Qhs4toyC$=zA{A>GFP^73r`VUpWoz
zaie`5cdivgA8n;2Bj=ffly(sza%<feeU1Xw?U4xol8%7pe1HwwSm{~CJo~A`)yf(C
z)5Qhtsc;TiU74PCp>Q}mVPkl8N@%#Aji&2Q)UtH^Yt2O6Bt5;N2V(hZBHly*Hjuuh
z+KzY)#h4YNIL7MxYTE}qhTF}s#^u8q6|2_ofzq6W6v1Ldez6*fa5u#b<Q*LbIS$%@
z@%d1mkv8r;M6@3x0;%|pKR|i1N!Q_>ue(}ap7PkrSGXCq*4{*H<}uyP+NyAt`rQ;@
zveh(>rFq-24X4H4W2^2wJdN&(^K)8|{iK3K0O@Hm8&^)puUxpxn5P&fup&fQLTdco
z)Gau5rzvs;?^ald@ALSFbD7R5CZQEOI0;#(P~|4~ye&40lSjJ`7X*0XXQ+~`-}qU*
zwvYUxT4#GL@3C~gZhyXz6@dPDD@29qMZ(#!s*1WELW+>t!Za2|if+)WOz>~LB|qOl
z-i-Lx2KjeQq(^|P7UVyGtxl@fq(8&#CZqsneBggtlxl2RMUS>-KEQH)Bxse&Q|57r
z#cJM}>|1Ss@vWn`Z#Ul2v0;i1O!Ls77xTDad?6seqm(04oBW9}PUtzS-t4&|OF9WV
zi8aWz978L)meo3&P@u=V9K&H%l}WhQzynE;id>t7BcwsEWI)B^#ph&NLrdnaXc?Vw
z9N#U)*j(P7^ovg1=VOjV6v1&)avz!M+%`F$owSkenm5KIWt)tg%CfUGvJQkDT$Y9C
zcz9!}bApKQAvEnqZMKHeoDqi)<ykt;&syt;ykc9uP}b{yN>PFzFUBs{D((V0=x@f(
zOL&n?r!+3?4;s5`gjj8F^Pnhlf?r#r%+h4y2sE3{$kbyT4n;JekzC1Xg+QKUA4)IP
z=)`6ZOK>9-@v^@$tZuTHu^s9e-Qe5E;=tsPXl27ju@PNgUz?ngEz{xjqiA<r0-9X$
zo(A@^09v>*L2{BPQK0fPwxuE@-I|tzer=0y^#lmYtQg$Kl*W3jKr^@%k_Jk-k9x!H
zSdJ!ESL9V@M0!**#XqC;WOjCZLh3<0YE#sl*IKPGnSoyrHb3K75Ws3Hrx~03pM}p%
z5EsH}nFgyRudiK!ppZD|jOV1%c_Bv0vH?5BSqqA^FEK~TTt9*>xxra;BgDT@7|V$5
zau{f8F>y9R$~qg^muR)<YZ6Yp1|aKfgT0q3iEIf!A(bs))wUXqf*;$+GWEr<O&bh1
zwvj%6|87H@p@8^igJXa4aLtyp!jV}+nxIIg?HhO&NPpCgJmQyz(5LXI?Hd4i6eoSY
z(l99SJh@DxqyiKc@)wFM;IT+gsaEYOpsBv$skp2-xSrkx9<E3sT1M@=K(SQa0xrFP
zZ)cNH`ti072Z}gAMfBnsbc@IOlTV1muC?zB;Fopi3cCBYZp^>eIvbm`-E}4EYKPXS
z<8r%g@wInk@)bn1C2)=a-o^$6*=5)igR@OHYVfD<?%lRcK;i7rD4P9)n=;T7-TTMS
zuOmmB3B|gR_>uW(w0s*ryS+><4B7CULT;R-zHIk#l$}lTA|2go%crK($0sHd3KK!v
z7)Y2VIo?hyV#Oa)TlQXpXtf+bqT-u<k`C8_K3jJgS$v!P_qN_=))$tEf=NPn&n)P%
zZC6eWyB3XIM3Bh`x0id0mUl%?XM}MI>7N9QYtf-?eft8ho*_Ap*dsa>QS?usf2Pa+
zg+(sw>Br%CHcC0*<4~k^X(g^4_S88P@$3-McZa!89Ep9}xlQ(()TUKLob>536xcGG
zM31;(>IqR5=#45rRRNn?x9e3Lo~s#-Rh^+nW_Su6fY_)B+k)YX^7eB3Wz?Y`D!43b
z8dlAsd*ziry;p3-klR2}2@t>@|CmEOp@{&kt?fI+AYwf_cgvL3ZDd6Se|7eNv_NTZ
zN4Md$xGfLnhNO1Ox7nXvXQ~TVx-mn7qq_Hq8Xzlc9)TpVP4X|{%6dc&r=-j$x5L{9
zP*i8jXj|z;SO(K-YtW-&etMArWt9gF`IZ8%hW11QNex^k20E*b%-TjG6=>3?TWBC8
zD%ILAk}HYn3(*aFpVk_TjcN3cUtS8?#>-_!@gd0g`>y=Nvy*W)G;P;9pqpVx6S4m^
zTqSxO*+2j=SvIsRB3T^{67V#!YMNK?uvi%MyWzk7(I%p)Zm`u$u4D}2!i5&V`^L~<
zvW9?tPDi&|`>lrlurS1=dyEN{A4f66w2s@oDQPs!F<6sm)`sj3(r7zmW@fBCi!r~e
zX<n|9i`7NF;a;@-cCx(Yae^^=!cEzsmd~CmK`HM8&DU=7!{uY6@y{Qw(Uymb0X3}o
z<~XIcU10Xru;$&k2W^{W7qWJvc10bw7F{sOwrhH{n3kWlZrByw(t3viGj3SZ{^0bs
z4J&5W#wT>5k)uVo=8sPIc=GvR$B_*@a|9<}*nB#bAz#RFWM`)BPD7?<-JbJ)%l0I^
z^syajZOxX;+uwP#ye_!waEEHuaR&HM;-4B$AD}o9wfO+P1>a%I0L7^xhl74$APKQ^
zTvAl(p1C1>W1heZ<r`=LH$LIi9=+h6qjCHOy1tTq^G%bJ_ANe_Rt$i)$JyTQv$Zf-
zfLr#B-X0PcviTTM8tCZm+I_g=?uh%lt5}8d!$nOpGt0MK)X)q2qL#)#K!|iKZMUnw
zThJB8Kn#${7y8)(*>bS=vh`L+HmnAw9IzLZMKVS*L4-89IYC)D;TSYpCE>1nMJBgL
z1H_z!TC>$+({?l1&E%YW(i`KoGxIu-i9&?*5I^lxi1UL_CBNNj?;L{1G~oF+U2%RY
zqkGIphmO|jr!<O@4DZ%F<7>E*)n8mXtT8eDY|Zbqm}3@01OtW$T4TH|&;I7Ys!x$^
zM=HZel%9Fjq>&yY#m3ipcmc9{gNlt~wr+Uw$=Ayp8rG^~)!D{7@4)0+-6z)IeEL*S
z^ihCPWeY|E&1%?iuNy9W9q?Dgo7M1#M?8*fu|21+k)KsSH2LrZoU|PtK6{$hSDHBy
zBhF%;(yz(fYRaAx=>Z}~BZdfPPLl@VJ53gTG3RfajWY<nq!UQvFFZGMcv11(%p0^+
zaUdyrrW|<B-`XO$Vm|wJV-5R2>3DaJ*;h7(m|=pd)%gEyyzRg3f4{o%=i9fxul@PI
z_}9k&BWieA6*3O(?OQzp&B?Hh4f^~jUZwhd$Q+bTDh5*kncZ@Te;dvU<)b1!O-ZRC
z$5&a@JOpi!`aFa)l3fj9uGr)EdSZ(fmOo*v_g+u%$2mD>S9}vC3;sJ#7wKCZ9f?pc
z*coFCuQXTz<=(}eCif&E8w({xSn$~=xYnKjlu6bHE~nXKNa$3%6azh$ji*mSec5>U
zt*Hv&@T|Q1^12vI#gh;iXc#*+3nWcNla)L+iPT%0+ZZX`I~axs_Q{sR%Mle;OX+22
z>WXv@d8{-fW0qdgj6J4;B&uNoGBw4F3UOj9ZnzAXB~O!VO!W1VMc(pSaC)+D%)Usy
zi`PA((Oq2G$3GT3Bb20%v9?~ZNGRSf_Gd`X8jJ{9-#FPocw5ukg1cM51ygtCpzQ*@
z5g0@amkui;3(wF)6HvcCpMr#d_Tw3{%SoffAR59}WeX<AsxuEyV}iW;7(E#?8v5yn
z)^X=*YD*5F4UVZd92pq-1FpPQ%8IMZ5Y<^yUZgIh3a(NFva3EeFk5)SukYE3aYz4x
zr~8VwEudhmO<u<7w`0LLsNc()?qbMe_+BI=Q@GTRp1nBOd-~?p!G9kg?!DeU*d@Pm
zbcp#kea(~2e&(9zEg9MvV)WH+t~K>@r!ypya?{ZaZd&UW#3gdpA48zgF)SE<-6ONf
z9}@<>Xn7Y`5O{}SH<xYwTq%p8;jC59ZXZ5lJ9eWYYozI#c{0n!BMz*>k}mP8U6dKG
zzm_Wj4OW~^0IQFvF5?uyza|EDN;gCrv2G}G%UTmQ4X&*B=@l+40JC$MIaqg~2xKvW
zgch04U`6!e@_jZ1A;qv}$e@kKPDwKerxEW&M6~1r^1eIi&`1F4gsLR2M&C>jiMb!!
zSOQ}@JePoh2^ZH7=9P`T&v0Z`Cqtq#4=*HO<8*@m8GGN|+`YE<yo26hcx1OXp$ND~
zWJxWn2f$)64@HWLHEDR<5RByqvzNDowdDUfSL5yNm}aE>!tzFzhho_o8js6u`6rg#
zmP4Guay&~XX@NHrE!(>3pIpn9{1dNtd^xatE#JY{c5F!$wkvG7KDj0kdz*?a`qw{a
z89Y6}hJ}?kl*${T^2X($FOy*!XF{T-iFP$!yLEB)Crum|coX?)lu&CRC{QdsqP|P|
z@(UZeeVu?O(EX>ZT?+JL1vIi{Kz$rpvy}b;oBM16pK;6wMad1;Zs`qF1OD=;5B7Sh
zEl346d;2zCbNLoq8tK_uUh7#E7vPqrvSJy~%d(R6B^f0r98t*!Qkh*$$DlvOq`NYo
z?V9@{$zDN#_tn|&bv0UFJuIc`@tdTG9o<mZ3oE|yhFV`@uN9+83cgO1W^5u<^RrJ1
zidTY~`Oo0YDRy7F;~wn2`SoDm!g4y}_=>KCzM(p7ezS#N+0)c8ajPqMU>I9Rvzho#
zz#_qS8?jvyukG@TBW3Ezi^-u#b?f3uKGj*$Z2D>vuv*gQ<)<_*ZJZAgUIKa=uh1ha
z1Nar3wq>uOh3|AaAFd7Xqd)%mBdXsN)@oVUXc64>N-T%)GO#(qM`xrr6A`s#9!PXY
zWSd_E!iGU*tgcZ@?3EV~i`EXM$8zOyZKAh$ExrtwF&+y5aE{5PY<aDd4T7Ontj2GS
zpS^l|{Pfi?zwGV5sjq5U&Mel8-tgboLYe>%(}U-`PxpKc$U?nneGo?Xm)9@%pcjW;
z!m^Z~^2+IyEVCa@^C?`ysJ69SwCC{YaGXODm(!_kcVXxBW0WGCz@dJIst8pu$xv3C
z?NvdAl->ARwUB^y1g%@(R`Dn*v)|MFbd}Lr+rf8wb09yUrG=L1VcM8v4L2IBbhMJa
ztM3>}l5H$z-7YSZ;&?Oz<(rl<mcQ-soxbK|lZuU)9rjoqpCjTOcQXYIHNpXS%%*G|
zG8<R^{`eHF=9}t893E<p$LVD{HoiG2KsTwJ-=)@X$N^fB!*7%i4M@|K;jDl+p<_H_
zU0(uFR&h#*duxl9*9Vp&V%u?$5F3n@$|xmG6zPbzl$JIqU|C4?x1k(wv!U2UTAk-3
zd!bp`&?zk7Z-`}Jwtff7RC>WyZ2jv=&H&OaH7Ea^<<`91>U7q#?sZwhY)SH5lVago
zmu1W4?p&v|hOa7}M$&*GbPl5=<Cx3d#M%ROY?-QO;)6HGd;8Chf8IOTBL|f0X5Zw+
z;xZFDC$fueN&l-Pmou7Uk?wFdlPl@io8#Ype(`4S@HIIX4bysa`$!?)iMO5h6Dg2h
z|L=yKq_MnpXK6O9SaLkdVJ%yR#aMRuX7}I?mx=ABskO%sHMLI^pkEJO{`c{#*L(ZU
zjy!wy@+G;2Kp9s2#{)8vhmH#IAMv(!mVEQgj+owP%f*Rn#{{dC*4KC3LSQ{h9&7c3
z#KU%y`3rXx46WCukag(zCzk8xDLvwXAQX-;QFvFYM<za?-YV2nR3B(9q@Qa>J!mbU
zo}%nKm!~`^?F*Ez!k4>;hwcr|F5I_Z#?Vsi6eC(>;ZZRRdnG6$rrAx-e<AS;BIDol
zU-zFvl#X)`+u!@m`Q6?>-jLJx(D}W*c{!$8QNrm#xYKRHz@C5bV*e+%Ah0k3a^t!H
zd0qXT=zYhR+!)h~;;sHB82KK>-bqJwi@UpO>19Bf3Yu05(h+0A5VR4{Um4sj{E?iL
zXyb`{&5mmTmcy0`RFz6A{8gP7`G<Hd!2iuV=njt@007h6d+s&dAl}z)j|M4LkNFnS
z>Hx#pY<-5Q$Bw76d7+|NQ8bc{H7sAr^Z|;^G-#0O*7|7%DldilSjFdU$1AoK?||i6
zIMN65&OdTzyKKAjHp*_43u=+?&P`jA-df{Yw&*>}I*ILV?C$c8pOAS`H-~-nu35;G
z!Pf+1zL5wrbB{()YB8b?U2mZ4Frny+ihta8JM}BLflL0vW)BIHbfRW>*OhARIYK_Y
z^WNRA8x@Yt&br3mcMo3d{`hil`v%)k%<WF~%K5!5^5oY4ZoK`P{9g&ljhLm>$8gPX
z*&vvDTWF|`H-111+1v7))whS=tf4o(q}c;xmd4es+t_&47WyerI2ycLklGM5BfpY4
zCrp27)0V{}f?|Y=)}z6@qs@0z!WBafL}fclQ9bsreDR<g4cD{`HVoeF_?&%Ywo7`>
z(Fa=Cvf>uIhd7ekZXYfw@wm@e5>PDDcgbV)k(7=-dKptoqy^1SU6rK9Wz>^jxT><V
z&#1>fbyX5)kx@;2Zd6p~1FO&lKFUr{smsOj`}C?@)#h!j$2SDyp0%7!&eI~Rz^#zB
z&y+B;n9v7lDfxFGG~<upE*d4#GWS+oW;t6<i~J%&Yd4+sbQGQNY(ch1>wXlyIfrBn
zkm7|uFM~5`#Rz6)G|t|Omu6V-+s0$HCRtzOO_1Ilez|&zK8cuvxt5ff`YWnVV==G5
z*^0#aeUY~&TGN}hrmYcvz4T8+W>u2dM9E1$1LSh{Ca=DuC#A|Z<b{Q25f#C{!-?!N
z7YU90Pw|cyd7mrr4Fm#kpAHD6qA#7Sv7=bo9pZPokMKNh#L|ggv}EokJha|+hoFAJ
z(K3}WT4veyIvn7rd<4YoFH|9J>_OCBso&V?W^<>stPREs=Qsr`l`RN*Ku;KNJb}0O
z;8l%VSZo`J>PPQry7_$a$phQ%Re3;eu+N=-=DYw!-oxMR9#h(FjomkCdCMJ*i=MdI
zi2BP8?`%rykIifJBtDM0Pq1(arUiOJ*8lv|u64{Q&23%JyGnMDbPI=SO~Co59<PZY
zkr5|72TR~|9s5Y*WK#b;_MJYJpJJ2Yp8M!t&bz@~%<tTZG!Jw6z2D26NA}SxJJDMP
z(K7b{B>ygN%LD1{vY`655%ruDo|0nApJmq!maA(^I>YOw@1HDvW&FTZW_{5AuD`ia
z^SQp<0$<Xv=KdLMZa#Q$FZzmf<)QI!6m4xjy#Me4?KLYH4F-1ygXpU-KR5sL=zB87
zOQ?8%UH6*5-0EpTKRh+tR)2FTqE&u=EfR%9_YjT!KKtqia8o^lX!|IFu<#|S$I`VF
zQJ8rAESZrLqCg4wsYuVFAJc@8j2;cs@i;&Gfkl%)p)~X9Rgs;YS42v_`|jcT*5>AS
zsNnA+krE3r$YvmTURBfWjSX-!q{?1DFU~etfpX)d9IdlIK-Q!E^h5OH;j`!^{S2w`
zL6e`Se?Q!gR$h#@Bf2)Ct%ncpetS29UaW6!t#93nw(f4<{cij2!~cm!v(wq{(F*I)
z<UL!OtVe2~{08I7hG0pVfm=8JpeuiJnPg*dOpoX{2P_fXpntEwnGBXd$!3%IoTo0J
zNy{*_fP8C-uaG%jna?<*@E4po#;@%Nx4L<!1n+P`b3*kw%eq?nqju%RtQRA3+St;P
zUM7W>9@pyv4TV?KGe|WUn~g(QET-&bt@o?5-vKxSZ&fsM5V9^of+p}kA8#<<c-dhs
z-UZsGuB(3{h4B6=(FXy&giXoXOSlEomtDXEA$(m2!@)XpH(yLwm9Ut4SKqLnfLR5u
z+NgJk3?2o!p<}jWG8l*eC(6ND0j;@aT?rl!OW#VnNCU>*y(=NGDMvfNIa!=(DUxWw
z!l5q`)p=530-uvKl}Rj23&4xhT8L<-q|7QJmWQDy=7_bu*^fwNPG$n5AFG{!mh&OL
zmW*nZZ3#3qdLz>0I8R1odN&x3N}?v?Fk6VS%1Qp&tKartzS@2EV*e*jo{a0o{^6V5
zmoLeOG#N>mLz36ov|e98LZD3wq?BxvA4;Vwob2+D=>DY3%RmIX)?;b%NG&4IRW_WF
zyTJGg!jSTUTu3W)YUS%fQtXlbNYfUXNFG^1S}#&9Ysx69K9Jp06T56ug|7z<_n{_n
z#Vq9!$Q<m=EmdlMaZ5`$03)AtE&Z`rHU|u;rp?0P=r%sOG_6=0suW?dPV*JdD5oTP
zJ0p9<6vMnyj4(Wvd8q2!gArNSI8}n|PuNNT6Q#1yX26)@x=t3N^~)*vMKI(6+$CXz
zRZ_k$X}md#y4+3HF_j&DzYR&|Cn@L})4VLRld)}#SaiRvxBkqMtX^picj^zAuq>-G
zB4odlzU7ng6~7G@@TqoA+x9|9FcK8W{F9lQ;jwv{C3rN!d33OM_@)P24`#u{wiu$7
zL3v%fjLJ`WGFtspH9ep<qk5X6kfl8VXRdLoc=5VLMb~tW|IUGlEOalo#J9FXDwP}~
zvT>0XDd7y+n@ikZ5z7F3%oN^I5l_SDZ0XplH!r&i+9GA&64rdV6^rETli7HzMHZQW
zIEs<F{^s!pG9bTC$w`@2>lIm^AR0ua%+kWx7O@l03ye=19ot_C7>28@rm=CUvEk3y
zd8srRmL(p-#DRh&uzCkTmsj#$bZ2E)<Mr=asJ2pzS0Z)l5!$~mh<64Dn)yb*(=0*i
zTME8P{Xy>(+L^Pxjq2xXiBht<c5TpxKrCHT_?pUnqMW|kB#BdEtLrRD3S^pwjN?=C
zzp|E=Oe#2`QU40{pg@16ygRnv5Ex|udjA`xMh&ii!Lb#8%qB^3RofDHu(#U^`d=ql
zQ|32|zK?<m8X+d$o#BP5x#p+*Wsi#^s8Il%mSV#63XpL@apbx$s-;YIfL)VQr5zGR
zom@Y)`nGk$`Bj*5iR(kVKpB$9+Gl(wTLY(L6{=T<$G^SUCkl7X0}wGDEKU#xhC@B%
zwDy_@*)&!$PaeDgmBo-k_<M?hBQq;n>lVvMLNQgGRQeH5T@u$#@V8`encxo6U|eUU
zT%f)#&N#SJH(RUNU*6{N)nV$4Ae*i~$;v%=R6~z%uQfd7#TpW90MQyZZz)p;k!r3o
zo_PypV4aZ&<UmvqK<a{R_ar$X$_Za{^d?!Ruy!h<wRB3Qaoyt0R~5i_N3pppSp`O!
z=5c<uy4j23UAle1>8b7@^{qloT;xnG9Xj!_Dwbm#fEn&Qr9IhX!-#iWDR1}^qqHf8
z5o0U;=xEaeB`$iTQ)!93Yhw&k;XUg>u20qrScVw|9)b_NvdzY}lD!k17fn)tBVV8V
zzH9~v60}4_iD#2gsH>nHbEKD98G-A?9c7c%6;D;LXP{2%`x(7$lYOk`3WyS=>4n`U
znq+h*c}X4n$GjktUya#!R*_Z<mug`HFTp$M-sz^mA?;CGl%uTT!{Qsjsw(cTsbdW{
zK%v;9sY#po){BXc>7PDvc7%(z5FqC)@R@bM(dk|G9a+jyKzkVYm**+4oRlTIk9vwB
zO0dT(bl%CPffPkSv)l@~XTPqp9yNC$aMJ5sBy9%=MEUh;EB|~QVQ=HhY_QAZxE`N^
z!4wR$n(>6%Wj^G^`=~0CNlE=+9jCh4YYCK{j7F?mTUO-fkOTUeO{pj6F*~6Hj%9xz
z>1&B{UwxA^^rL_PxyX95Oiwk8@U>nLCF{|0s?Y6O4~<c%SCi?R;T`yNHjbMZo5&NK
z$_$06Zm8zaq5}gyZgevLQWHt<vT;WZ;o5}^XsGs$sDC;@AHCd0;$EZLTI;BN+`Uy^
zgKYO)na#z1Uo;uaCWYN)dU*RGvI4&;cO3Z_d{@6L20D*6UCj*8$|f4YZv0+Lh=!zS
zpA0c?wZ|iAj8LzqqL2SNGt`o`2*e=%-s#BNH)&bP7ZG?}xx&W|?liAH#tizK@Dy33
z(}MJ5QXxjL>O!xTMt7mQF-fzc4_eLMKWEuxGEPCinw}2qUgPkEov(T<O1PQmWQN(R
zTRWhu?+Qp7b)|9@x4fNtx0SpPwg>L^*!5Ey0i=(cnpL1R4M*{o)$!exI1Iu_Ad`wH
zS*K_MCbG_WLGuI^iQ%aAOWq=z`o&AuDR$`>#XjSt4rdn^Xf-x^r+nVfJ6_U4vP17M
zE>NV_*?3!igJ7y~sp0gWrRA{5@B&P`ZR}qj5@L8djm9ym#U1^aM?wxED}^Z^?89dM
zV>y#nm;P`E<`4$%=M`FUd*RIIJ>*rJhek`*Dz+Tj%Ei@1lHpS{SvQ(x`xp7S78rAt
z&kCas?}VcY!($t8K(;~jh#LY7Vu;K(s6(@@z%f+W&9{vD7N@=?scVBn+FNznGSopW
zeMHK>JBrcAk|lUBJ4=cTlp<d9wv9GR9dXM^ndLnUh+h>_0U7oDBk?Qs-k$U#&p3Pr
z2)h&pB9PdcOvy)MFYj21R?ORjIyb;Q))xo+cuzki|7bo}5Bpfc*EZb4$M3~6kM_jD
zJJ!t`VBKtj7pQupE~~1!k<!>(qUg<Fn>KbLUz0XAxEihR#d@=~?bT%wrn_rv{Jy65
zEK1q_I5n_<z4<c1%q9qlkdD+-MrUj<@{D*zxFv=sN#X~aETyMRN~)@~CQafg7+Jj|
z{LLT5ctPrrOYd_DHgA0~bBVJr@5EF9A=OfKSrmNwi`RRKqQtKr3sjxsW4H^$wI}Wg
zbT0kX2>;NxfEX;Y#siXKGg`74n8f{*dq*taX20EDjz)P}qSGsi3i%2exGf$Z-J=)R
z2==Nq|LC>nG4@CE=;iIDVf6f|cKJ5@ZJyCHHJRohoO|R*hK>t=Z5}n(%Nxc_Q}K~u
z!N2p2mugA$SR#7{C@|n!L~6sY^K*b5csNMbias)#Et$5hFh%sDff;g>BLk<65SBnq
z@;Cf54}+K{BshdR3S$xe{t0+Q^&$#FL7O+YL_5-nO<0wDfd9_JD5~@bKC%2rP#b>z
z1YD{mEYf*|z39Xu^nqNy4gYjtkn6B!Cv<7eadUBHo{v<U`H+m?)5=3~FjuLFkY0_c
z59)ikMkC<&N_MnNhp_x^r<O;zEB`412=uS6!p4Rr6utGt@M#LPNY&9ekIUPdQ;cE$
zpj`5>0}Fg^j?i8<Fl8_=Q#{L$8bK!TPkpf!qym1W0C~`&(W7YVK6rA{ueYOec0#kC
z!QZ`TvlngM!`G^Qzpn!QBh8B|lWNWMBN{NjG2B9VyJj(87uwDkc9xyEf+g-lSs7u|
z&cQsiBFYZ3S-`)zTXa)HxV5yTzu0G#eW`Gt7Z*(DMdZA)Pnu`8PF+k*Db2pM*%fx(
zruh{_7CFO=s4{_kybZI=IoG6kF{Y5Iq`%E`WNP-}k^I9x+e!hvpk^1Vd}7qPVn)>R
za{84|O}?+yWx&&>!$@8i2<`hOp%|%!y&Y^T846`(;#GDuNQlbh1}Rb5wtQRptAn)E
zFT-=IQU(-X!(i}=zkD11A>GePjvE56p%B0Jh-VLa5<5Z8e%n3RhYaECd_%+tH+Vf2
z1D#FA5Y|D?(Fnq4BS@4Af5k;gDmn88mT7g6eDGb{-089DGc&1ll8v+K%JTZ(RKbQ!
z>df3*t9>L~<lh-t$3Hy>p8|w=m0?D}q4?b;Yr5~OC{D*A|NdNq3ANy8!(f)+$HGGM
z*`|Vd9j!2zq_9cg4$L?M^bh-v0*z=vv8yW>f$M6f7C}pkJ0pz@;#OZ1Z8ho*G`WcA
zrMtR-0Cq^3T!L#2OJ>Ub$xJN3LzWR0U}lA_2?NY&<SYxT@+Cm6&+<z`OhjabTHLhx
zK8F5q%NkBP`=gDIm(!`s+P~(R^z^Wm=Z{{s>l`;kKjQ%hx3OtnR_oj+ksj40;2n^q
z-8%RSOx&+?2+Blqhm=}905{kIuV(m@B}JNCS4sZ+Q9Q~DIB6*I<Ia*JMnq%)RHH-$
z5lfti+L}qjeikO>dkV*3IWy%ugCNUa7wTbg6&)gcc@&esitMB`z3$ixl2OKjxyatf
zojFQnzmKqGeonmOT?lx#86ujA8fQ)MO?J#8>rY1M$?QxC18R!45Xv7DTU+Kh8s*^O
zxttncI-0vs?*&+aus0p3V}H}x*od;TNe+M`v<Y-Dhg0(;<y$YO(+#*&l?SCaJC2Ay
zin{;<t&%fpcuqbzXI@)%Z^#Egz#1mQN@L(I{;{ghVUJI8kBY#X-NV1}h+{_t29kjg
zL%NNux`VaAwfmig2>|5DcJbq+w8e@wdlVZH9<F_y{M&V-ej(r|?0YfzwU9g5M4qS`
zx(~(OjE2bsWC{T`AfhjY@Ng@^9!x(y^C`?Pyb*Jf*<_RfESNkrk_kAd3;7Ik+$1CV
zatwSq2L6SPfls#G3k(?8<i++Ajb<q<OZEX7&?r;jC;p{2eae!~8$U}jJm=<rD|q)8
z3<K_S2>{G1gx8_338N@ECEBnBSIHkfs3_uOjN#gT^nG}sv~iW$MsOJiqak1~gOe!v
z(4$h&(>iIJpdzKaCRQiIFRDXwITr!@jE;F!I;W*b%dnYvpG}!rK;Y6hhE3BT!>pv~
zH?S>NWAflFgJ7T&GUl@h4JRh7*m1hwFcCt9;ts2}(?(6u>8!PkO>k-q;&dgtK)~Uu
z#5lN)<JzGzgLlF^8tBmWHke<>X$3c63!3ySv+g6aZ2gJ7p9XuFyY!l$!-NH<)<h0}
zBJ_~{ph$-^BK?;sqWR^g(Iax&KfzGDM<9DoBC>UXt%B^oNkoUk%D{FAU|*c5Qoe6j
zZBEAkyfTqWN;|6ni!5>31Dt6Mn3hyK)|#*em>vPT4^x5gAE%`k^e;NXbR@<odeDo)
zT3Op^K1Bx(Cpc9n6ooh6wT9ug44rC!Dq*X-)QXYHjM*}jk&O^PO~&Lb9$j(q0jSVf
z6%EhR;d|8YA!h|!D1<J+j7*cW`Z3jhx`oz9WKV0u5$xB#1<F+)n1-T=w3;Xhdtp<7
z9lbV`-N0ctYhZ!FzwMZ|lKH2|+t0_*0)!wq^wyVuuj!4+&48{GwZLZng?QX_2HIm}
zDP$eBBmuUl++*-AGFGqdW(}5{Fe3d-0ekT(I!WPGfNVezV(&2Qvk+;p42Z)QFluSm
z6xiGnbvL7|nN_JhxR+x)GE#`yTV#m@`_%2vEs^l-N7^0SCqVlk9VGu%ri^=4LogP=
zP(%K5&nZvpt9NU_HnDyaAm2tW8VR_3#?<!hEvXAu7IW?4N)c)2P^gDtjVVN6V=reX
z<PX;o#5+ezX$)3OGqrC;Ac)gc$S$|>*9@lmYfEl=?_S3#xEl|;j*#mzlP-YaLd2cw
z95Drv{<aI1id5-G@kR_OPN1aw9^+Q!K<sJn9l%J6p!Gyo*TODAs#LLjTaD7^S0U6g
zhWynMdNm55qFT6=3b+p!&BirN7_f?40Pw1$u5PkRa1OAl!Ka_A0%nwzpM_nD)owdw
zF;MPIVp^0d^S!zCmi&AJ=~Clc8|2?L;gy3Cup6-pt4kwpGjkYoB__pDv^)y5U0VDH
zD5xypsZ!K1$AdNf7Oe;z58Q>~q7*^^sX$i0iyKFkU0riJF}y^?f6@sG{qJ!5InGc1
zj~tGxycF)9^u>Tfxw5Ya_sK7@%UnS%Gewe>EH`RQI}lyWN_@<cZZ8x*Te0wNZzE-&
zj}YwxvVo^E=<Iz$bs3_Mbaz8}mQG7>7Mzwr-Uup$6cs(F`gw;?_h_2Ko5?AKuO*cF
zDobOv!ZLesJ*uJE=QL@fu@ZS9B})jdXh!;b`Rle?)xzu|nNGp=A=hA=CDQlyw#4bE
zAvQDobbL)SeJS#2IxEgnRHGGGa%O2J%cjWEOBJl&qQur+PyQ}4I{e1+nvv}o+o4gJ
z4&Y)Z^a!oI=5$xm;OG3bwKOOWa=UWAn#gGhU>ruiXM7!$%nga(T*xXI5vjw>Dh8y#
z@kYv4+csHgO1cc5nWH?<XJdx?Pc|_kDUg<hW^%#2zHp&p85rdgX_<{ulq2wy!IINi
zg;=Tyn_uv*;&9>QGu&$7ds~Je%iYXjdnD9Y8r7*Si7K;SO=%jzd_2-lO8wi9<w!nP
zSdi@1JOD<Jsb$|lw?QCm7mTcYA?P)Ug>1RWmCM7aDrbBmvk3{S99xl^b#}2xJo=z;
zVJQ7s^Q<3U?7-h`R;2zeOd%fYQ?yen$3(<tRyK+p#hR;KJxJA4llk}_18<G$&oJ0C
zpe_w0)hn}5(SX`4eV9?7B@hduKm%v=`Yb*tWaLB_Fh>shg|Ds>5@l3%K&wa!>dJ<j
z?pA*@c0i~XMT7ZzC1Z=bNuJo|!V;KfMOCD!^&Nm+da@87$r@p!{7x8%c4o)#Z)~kr
z!`B|?X{NEpeuYrD2uf2r9@TUtZ5fMw!Ga@3>mzCzT_r9DC6o=j_q{XrP|{AO**a&u
zw*@gfM^Go2cH6#tY4eM<Tu-z$rzPT;S|Wq0DE+EG)L*;1uTc%?d7CaTxUZg0)~H#|
zFq-_td&<{wd)=yO+b33s1<>bkZJKS`yvD0IsqH#CD>8RK<KtuazClph;mb=G_$nXg
zAJU?UKxdBpT4W35hPy`RF7DA}@NK&(a>%#ps;JeuyCSZ%U3YmvXuIx;TAjPAMLo9b
zvKpz_uG?D8&Ry4l3X0@|_wwKw2RU3v?g98Q4=wI_njbqQ?o8*vn%4JwKhH1IaZYZ(
z*x~P&tRB{CDc8fOT4cL^<}|q$;4@+F?}b**_dqKPwd~1xI&NYGFXC!nd~a#m?lNvw
zza6m))Hjh#a_RR<q;df7Dz0Qzw1nlkNdrR;kS_VmLi+^|EbyE4fdwB|;9HAvzErUm
z@lQy+V|!F#%DO1AW~au`6^WvW9p71UhYyrHozwCdOUN?lfca8r&`AsTBGne2wVG!}
z)xP^OlgO!+_fzLH6;84&=RlkbpYFgZuTQ%i-A+UJNV&7XL`}5~t(#0}RN6{~u?@DB
z3w;ECJ;_kV_i1HAIbynr1t-u}BILo;Rv1K=|9W!3hPGf4=o%WPMIr+~+iK8$&C^q5
z4t1Yxv1NO0-+gTQb$wB<`@LN*|JMEXZ|=UHYc)If{bv-}*4=jQJH8(CO5HkJGDH8$
zr~^6)eKn}{7Tl^Q<*Z2QQy@OU(knK)^uxm*(VS;ffo_nUombH~AJ$!}9j{s9HHz#a
z)sHFcaJC-y9Ex*XWfzcSOxQ#1ZY_#Y6Z|jOLk0PjzBu$E>1m3;i??|PIn5D))TrkW
z0bsyl$Zgv6FEFGy2u{zZ+)Ui#IXLwXPO^#efy{j(KC}~-X;GBgEII;)O1Av76x~L+
zhY<ONibFWqjC^w%32Yhdl~d&F-gL_Dn+(I*GB=20jY^1MqkIGjHkADAQmsh#7m1!<
zqEVj6hbRT%@=S#WCo;S6oW@Dj+G_6DXuU@;R_T0#;lgU!OUJ75^^#WEnJ*0$qxfes
z%>)PzM9H6l$9$DDQf{Xn4sr871y?`u^44<n@@)+WwPS-(x4RvhFYnftXb;Yq*A^}7
z&C_X6K<4AV`u^CS|FzoPuLR6-p~*JwyC86n2<z*jD>&SHf8Z3GEojF+)1tFu!5uh?
zkJ$-R>x|2-f3AUbo4uFp&|Yo*svtPT0wKDwvz`BvlhuZ6yzMcVy2-SB!lnK;?cQ){
zovs`G0gK8eYSp7znU-K2pz*<6U+F=wlgU+UP%L;4WfWUKin4lbUq(f>MX>`y<`>Hj
z#0cuZ4yf0G9kg2Kl!+E!QI533JbfvS6L=DoT9#K4{8l>IA)|8;SF~{ZPB-v}hc&Y}
zv|EB+8*WJ=9=)^{25)#JHQ@EEwRq@KcSHlw$9GD2Gov)nZH!2Al&_-z83h6(m0aY#
zQA<1&sTKh33rcc}h!!mq6byB3e_5l@G)=)aVI67^Se6=m=LU?j^}UgX>%dh#N0)<=
z&b_fOcG(`Ea>}nLVIQ_fEr02)$NW|s!ye!(rX;Ej)elryJ=CK06@I`zbU;+_I#wtx
zm7r44+PaNqEG8s(IghAI-c!%H>^*hVJmc;TnUZPCU&zxJ%It++iln4Hm7#ZpE7?1Z
z&-NnD<!<y`E-EKE>of)*z2yJ#*u^t95x83G)QmzSZV=%vEf7ghF^GMQmC5zj0qBB>
z$((R5%^Qw(W?452svRU4h!5~I6nqTrdrYN3EJ%(NhWNUq&tMxPYD3X3e&~gQaHT~3
z<^{A$@kU&6S=KXK(6IO(yAIFRG4EEazV3nV9e{W0@s0IVCVL-;DN6HpM5&d^{BfMI
zY!Z#~50i18jK~a*C<>Xw#K*H{gzTWaaKM)4+P-W>;~F3x*B#A*if-vmaH@)$4{4?5
z5Ny*Wn?YAN87@A7Y6)k&zGr*YGl=QLQL#8xd9V`EdB)AuS6emgJN|s(dMe`nwt6Zw
z;Z)p<^aOg13G(1a4`O0adoT8Xa(ZoXmLTR1$i!rrHsAyCVs;^N>XWs?n48E)YsV>V
z()>}Y=7ss8s~vJh;9~z77B6_y)7a31gI5Q~2YYXRJ=phT6qUTIj|ia_iK2xQru3-+
zdC0huuv$K7CG%DySt>6gyzw0`g=_D(+TBDQrT8<bhxD4KtfciPe=PIJyFZX+*K#Q>
zUn|Wubf2@Yh9Fo4@lFwne5%VtK*R9EQKO=}2K*sgS&c-lJ5JB_(qaa59k6qffmKW&
zqX5Em)2MRL%)<7HfOABEW>Zzkv-+L1$v%P<8sNTGSUbYi%1_JVY^85+P6`gUE5rS&
zVMIZD5*-+B=VwhT0G*~(y923XF(LR`zHV`5!~8Pqm;mBMv4Ung&NijjINeM;E*oc@
z)0<<;If=RET#T#5L6p#~IcYp^lnGBt+k|VM@k>{NA*s!qy+JZ@p5$%h$Br8tq;-1W
zwRsNb!pky+U6{pL0sirr#X`s7*JQ72kpg(iWDqJZ_ThB^IjCzRxd1*UbGOu*cfp#v
z-O^Sck1R)qFv%lf`C(}xmzwTo@xD?in`kLbcxp-N6UJZ{z)>*4-{PomBs#k)tMsB5
z35OCTt4$ABhd330FgGjG9>DA?z~1hZUkf)|7@&D5wQ|2Szn10%fNpYv#E2v}yQP3{
zLGUM=!I7dub$Li&>&3*FrpczNbDLy%uvi=Ex<g9Ec*XmxHK$zgGmEPO3uV(>k5)Hm
zITO8nuA%=_RXHy|!xGWes#y*tnke@oEzZ)wwgn!#Enk8?N-MB)HNrcM2%o}wh*+Kc
z)T)v*-`fFuV{7lvOc706J2TU2b9z|uZEZ$m5z*$zokBtLF^Y*tRnHbE%V-HsSfOlE
zMMYM=zd|79Q^;<%E`hj6<HPej2YU$JX~6=CrrE5*j9D350W>$7g0QOma8qwTieA7&
z3oNJK(;{D|#KzhCG<yB>Ybv8<-<Dn_DrXerl+a>lSUz#?=CBTT`KalFWO>Me7vvvg
zL=O~J=uQJZm(#5^n{cBGCCkiM=y1?uiO9kAQ8(JIITtlDiMQpCi=`dE^_Z25?%Xj}
zd?yfMN>){N!#1Ec6fti~K{M6CEbO$&3D6l|xwYTV3Qtbct{uDIGsRi7z4hrSaOj_A
zd@Et0MIIa|H6sR(W*d{#`(@e}H>|iDO5ABwcRjfSx`|kYUZXh~fcN4t7pk~d@*17v
zI`*M;`#$TwKC?}+S8an+C|c2~Q}Ol2rwFK{pdCXL?~plH)IGwUzSAV$<^|5i)z%SQ
zj0m2A^pqxnL-#t3^I9EqpQNRGWS%>N2}#vDU1l^KC)owjr>ls)&8lFhpapQh@cfjM
zgim>OeC~yGo0zX8zqkM!_efL{VGdV@o?-zE{ImYqfPVIjy*#D`|JtThq=`d?$VwG7
zbb8u$F{s#~op3L1%>!%WKGUdQ)b!MaS*N6IcAtE5X!gTSmT)ABQ<@NOGa}Kn{VXPn
z&vFK;b}T`ZzT2JVw&P3%{K-^|BsiedFByyE!=mfNt5cNI;~*;DGu<zPe7yGU9)3>9
z$lrI(;&_WT&_yscB)RnCa6B6|0h=3TojyfIIVl}xV_~j?COMD`_Lpli*&cL^(gXov
zcx7Ofh$8>^aom)J%i?SqJ}>t6=|ISa9Fr?~{DkxY&LeNx<Rg}S^f+Ev(k&P4Xrl+8
z*hgF6!<+Ze7CThyIBpqj*FKV41;K6^%&k`K*88kHoSiVLuTIIf<3gaDVp2g-c2&(k
z7N{1$u@1>m6x%as1qr#XbFy$_*V1hp{-FE03?u`?I~r}vXp~QgK%>PD{dq~5>@=gc
z%6_A2F!<AlFWj8ARbxwyfsiwzLk=>1ashVopR=q;5$06#%ceoo_U0n$b|ojJoO`l5
zQ23)=>Wh&6Qn$!t9K?h{C>LB*y<8ah*f7xeFz`D_DQx2=SMm`}HZoY-nV)NCMLwI_
zn1o-1a*0uKGX)Dcxx(9GY{5SR4`*5xj$}+N;CHWrA`QZ!a(;`a9q>)PLj<;(T#R@F
zQWUmYdFgpY!$zuEbC6sG+Ki`7+Ak^MR(=C@UpYO#ONqA!9%VUDS8g<pI9{EbvbfRy
zA+jb~uV{aMJ$SLY@UAStdP7%s`Dy~j8=N=DG)$Riy}Z&@WkPW)Do^Xnr4U1A1y^wh
z<T6|n9)Tu(v%WaU2m!I3)9RBn9i^j?U4s>UcZ5y)h4YrDV&k@8tE8l8vh}6SwxQ&1
zvNhyb^mV6Q6bR|^W3IvPBjclJyN<sbw6I-U3l)R4`g?`9zmKIbH#qV%uD|XsHcnVG
zde*p(WUF}b(muJOjAR83SrV;<czGMbBS?bO&_mm^Dl|=?VHGJuJyw;1ka|+1sI4B2
zMweWqhThR))!gjLxw+Ld#|jEwMO~b67kc_Bm(!nERvh6OKrWq$VoQ#2;;ql)U91|?
zGy5l?yNZ#WwOb;KLse%G%Y|bjg{u9HhF`2$cD@(X?gaM7Owo$EaLYCSQzWb8+>Fcx
zLYJ^5(<KVI>w%HmJh1l8LS#+}Xe07eWyx4`zZ>*72^oyxom6PH0HIV_Z5ToluyI^P
z<Lm-6$NK9==uZ!wq$!%v!a~zC^`+ZW8a-mxOA1*4ftB<Fu(Ax(0`Mle`K7*SGLh+t
zXCi{!w&+hiLSK$38By2DUTv*G5OB&1_r&9n7;IV2E~Yd^5j+Ti=aoLbiGw7Wk{lgP
z(CVbVFmWxBmZo$+<i&g1xYh!v=*V)$reB@TEi#>t)E+)jypP&$9y*>nWERb*X;N@M
zvZ5pEL4)D3E2NFfC}}Z#_+Yv(5@{@`#}rP_rx?|Rzw|8ME0JIE^!=HwjB?NL6_bc*
zSc?2<E0ve@Yx1wHJL+`#T64vjHQ#b<mn3AQkn_h7{Eop@kG0z0NAVSzDo{ZtdA#FQ
zM+43Srg>Qp^gsXPsZzrUxik=Wx_O^Y8{96{_e3z7%kU%(0D`r~WCNIhv0!~lm3vrj
zJ*jqK2)TdicZ50amm!+5+C#Fkk0`sEb$sgRUe2b|yr}R%0=M!ADldgZm37hoz0(<@
z{wukBV|Z9-(CN*q0Bf^PwzmExt>P|YSdr5k!$@cdtjc-+4ZWSQPPVF#!>HeNGStr4
z)7{uQ!i;f|Qg0C*Xh@W<_CQF1T5}P7fC%YvHmu6Pjuc$3Cb?Ifnta(TdkuSP4!mUQ
z72(}EEJ9Zu!+BE1J3&?CvkuGw|EuAOiaanG-e!yo7$VU~LPj`nfU8?dD#XWWAp5l3
zm68pC?OAFAGs2>gyKO&O`<?co=A~#kBmfc!)X?zmwcZ+Pqw84z`o`9c=vn8=GF`x+
z`w|VA1GA=d6$)G6^2}DekF+JyMiS(ruL9O(&=%c&Pr1J7jiI}Ie4Yh&-9-|EH~pKH
zMC?WvQ5oN?B#v)X62lIeznmm?xg+=zv~+vo62NPf7l_z{HQ3F!kj%lK6p`;w3MK!i
z#OV7|0?hwO@uwOrZW`cUJCm9MlJCw?3Ifx?sYeIXcavwxgxy+DQ24zqkaAsGs3!$*
zx1yjdc5f+YJhE(j0|;rnz^Cw^l_+Sn;6yZMxL_>}%rvpLv98x+bf7?A!Gw249y(w&
z@7(c(96Aht9-}j@u@DZseUo`2iq@{lB7;Rs&tzGzn`<w*DdX#b!=pF+X`m_9^v8>_
z2oGt;n>HK5R)28QJAtbS`Tb_Rh;@3H&x&E%F;TZUnCQ<x!=rgyaKjC=XQXH-hT>}7
zb89I!G`<=k>9g6{7yn1xvqp@$t=;jPw)4h#PD)^8@g!}V@*pXzU-D6Qnx&(*qc|Ru
z$``D1%fT3RcNXeofv5oNJr*8X85Dr>b{gb%p?zvch8KtqPN)(-dPJ(ZM8AK$KIu$(
zPJ^A{DPlH(&lI2?dI8Je1(y65RQXj~?VWlQH|qbSVn2HJ;$ZLTn^y<_eSEn0diP+L
z{7OExfPV9OWbDU9Ivpp&l)npZz=Po1x3Lo})6z)K)-vQ+I<0pZxCI{{BQg+YDLutW
zUy@OB!l6ujia($(<)d^pCfz;FWQ`EWrt0i>LkCF^Pjr%gh<51&9=}Nn+oYQOCpFif
zv<I;iA?x(oCnc7?@tNOj;aAotSuOx|NK!KM@p=sNFTN8eD}1*R+hyb0E@3!QvfUTS
zuzE2$#6`1en_$M12FODTP-N4T*D$D-pHd_!Out5v3Zodw#NfrjrfoS0B1`APwRI!C
z18VVa_IxozveT7ZrejMC&~fp>788e$@W=UNn9>Kn4W-t`<<>^=q3^ontt4b#KxXZ&
zS)x@*|Bv&N|4WC}@nuq!EbfYWHlxcJIZbC1z$x;DRZ?-H4o|k}vOk#CZ}_ZDBIXRI
zH-<-j<x`@so~1>se^{hvgvZ5IT-Q|;-!~{(R)i(?Rg<v(D=5PFcVM<6wZ5miC#g@e
z<CL&x>1i?>S3ji_0GlCV-bLO-Z6XV;#ZFWv0_c~%J67>i8`om{0yvONlJV8=Db;G9
z!Vb?-tr(_|$3e;PEV<nJJB78)3yWfluEMsmy~w(J#rLs2=D2wS@K6Zb3j_gUQY^c6
zeOR8oLX-(eL#0q$f6_Erj@uqb8(t;FVB>ylU}f*WI{0PxWjpAD=3HEhfJ68qQi~9&
zh6~5XawLrLwPASxMznfuMOn%ue2Wqcxsu(fGn4XtxnG7PkE>|WH4n^@Z8(0=BflG(
zsH>mt2>#=BJ;M@se4ba;bbDh%bsyRoRih0Y&HA9f8Hd0nv9TLhjhLvjlX4qw8gVZ&
zebdb!2jaw>Uj0T78-ve9?0FJF6&f3k5$7m6_+dYap3cfDzreo$Ocm3VjnY#>V8ltz
zN;t>L*$KI{5mhWN!0Y(rDw@tJ#79k{<@IF_Y)8@K5_C&`gjBaLu7=piI%b5c1+`Zq
zaj|gBCf8#~gEp)3b<B!^IgMcuxWiDz84{*dX-Pff1afOib`DM&!|7>{sADs9lT9hQ
zf-fI0v!3Es150FscNXOa1c@-^JsB^y%qimz0>zJcah#T*>$?|Dhb>gHNXUO3D0}K+
z-cez3$yH}k5^h|e2RGcMsvNIPz^a(e1^q0J%A8L5Hsc4G_F)cr=-A&%qri9D&D&fu
z<cfwXWL@UphSd^BG<z`&Xh$b&xzv-=y$J90v*Cxl7?q3_W>vc_fK`V47soyl_+F<T
zR?BimvGB6%@U0cJqws+L_7A7|G@Ve=RJO#RL9UibCkxU^OOhN?zZUa39Osb0_0)_T
z*N#kQTRWY{5@PQ9TY9yAN_GWubG~8$+vOBeei{p+O3rXG5)q`|)6HlGsf>sK!VzKA
zxX3;-TxMEM)|3GaI)o>#cyh=?5QhTvX{@v3_ms@)3QNES`E?bvOG1HsP+Nfc>1iqb
z_K(XHuI#I{F8zr7S~8-V%u>``QBiN3l2waSW;n`kda4|;uG_HlRNFR>sHe4htb=O}
zh^tstNlP`&%MziaVAwr=1dugHAy2OGK*@*0Sz(=5)jZ1QO^qZ`!$$N;)+aamA)%0`
z(;~YhT99MT^%VBX#Dn@IbCfzJUn($A1N9Ur<<^m~0Y}<r?P7^cm9|%hXx2N}e0%48
zP-LPGt*-T>337LKQl>*5X7$Gp<81OiT2XbmYn#aYsmvSifK{~M^h&C2{@tT#kv<WD
zP)a-ufadbugeZ#iD=w8>I#|NA(|kP6KT!1|pQPMQ3?zo<*?8ongWm>ITN9n$P<pKa
zYbQ_@kN_uyA2Y$mNs3Pbq@l8%K;s&Ilbk_Z!6cjNLV~N%rtLFF75cpsTY!E~!)pi!
zFe%Zjpp_cpwy`ruP|cgKC7qOz36tr5DKZ*T=8_GT2cVitI#O1aioT)+6IefG8Z8_{
zPy~35LD7?F;EX$0MymA6m=^lIHaXg^&iXo7b6hF-`b1(aU{7quKnE@Js>_WM>P%vW
zHx|KUeqNt=Yt*ayy<;=7_L>?O=&UpempLbn)EG`nsb1Z}haGR7BVVJQ%bhYI*Gtz+
z-#=OU>a+iVdPpwL-}N^)P_I1LJAAV-*aU@gVQmaHHy=E>7kx#>{m}Rqetr00^FIBR
z6@;%hx1z7U{M`J{qwmQ~FQF2^uDl=t$AitKh<^0*YZ(!J4{w?G*;hZn1J_wzT#*R_
zi_8)|=qb!yMAMAnXXK85PVVpU^HY(YML(tqAsIayrsS+V`+*s9o=}?k^s30t&MP7f
z-+lLReQR^`I}F|4MIt2@f<2X-3P6xqgy0rdqQ$qL7iSx+K)G>Jj@H>9c+cM_+UJjl
z&!U&~Go;4x_Q=oEzaMT#D=$Xd5nTe&*0&Gu-~Tp(UaW6^yS_Duwzjsn2HRWT{!cWT
zoz8xbR#=aSjzoWKHY&!I4Z)H!gR30=;In*knPg*lWRB=J%+W0x^zZdIlfl*!C<c6*
zo)c#BWTK#P!Hh*jm)@v8Ry;KtDQ+>eLP=&+<-}e<DEkH3$S9dXfAg<9y^O15c45Pt
zcjBI+ohoSNs7Xs(UVqfI@5`i+MKo;?zF9dghzhx*YlkXDOkahGMOS#@aS?m&%H;qg
zwHGs>RVUP(#TbxQL955tvXgvPA)fUG*!=|3b&h674n;kRPK%se38>g%X7|F(jjr7X
zX+~g>m06JiHKKuo7a#lzwlJhKB){2j9ULwOdP=r2_9^7z@LWe~_YouTp8i2ITPTH8
zmool`QRpZ}TRtt4jHl;G9IcX7MD4cJ&fj|{im&Izx>A=vDPZkE{{vC4$t)D{JL~<#
zWF-0Ols<AjofQQvefT6LzmAUS=Trbd?lKf@Tc#AuL$V?hN`ZPW|B|TZI$SzrP@x#T
zQF4|*d5?b~g)K$D3L+sXzl$Ezk{s3i*Mpa<Yu9do38fgyP*0PEp2ClwG9HN-=S+x#
zbrcwxleDVR;t)SwRjFFcf45le(6rO>GJ3|ysq07aGF+v=*CbKJMo%iOfSI$=(Ck`b
z{MNX^6|v8og)MG>?7=jOBp#Gjh4zYEA|k+rvVBFq*^VZ&u@aoJBDQTiQTeD=BPxSt
zYD8hbd(M1^a62JfEYRo33M>T<NkkZUN;!0R+EG}Fd&y&MH(h^Hus!ivQYEXR#U2MY
z;TR_ze@Yh%!}}=nJQ4e|-^pVMo=*65E}LoYG|3SDSG+jLm_wZEkmf}TBqnRFa|f)w
z0ih-vV~^{47p!+u@vVuXUKo$E7DJ${3ucmlZ0njZ9J3SjC?*t#JbT8fvTa%e;c9T^
zBHj8WK$)w%RQxDjYvu9eGG)>;$3_XCoyb`^E95~z_Zp&Y7JLUcUu{K~OBS_98@OSR
zf7V|(EiyDX7x*Ar=J4nUryo&uz~n{Rx&Z4t>D0+MwUIcPokjokaBFK|ht(9xuGDe%
z>_-7R&gnUD<7p1epiL%B?leWJaN$hx8lR-6F5FTVgW0+HDYHemp6Tm)h@oKg#E!wT
z5%gI9T<3rtd*9ZAbS&v%q$NZ0qJQw_o1!iied2Kx)3p$*`-=j~_1D#gB=?$?A+@X-
z+G<gR)Z)4xWcemc4N@!WT9Ead|1>4&wW8{%Ye7ZK5Q>iawa{#9iw1>D0n4MLy;>8d
zbW&0n`?V-lx3Q}=9W*NzGH(N*Te-+4Fl84BWP4mu6Hi&yFJ-eqH!Pc@Rrw*SIAoTP
z!h*uVT9gxzJHTvkBthprw2E|n>vrtutd(j(tytOWSdT6HnEun*M}2k{!jZ9uBUB_l
zKS##tg8JxfW#VpSk;7_uv14**+29%6im|!lr(|Qdq*r3hv5}&9873+C)Imy@JPS#s
z0Fqv^fp^$T+ndw@Lqtt?W-asbWv%6f757fFE6Y}xQ|G_f<@P_|ZX0lkppEd<XDsls
ze4kAj6tJ{imYtd<)X)WlT{MM32E5u5qC32ZFQQj}lj$M3xK-Rpvs{l!GLBz}(pFyN
z#n6Vie}&X|ffZCq)4uU88?B_2Je_nq=u({|Ca9ZK#Z>?tKbAX+KQa+ihN^ty^$eHg
z<XDutzTCL#`k14+wYGq$oXAjuB3V>jFV2#x?=xys3(&q*OKyO0s;zRBh&Vlaf)z$W
zzeQ43(*OA>-*Rskf%9tUYATf*4kb{GIid?;2A^B{4S?;4q}+!z`jAZEK3z`JA*7pg
zd3gy#1liCgbTfq)xg5-IWm|CLrc^|?x>|;~Df66K{jzaZ0jN9Kne&K9dM`SeRWRs_
zSy_pk59g_mmMvv(CS7Km@*>S+M*=H~?;<^?7=cD=%d2TD3{tFz_X+JJ1&-$9IS*3W
z4WiA4bR+rL!;4<68}PC{e>YT>rnLgISpCHmb+%YJ&V+8C@AoawJ(__Os*_T5<<7{$
z%c_<anon*VRs0X$B=6G*atDl(DnX;ZT(|6npXP?5uV6(E4!1O%i8~@hq-Ozs2k2dZ
zzs-uw^{&ngK->hSd9Q1}2>fDD_e0=8HJA9dFE-Yg!tc|E1nFsD`x&L>u*gn$oCI%*
z=%0MZ_CBE<kGn;~_ATEMOCBu-0ab=A(Bc*FCm0;LoQ>>>QhB#N5aP68&JwG`j*M{v
zA1lv5Pr!2}857!*q{=Q+NWgK5mQHpG38%FW@B{?=!4&$R4wIPxF0v6Og9o2COX79S
zKS6pXv~%a4XH~3B&!^%Z5NenAWVlxEr|KQkZck+WdkH#WWY5H;+RVLX;ip97PoKlv
z;i@n}Pc<tlZHC!awO+?S8LiOW%*oSv?8(B$ThD>9Ox9OQUm(ttOSWSm7a+_<yvMs9
zB-mWEW?K=+HeKl>CFWqE($~2e35;V9FzhS6qk)VL;_+0#x!nkh0amW;TgE_`T|rtE
z&Sk2*1&XWa^S=tK)s#r8+g~g0L&$uQCFAV(R2!rDE~tEE?p_+b+9g_TnH*UGuT<XY
z)+f65AQrfe6w3tbQ{CF9eqlBEsRg99LZjz+^AxGz>xM{ahSA73*adAjNwGEHhjV$R
z+zPgESyfb>ZQAIqHkZYk$-0=xj6Qd=jp0CjW+f~jaGLS8TCx5(%WDY-r0vOBo<36O
z^c^_ryav8S7&Yv8*NZa#v6dBhan;ykvtQafPX&ty23<@WMVm!B$+~ED8#pIaNUqx4
z<~wgY#-dQSf)S+C0|$S{n*?{cr0aMzjI|gr{_)h2R!vTUuVlR=7DUcf2HF#;edz^(
zk!!x%gvy21og)PJf(S0?T4?0hXX~y9L{L*AQ6sSCm6J~6u)v<wx9VP9&5qe0P+T6j
zMnTbU8(o9bMpa>li!D{ldU+}P6lGQZ-K%M0Y@TAC-i-Y%3$E=f8HfyyOA_!DGAyyZ
zPwV8Fxl1S*@Z{ee&om*NIwdJDcJ+{Lm5}Kk2G?}~1j{dyO^#Y@zVNCarV&kf985XS
zy-POhglkpGg!s#-B-Qg-`JBFJcoBftS~g`TSt}t={94@|pKqaA+GYECnUyqAD2vkq
zz#fF4Z5L33|M~UcCC6vbD(XfLjF)FYVHhoMw{bwvpNc*Oi={FQMR`%NZ-yJP3}Q!!
z%LyX9XgE3K7B_rPGrVFRS$+x1s#1(0x=1E7!oe%G;u~gzI(+%+)vMpgPqa-w-uSY7
zj6Kn%VOn!we9m=6`PdE)S1R7M)<O3czL6FUfgB6LV&V0<Y-8r~drvyGU&fjSR9tgr
z3B{0yeOS=UvPdopiLM9uv#`o#egwb!)OVw#)}XJK^^KR}HDIJ$sdiz_zX8kLWbvD?
zUPCm5NG7ZX|Im@TnOgNRNwj$II0fsx*bm9~&dpwlZ*1P{ujEe8KIjSO;6Ph7*?!Nm
zOR}fO_creVYFzXjRI)fqF$C}f*!2Y$VDq2EZ13;7J@@0`M%*W=T{;;eR46CE){nm^
zJvEXhyr`>fW)p!4%_rllXb?@`pE<YnupQm%IBCqbU3an!k_je#1T`52Vn`0SY%<C&
zv(YTEt(G|s7v}+kXG^ADwz4X{u%0qRV&M&DN_K|obTz(R#{Ib1xLt0H;a#|*=4Q8_
z3NF;85Vs(uBfcB67OUW2cBJd`ooK#zCTaHIUI3Q&?CTc%yv<hsP4d!1oR4+Ks%Ydl
z&1&ll&pdoq7wAexR06az@MAmo`9m}-EB?!rIL7NI*zR~N4zE#8!=QRNv)Pb2N`TJ=
zA_4NPKptxJ^Ky1^krY=g0;c}`E)v=fs`Zxw1|V+fDj1qh@)FW&J&87J`ur>d#0lIW
zpBK0WM%&xqlrc^#NCUBB7GHk?NvUFnH36y+czg8w{mt8TXid%g+ImS@@NsHhbUxcX
zho7}n9M=`yjZpgMEE~S3-$b|cdDO)kJh*QeB2Bo$Fu}C4b=PdbAhez9A%|bk?FyM{
z?F)1q6lL<iRmGLUD0J&FUyQB`g+2mm&}Sd)wDO{}&8I=#CN^CZiWTscA>{jm@EdHA
zpB3P(q9_~I2fmK0T+|m0ZA9$Jqpnmwc}$1k1p%jHB!j%~^}rR|#eLiz=w$ocw}XiF
zn@G8YiS+p!ePUd)Q)fLMKTM0JSUT&ts=(!xh=rZs{P=PTI8_i^J%!s%6i&9q8?+0$
z&qK5R;hm39(r;CHZqe@$O^T9UYn~QMRFp%PVhSL8g<`?mxS&~M_D3xcCy=9cv>iKS
z>5Cc5eMUAS4=m`2+Ht$Uv!>v=TfldyN45s!sej`Xe>nL?_t1vMT#a?YqJQ2;O`<aB
zv_@W9Yiss?x%Xyw00B;8&;k+;t~a!)baE4FcDr*&IC!Eey!KX3*y(drW0~Q6q<tK;
zMY5DB)}2cEel}spnX^Q|_m%DInr}_n=<#G@UBkX!JC`w)o(YY^H}9r2>&hV*7FvXr
zOni@>4!P9nuG6GkET*3td)jvPx^c$%5V}qTBM?3~wQ(WOjV$CPqsP3(#j`^6rp}C8
zfy|IIt#&w!F>Pl2x+w;fEkx!5)_`br(><t*TATTwBOs7FDV074z*YjO&Z|Q=ZL!Pf
zcw<eBa7dSLIb3(XR`3?u9-fQW?D4?h(&V5z>fpid)X}-$dgDaYJlVtI50PDlGBfhe
z{K)hXAFb^)oUlz>stPUvXcUN!JZcE()rQcR`z{WmMQ<SuS@0~m@7f*NHd&pX26vE@
zb*Iu>M88M_>rYC=H!J<qD{541XTz#ztZGBWMk`O9`lx}T_gf_g9?}DSlKc`XV^H=e
zuCAsj9>S1r`TbcOI%)n}QOo&(?o$IO`K>EUt~(!N7M;zx8;Y|bUY~3v>v8ZN9(c2F
zGPOW}CcV_sPv!MFrs0@~lmg$mcRYDb#yBG3w_1`9xL1Ng-Snt&KO)BbWQ$oYW&XgW
zKu|lcN&eH*%@^6mUz9IC(?2<ikN62|dE2a6`#qMc+AEXI1^6Wj;jh!PA{i+jmk<no
z>;bm!MRy3@v%ivq@Mn7T`+To{-QLo4^kya)M>hTNU3Y9@q<pM6g%DX=f1;!jQ>>sO
zIKin)QfeGwvw<4B&C%j+nq9qjR$50B23id}TMWZY;B7oS#1zAO0U}vqHV59h(9k_M
zf@QcIHN&V`mR<)aH8HgTaB7x*5<V%l5p=q!C}sj*1e4jt3HR^hW=bffw80aav6Rp8
zF?`RGij+TIvH0D6BowbXU)F;{I2CU=Wu*o}oE%GV3V>GfB!L4DeTs%w5#gojBPU9-
zh;|^&Hmq(1<t2Jj&qCqQ{p9)R%V3A$19acP%*tnZ&d^mBjX&*Gwa5^UTUe_oDh%+2
zR(kSSVGDk=O-ACj(Fouf(XIpATyD!8-`snzZ{|*u1+3{l$NgX^3SWiTP7HK}vO+pG
z_k2W5_8HJRPWH8Dp{l1fv#<pl8(7)>erDV7?csB+cKMFr7f!pDHQPm391QoPobwEo
z+Tz&e-RQqGSVA~aMUY{fO2nikfD;R|n@nUBF0F+zby)U0yZNwAAH}C;VZY0z^QNNd
zYBkWC25-queo@mFdfEcr7=l4(!n8Ig%*U^j_mljCVC=RH?<1Q;oU=99a{OTV?PQt!
z{wzJ2ooz?f6@#5egWE4@SrXE#Ykm+L>+8dcqS`K6ckT|zVa$_4#v0k))dbwd+-ujW
z75otW)!o1l33}7771Z!Ve6RZE?iFq=){sV8y}hrD%1`#{(SYF7$$w+i&2wWhuTKqc
zvNm7~)j+Sm#gx|gk5Pzier17&ymiPTA4A)Ne(r#XR+A{*PPC4CPJZ0zM&#ynBJG{z
zc)oDiIAfL>Q!PAp7B=m)xkF2!z0i%fyu!#?fempa?5eCn(o}=o9n(^+GI5VUT5bJ`
z4jY27C6@?_Uq;&^mw2tpT01;{vFhU37nAHc_`iU#{Ck10SjE7Hvg635=h)91B}xnK
z)O8~SdZLd0jwPgVkCz(OOKGnyyjaqR@M64`Ex9+TsbiPYcc-aid#Z0sQ^&p(i@ZGQ
zc2RZ!kx@1WYkFLq6dqCyOiHo|0?-0J_NlZ=0O%>Azou$lIy9JZYJg?&Pl!gXa*Fj!
zG*Kd1M8j9CQI2qPo|RZFX~v2_vmmwRggniU!5n-T&hR*^CvK%FTj@xj!|x#2E5dT7
zrsgUv-7zA|EgAIC@W``uSZ|3?EE_7h$oR|TB$<}yIVf;sRxeY~16bBw@(XDS|K<K}
z%AF<SG>+**vFr&$U^WsZk@Bt(qsEL)%o0lzQ`EA2tgkn&`{NQ86YF9L+={-522SZb
z%!^8b{5q`EU$=v|^%$#(z7H{#HhkKexjEs6<`ecyY_Tx2p>H~w89?@llkECn9=ea5
zbO+`;@b%L5SD)_(G?8^ohrS^)#BU4+a2;J(8-vZw2M_K=Uy;E+H2x(&TMstx-=n{>
zg5>M_5AQ}_efhchpGV)5nO?$O;cGRW{2*G7vWw|By@1p-r%6dRV-YsAVGT#4Bz}G^
zp||fLB>R2#)ei!?BZ{VEH(jDf5X-Gdm16uXnN{cHu!EnUiu5e{F--``=+Q78kMpx1
zNQe8Aw0c5m=F_VpJ3Ft4^nCZ-!}YDr&F?Tt{4NqHu@KWSfZ%ymO}95T@+tWspB2Nj
zpBHBvtU$SOQjXTyAFu?X{q#fh<KeUDCH)MkiIj{{^z`qC+tJF4(RM_aOtkgwg9i^c
zBk0BY=C|vcThZX&_Ta(x=7ax<Mzhn|@6ihD(d0eb1z3-OBYieB?oF{FSW;$SIKm%H
z-6+#L({K3sKIq@;-(7-zna}BS!buMOf|>wBOWvqHl6eJ-FBZ2LsGuY>OL1Z^ghU{j
zL4WYqom<9IGPSTf&O2*Q!EP8ZZD?QA7UI$$=E42LWm3o@+DQ!Gte{P0$FRPuBms96
zB6-P)#d3H_gKf<lNU_sE;J&c&0j)ZrHMf`2=RsNEg4x2G$;6rKX!BQFb~+NNh34^S
zQt9B`O|u8rzO@2N*GfriaGm_zSZfv+rg{fzvFZY!$<=v;$YsB~5y!X*u?&78sy~+v
z(adPWjzSxx+CnSSquVvEZ1&b^@q(ZcwRpjm48b*<$9c!oCL`@{+4*u&FIsb*Q(Fnd
z*|tzs+~_E$>^?Ls*j6pM7&|daXheP96zVRpZZ%o8F!$_ugI{&#(@F`;6>5HH&)bQP
zOrJWU)0^9@3<=&0j(gP&_U&R{9rLQoUF#UsmhV7%h`}OaQCqz(b&M7Z3sz_so4S~O
z2gay2#YO~8?Ysf2dW1xa5qAn)HDd-FgI5>AqxmCQYyG~-$mOMg7`09Tt)HYj^F_BV
z)G5t=2DC-a>9CnLhIM*48wAwDJ&HB^c?qzT_-at3_*Q_9*%ps%$0RamS6CxVNLnlo
zyMtOY@J#DyynvQioYz`w8EV9Qns=0rId7%&g&_2N3F7v(aC3e%&M59~arm6D@~*FH
z+~}p?)=TZTE3K*t*{lEDayJV4u(hUlvMq#a_cE=2tya;>$S=UPi=5VvfKXf+f_ur*
zYWw5xwT|gNQb1(n9H8%*^BfvYeeV?CzR1}2MZ~px6cTgU1_rdx5zOAunRZd^ts~gO
z&dZR<b<a3DhOEyQt{xVu-o*XD81*?6N<GHe>3N3ALBt*HZJsW5Ulv|^;of%Cw=I(W
z!EkANS?ScH^(HKgS_z?MwM7)Q*GEtG%pOR!W;IxOgQ^XGtfd9SSpW5t?fl!mig;c>
z{0|>pvm!VjQZx_7dLjXq{y<ODvA72p8^e^ej1EEOR&Ma-`jWt8feB2s)Dl)NFqUb6
zW*8Vkh5-#Zp()>mv$l9;vO=Nj=?yS1fL*_KCo{0Ua~b)$K4I>bu*?QGhkozClIXa(
z_(ew3cbfnue67}Xp0@d3ELX-BIbSSu+>CYMcLfj5|56`&D5MC40xQX4mYSy}yMg38
zS#b89tZn+8<7tt)rXp*XgNKo-6Y*vQcjXGOVw+$SGEt5#Lk^_>V~IgAxoGqutInfh
z<B`Poegb>tlH>MF6SSZL?0FX?tz68;RW==`ZW}D4g`p0YEYFEa-SNVpR)tikj=D9|
zKAj}na9qPUg?KA;)kA4vgXu7q&I7TGV#$q@vyv%>*`y-p!U+!%k}VaXAs>;{;7l5m
za2hmQu2#Q&W|}YI17E@i+J+Bwi5}<>JaE1A{gW@=(to`lyZ`^)PwM}F|6a}i|H0<q
zi~s-U^#8y6pYG3pm-+KQ91NsC|6mXezTLh**dE;fbpHIC$zW^oF8z*gHwK$cKL2;W
z`1~)*=U+^1&F%kglzxQNc-n`X^;iIw6_47%ii-r5pX4N;fwsgj`}mv?b?hV+l0$UA
z(;~m{n*4Y&^ztGpswkc0v$Jy`Q>0}+zD!Y<BPw5ZF}qNAifELQ`52{>;T6OS=BNqs
zc75hVnCMxNL2+`;0~+uvD7)ClA^EK|>QjYLeeabDGtrPKQ?_}fM}+JX{)hIa^R*fM
z9V^B|p8xY}GgzAcVH7%2zzCS47_AaEQ1z91;q=~#;_G>_uGAF>Pf&Z%|3EZ*K%t98
zg-09eFbqZlni$oZpU#Q`)~!G;V*qkAW&>hHGL%cqd2P|^70_6m=^Cycy@C+=P$Y~6
zMMlY40_Cly**~eSPoo0RJXoe_^aovQ$F$@#CN94oyj)$owk!GYfT|QTK&3zydI~@6
zAh^ya5^)J|Vz#M}ZAM@Q*YE90d>zV(AvcMsqu5RQt%r(~19^#$rsgHirS;v;lGR6C
zcPVG`uNLNzs}4tT+N*bKq=4xz&b}hwY)6yXc&rc=d#;@*UjY^$bn#W4C>V<IG<_U}
zVgM-+L|e>!zGS}q`s~oW$!^AIYm|UfM)swzpK_>>4Nfe-Wh;D_g7~#j0|<-P8X+m%
z5U!0O?E%oO^TW1=Lbj^?f{ew}bOb6vtw$|ER8>}Kl5)&K;*MfMahNjn76ovb{AsZ+
zg<!9;Jq*Ll=L*efbS&Q3Ap09RNoR!#fJx1U-XIL&roQ4uSyeg66JGmKXaVymB9q5T
ztghKZ`Hg|Vq{}6Q1~aAwlRZ{dUlg!f7`XD4CzFsWQM{)+UGvv18d}!sV+x0^@FqsQ
z;)|3>Fi|2X1K_f!SQBj|PG)D(e?8pV8d&8(LZE7ZO!gC%X+;bH^^2%{Hc|0DCUB-Z
zp`<m`HCXy$nwn>{dHW1-WmUw&Q~Ha*+@!!bgu}TXFm2f<BVQ)$h9=CZ{>db>%6MwZ
z7w?9yi(4MN#Nsw@cXcda#xUl7(_@YF)PB@dY!h*SI@j9T`B;twbp497RM0;fk-^0s
zO5D|CxP+>mwSXx2_q}OK?loUD)v{<V@n164;`$xa@=e$kQ?01qFs<Lrf5H6sx?jFl
zZjtI*P^MPiA=R&i)u6U$P`DIhU=4!0ej$y{lTr<9i-VkHY8VFdTw2qQ{FS&4VttWe
zDw~VsBi-2{JPStWxY;V34aV9H`kQe*2asWWX<996B{?<Vd#_lgV@%vqF#~Qg{*YXi
zxPe6L(I^M!JE#gaJ5od=U4F<ay#A_vD4-4NRTI`h3^vnk`#HrpW?f?S!^v@Gu~w=D
zwPKxS$Ntc=kLf?1ebl98AsiWdI6_7A^K)dJE~t;*RwnLN7CEdY$k$G5nF_Dvlp<eP
zPAL4;4#dGYY9p0=w2^{O9i((|wUAT_AZcp^q`kDgNi~8^smbQg;lQR|Ag#5$3GKbI
zAsg<bMH|-ut|==<(SHS7=zo;Cvwi`kt+1KqUbA>PWS@!GuCiOZgd9ypL@$!^%9%%H
zLR6v`@kR9NZ`4N>UfH++iZG4k+AvJ5VvA@MN(8YO+c5X9nHn>&f+}p<H{OM$m8_xT
zFw#Mm$r>sSqX|Mu*iy&-vTPq%?kN7qq)-{F@{Ko;S(cN7QR@1VQ>ja2j^@_dgGw+e
zLuPuj>+oK?n0k?6)G!c$kW;_1s{d_GZYmLR4EF>t@R$Qz&f|E|l;PB4dFz^tiq0J)
zY+@H~x>C(o%FQaklGQ}AgQ2U7u`4Y2*Aw__>d|39J-(E3?X#V!eF!s!-_oy(?4Tj#
zKBUoyWCF&Qa+(ga(`@KU=qIdJ6$DeE1fU-{Jm8dzN-NXRM2mM#`cgz=E;2abF!^3D
zI+;~4%!^rB@#{A!?4qMiFF)l--==w4X0~Uj1sNGB{%CVzpJv$rbv_`8CMnj#8=R(f
z0MqjEyh;b{2e}J`^dtG$!@G5@A4*!ydHSJhfUWht1*?0eFtbI-;u4G}?tZ_&bfX*k
z0ypyZ8+e<IyB%bu_A~)KBaEb*)(pZrs+Je+fAe>V>whQz|2Ikbe&cmsR%{(o<cW>q
z!yFL-e*gc$-MfQ<?*Biy`{2Rm7ytiH?*IR&BC}s^PtECn60MWvl8iP!6j_zZP31p2
zLVzxbXzSsFyWiet5dvH5Tlb=^yW963Y;WHEq!9v}=tj=w@kjUqUCLd70QP0hJpUP$
z-4k--ONLcRk4CdFMjAvQF%Wyu{}K_fsEB|~Ga>*c>$o;q$HfOdM!;UI9x?zbi?lA$
zY0OXlFCA8945-L6paW)+mMuvKrti;o%%=7xkTyiYFN(m|OsG|6w5h!<asu<{b-m<M
z>c`G<5ZFpQFEFxq6s-`kI;#Pbu-F0Mz(066xO7$b^WN@}?ys|Y2Zqv%?ufJrcUZ@I
zq8Fxj0G+MvZAtklxg8PJQl?(uBxsS{!@nKB-hKMF-JkZ<hfAjBuuy08HefB*3z1Gj
zs)rRZrP`Okx*D#b>3)HZ1Y|c@HOHf?UA!3S#;VeK&uC5jEyipN$L$2NpIkUQ5!W`g
z*cFSNj7D%n$CNnHBka{#k<X@2L^w4ewa#coZ0YGj{;C*}#Q=Vm+1Ui{`Q+B$i^?3s
zTIfqH_+REDej6!C*LmfV?BOYF7Vrhpq6<RiJfD$^B6xAqcy8XOvLE3Fxk8zztb0Nb
z79^{gW*DV?LhBc4IU83L1c>%1=OGz{jjy4y48(wF@<c<bA{>MovZ%Sne=S9b2Vo{z
zyQ2)|=*`tM{Rw(ah-0u1GFs!XjC&WeL5>Pe0Kn(SEF@=+c$jRYQzL&TC2(y5InR*K
z>TGFy0}WK+jFiKbqogD60Y7M2@W-Fzk<NOpOPnYOOEE)1b$}BQUSKnnKV&35(G}@k
zq>}OC60w>p(kOfYR(%y@nteL3JT8g0WmPNOP+84RPou|LWe0wqvgi>I5q7w8zg)%e
zjO~nNUd%?$4D`anz<E&XHTLGHp&^9;L#R+bamL$IHgswctJ0<@6)PvTT`+_q3VHmF
zVj^Nc{5u+$FvjV}&@GKVQ;D@#TH^%)29=yJ#wv!IUv@<Ij;O43btkkOIeuKWj{6<2
zo{vXZu|`B7ywSZ0EoH#}5g{w1Bke!NZtaR(#J^N<INFCNG*A^jAiaaxs`bI!0W$1I
zXuxXf00u(Ra7dVdiv;|jSXYFsxWMhy5k~n0#}GdTV31q*-zmB193#p2U-PK39Le;^
z;Ud9LpC02>&m8q*9B>F?&cD+!W;?ptA6x$dM^+G7>YxPV#7+PoZ!<?t!mpin1T_(%
zl(mmql0(U(WboIWfAbSry{o`2$bVn@|LnbKciYC2F#LY@uRu78NhTDv*v=wFP83^C
zbVinaBst4t`*I)>k}xI#4ggwKZv5ZhTDlwEKsOdjcAOje%-o1%uhrGnwbw{rS@})J
z7X|%Fg3N<+^O-atZ%nj;l<$!@P69upBvRT7smKTCKyt=gGc8&{ETPzHU>`CR$Het#
zvePAB`ZFJ2Pu9R&Z?bHHd84V3)l>KSTx4DVotE9QH}6r@6X*T59Dxv@`r}`1dkZMZ
z66Ey3#S9lyJN;+F?lw8q2eSVh1@oyt4z6eQX=?xR?rm&5DA<2C?mxJ#|NNKPe-b|a
zTdU81q}4}U?kZc4K!980&c`zDh%>R9bi|LskYh15<h^eV3?JFR0G#%IbQbqkP(y*e
zV!;f%%4iohXQZzcU*S;9^6;SDOk|eD!Mi3y)L+u@A#Qm0=0uTO9_&Ad|9cUI?}B*x
zk@&yO2lq<+--CO%{y%>i|F_`dzvch_Bl$mZxvTg;fdIGs-^b$r#F^OnKk=iR|I2&d
z@_&j;$<v~=<&6aPFU1>myMHr&$ol^O8b*`&GQBAlp!WU$YP0bEZ*JcE`u6?*tKR=h
zb^Nz1z<(qQkl*hrE+9vPTSnkxF#`F?*m;5ccQ-p=jB(2m+yF<A--Q1-roj6C^Ksu;
z4UoF{pRezIRe1l`zrMG5`~Lqm^*^)=Kj8YFOr+3*Kn7<f^dhAHa7G}%Cd3SUdp~Ce
z9(e2PTN@9y?tlAHnE}ZQ{MQd(Vt3B1k3~EA_~;oIWRm>n;zfo9yQteFID@}M>31UO
zdq+pljz)*ic27=@_J2I?4yYcKtKHN6<Kz9qpGMpo8gEuK{`KgYYC8I5_u$1Ibhua1
zVgC?X?LUTA_xszt#Z~K~#XIC&?Ec~L$?m~{bA6)!?&0IS<-LB+A~6s#rCQ_xMkNeM
z3f7(ZQ8-^rML9OAv%n7@d644MHx$?6n4LQ55{XgJXVBZ=R-X4%Ru<$YSO8Q&tG`eo
zco&QpSupYZGxS(Re^jdV;$6T^@lJyP`EqZb#N&VpyWus|f~oN%4g<Ilo<{){*3f3o
zhtsOe;U;ha#P;C@dv5UvCU}sS>J|L`29wiI-uf`cxpLz?1D=vW6ru+)^gRu{WI+q&
z-H0&>m;+^hL?}xKSh)`D0~ha9tdPKi6(~e@08Ta#qhm4tZu%C>{@+o|6FRi)bf_XE
z+`kUohADi;KZ(o~tl{K?y3_dqu8zMt36mc>0KuIOejLF^_;fYL?r@z~nN8}f8RL{<
zP59^U)^ITo#mdNmnjpkQ8Rg`Dbj2{jOAk=ZmmyuF<v!>XaVV8gXzphh(xrPWN`hc_
z54s2A42Uy(M+4yH@yI%Pl%?Sdb8NySI6Tdj82bsdNx23H?thU;H*6;Nx;r@?^sO{;
zW6}geNQiG%$$}rNax~yCl<^gjSG*C3fpRlQFuHsJyL9edS@N`7a6(_z@2Nr4?39p3
zW32+#D&ky}gglcleUpzmGYMhExHG&XOv22uRjLtm50?`$?jy-EW|R#dU4+vKlQse*
z^q}k|F+e5>CxIw?li+%?tD*9q^v6hj@rMkCSAOYQoTT!UWT=)xCXF(h;rK$5MsI$B
z=S}m<CrCXBi)f-8)3v#{%Z^ui{YtYoSU6wmWqQJG4FNN+mg&oa<}y76+z1Bc{-rQd
z`!957Y9c*_aBP*ZX?BM%fGESXqh#}v;41;AwILVDBk_H&EN%15)IkTG)<TC1`8r?t
zrL48wl2LU>yYwZ$>Yomt{kVH@{IWaJIH+gGCxmB*kM@qcuV2D~M|6pJ+&;TP-=z;l
z*VVF1^DjcGr~3}#NH{J~6S@q*Z4B#!iEVKgjWL2FGH?|zH|Au4uaVCpX2J|W)D#Y)
zpzX8B3y>KfsG6%XR0y8$LX9%zs$1lNzyJRGmjm|M-gqtl+Qh$x!{O_GfrO#R5GP(W
zn?9g2z_cs&L;-Tb5jbH~Gf<g@cMnF)XJi5#{=xZ8gL8k%AvdWur|E{SKW(<VXgK+>
zch9@obl~OsDvPG8jB5K)n1wLZAAv+G#d2xPln4W|*P%=N%Yj6UcUnlf-bTSD&EuMK
zBr^GLLG10pJ?Jy<!NtnzE3-8OButz21nh7{yK1SZ^Mjdw5ydqs;rJtvr$~ZO2qd_j
z6#olspXcqu!V53E6bm!~h9m<@1<5=ukB<4lQQGm+1-$`h0EH_<(m~loXGTPDA3W7~
z(-7XFkcFx84Irl+TV2j8zOJdaNTnb&hWDRND~T^TV|rgkCvuI#_!4jOrJqd9^7FPB
zNzw7?i{lgT@Y#vRt>D}aZm2O~6ESJTXGvmdZ$jkkE&Ps!!9f)ESqk)~@t6hMo>o^9
ze#8Rt{UV*yW6kuUejI#;@hFr~4EKFTx$Lzz@aq|Hw#E3p9>%K3XGlT3Kj36{mth)c
ziR36xS!tium=4&IWXFt<l4i&uD0(H$s*zkj#t`v@MQVY*jJ87jWh_MInj&t1t}Uj(
zp{NTW3^qJ2KDuy23=KgPz~ES*Ayl<kwcyyHoyusjs6ts+%{sNDxgY_;dyWHF!>Kqb
zA(?$hxY=6P42lDBsnkV~Ujz1|zrFOrjLkY$rZYr&;@Sr5qI9+_q>(cxL9&=8ZUv|i
z@Jbl?Il>U<5w55wa@tYnf!Bq_b^Erc%SPN84^v8L%jsm3#G1LTlpuv!;H@o<I8x`r
zpjzrg?axJY?Xxt5rhsC&ebVO$6_Oe7ES8TYP94u+dQ3fPJYW@nY|9;@2Ge0OOPS74
z!tvFOQdAtPT{L^Gu+P@j?$8Eq85Gql|J(IULDlx3d-pdsi~b+?Ht*fW|9nFE-~Qo-
z9_xMhR2)E-@c+mSSGn(pD)U~O?oDdZ4`Y(b{mhmqgl!hU$4*cxNdsg}vH%!$5_wE@
zKc}U@AxV9XukETBrGu>Wj5zdLRq>6fiW_8?v-qAE8e~(KslR`m4UQ(zztE#a_?!6j
ze~Ws#y3BJ`Y3Ibef`{L3qy?>1Hi0aUGQ5Wf4iY_xIICGW3x+m%4kVoz1^Zxzs1I_$
zTYV&HDZ`W^Z{Q<ZM#2o(_dwjXF^Ydl=*uyMtl&&3)>6ks`25?`14DDh`BloPKFgW3
zZbT<ml~-UX{f**M#cwaW$nbHd^)8Y&N8vBKZcW&ift|M5I7@}K^GQX%3@TklCIU2V
zDobM58l2Dk+kBB;5c~EsQb|BBUKFqAXz%33(V?#2JrjlJWSl&n_akwhz2bVR>%w8<
zQd$(TsCaI!sldbEBoN(z6!i!RFSa~qKZ3(k5M}}Wdwm_$st$($TV;lc551c)sh@B|
zr=+%^`hF9x+^)1^pLI*?FDl!85KynuFjZJUU;Ggq(>wGCn19}GsZeB|I$I856YH8G
z0IlTGPf$ULE9rK(D=N51Wc@`so%|}g_WC3N<4De$GHROP4u5#ro$+ZCXgjZ>PF;Tf
z7N@)`!5g1hQ=eH++<oe()(RMV^PTivNzUaF0j@+K49jzR*_{ONlqSJsB<zq_W(6qR
z#`R9{rV+n}CW=h}Q{j`*b%UAIZY4ORcEqcMhLOBUy$Rg)Gb&m$5>6CCZ_-`EY+S_r
z_6IWNc7)$Kv?xW=iu)RA4`=u9auf^{QG=8IHeM}kI&qJAeMmNdWv5$vLu7(43sSH?
zG}W|Pf6H4Uw!zkzzVx^0^=qz+?51MNu|I{1uL~_9{=HEcB&XF)07^8Qzjc+p5yvCC
zz7&7Bt0W2aU#Wfbl6wW(DMtFIoPCL{tk~QN`#VnT4)yFLK<SrYdFdP-&oqY9Ow80R
zl`W)W1it-caSUj#XF}_1x%;rW`D5|aus%z~4t-=wTFmEhl4;2xPXm~4Ae?0;Av0RR
zyLm81yC{fNXtx4MBrOh0Ryz>e7AZ?<kz8;g(_axFI>%$?gKYtWill@Mx^Lg9sOBeA
z;Av(2@)U`-OR-Ww2RT9&wb58Sk+3oq<J8sYq(-(4hLeg~Y9Hb{y04^>`;_h{IoVbX
z)b%4~^=um>QMlW0!mMg|<b;%XJge#;YK6RNh8Yy7LS^;24|NRgqp-rXa-41<acw70
zUFkx*x)D2Cs^FU8<l5^7<TB?OyE4p^;B6Q$Qech6S#<kNYt=QrUxh@Rx94m-mi)5&
z%Pgs!m0tJf5$UBnJDq{otzFA!*er(TdFJ5GGH6jx2nv`{mBClAmiD~H{ac*+hu~BV
zsS!zfZ_(icpaa3Sj0VK;g8ZI8RD1~i<!YWbWkt*^)HN(gI$~F`>yP)3Mj#iPse$gH
z(&|W0$lzUeU0kTW_9BC}^VC!oNff_iZhzACd(${Nr|Rfrv7R(o(Mq~FEo5@9Skrc0
z4Rke{AvmdTD{G(YD=7`vgz3+vseC9DsN|=bYh^5T34!6SxlK8xLQ6>P7*!Inx?6YZ
ziw?N&ok^T)A5-6T5pk1FiLd5m&EMr-ckQLW`p53-|65=E_Vt%*m4y}l&Zl2LK>g<G
ziKf7@kAX*ZOA*#hpY5BZccPHrR7FvepS9;>kWRFi1qlYdT=?jW8zkxS{8|+pMXL5&
zH2GxEq?S*Vhqf%OX@C`<q^jT+C#rBlNr~++!c+pjd|k;@$@h}V!rWOB@XZZ8?`u=}
z{4=7s26%5VKnTNQ&K6Uy>M}o1{7I1Zn}u|VgwrCP>uoun%ShcMEbzMRm#w~N=GDiu
zI3CGCuoXoC?pS+lH<{Jzv7H%h%LB7v*&bh!Knej-{#k<rw$VPikn9+?FwcW~wsPZ<
zbZ`}hC!;u5IRqzs>t})e;7C@Ut9#SStu)SpI<kes+iAsZ_Ol2?2I#CW0AI#tRwDBt
zP__xVDomBhs9@7_3t)VqcGQ7dLDxtUlcq8q<EtywNSqA&InAuJ)0c3vRBg)Y{S^h5
z)#qn5$$g?wR-5^NfR@2JYOeZV^B2)Hd=qexA>Zr)UGkhVtIRQ!bjGJZ)i9z4fv<`r
z8j+U+Ir?cZ_7}w*4$?)wlpUqk)pz61c9EcwRy<RWf%>o^o9)9dt)$J8yWlg6OSi+p
zleT5E+OMralUe*Wu+wsw8U*qbR^>=oXwO$zxEQW14fNk0I_K<D;1}z0<-<|L2e&V>
z^6Dn;cvTNyMwb#w5QK@4*h^n`4c6n$R!rA<<y3=j>?n8_rdirEAKudYQn5LDTPb2Y
zn3&d0E43>G+T|g1<kaNy(9|8=^p%$AkLI9h_t2Kz<J14e2RFDh2dq5M4feJo-p}Pn
zTHtkHJ&4@s@?)4|mU0vagw=>N>_7}%tZ-tKLD8AP?G_$IbU9(hhPXhd_o30i2H+A3
z<N$Ak2znCJ@<nMNmK-V_H-?JmVG%)Ki{jYYGDD6z9#sV$H;(l-UI7WFTxe(+6K)9s
zH-o=#i@^LR)&IMx1h6&vUmtAVE5`qBtl$6YHvadouK)KBkNVYa!Kaqr^=4yzRfbDF
z!uK}X_QOTn3e0L3W2@&2bi}oma@XpSvEr0x%(+}A^0jUBX|+1l7G3(mf<<*Vbya(>
zY~QG~X{dzAeU~4&eU_IlYf9y8#e8i%Nc*Yd>rWiFpO$JFUUy;|#5uJC%9NNz%f?%Z
z(keJd+5o1IinLMx9b5qeUZDwf?8lZU4~J*OEl+A!zLgi^3<$}CU#mcKF-ORxnH4a?
z7}OAttRhgQVE1u=CY)8-%#LgfZP<@s&)0<>Q@vHpj%Ed54PxDKER{?mu+wxgoB7EV
z{)x%pqF{=DMj)M~_=k8n@XtxWQZJB3hlfZv;U{UNx{D_h{}jKiYF~*zR~Jd>8d1Ed
z*xH|mtJ+7T+=2XFeUK}d&}aLY6VVo5nr{E^hGVw}Cl9XrVzqe)?B|1*&~`!&*L86|
z`b#h<+~0vg4XqE&r(kzpM4INP!pbXv;<D-Ld?0X-c819N-pk2X-`mm*r<Uw%F(o!6
zhz^l&+!(HV+B5?OfIne3cCw1*;0LiIm`*fCx?n6l4g!Pc>w7E-h-~EnCEJ_=P`zoG
zl1`9vagwbD2flGT%0D!t=JgV2N}rH48<By0M}C6kTI`u6!?A(2XxQ{i8fTwU1!!2j
zUC>C!mUI>L(EE*<#wvT%jztu!31=+WrK;VpX_>KD<jhZjjEvGC0UF+Qnr!h6%8das
zpEz-mkNA1Yb9Bfr`VPM#Vwek=WN`dS?=XfswWCRnX~8|0Ym)07uQn@m2;H`T3Novw
zouE#Kwh%qC_;trId;P&UyydG_tznB~;luPXv)2dy6~Ll<md(4BK*V6><VxsjW|($O
zY>p@kRSKy)0CNTBlt4iWIkbR**BB8r#{qORf$hbW%a>cY2qFw`^cPdgg@qJxTI2Iw
zyLMba%cZ|x7WHm=G0kIe>f!uBFGd?`rO8izLxJ<JB&tf#^($oC{P?8+nYZ6=M-CdE
zlZ4fWJtgNksI(7)QQHTWr74J3vJV3ion`z`P_g>MRo*>~r(vI2Un;$}U2U_NTV`>6
zN)HQc?g4BjF|wK+Z|J2UZ^UOkZ5jQ7vAg5ZZ(+7TzO9$`iE$?Ab_#}k%U~rgOEZKU
zu3LGZLB3JltEWP&Dp=HS?Z|(z{Z|x}|2Xzv@BY2}8zuYi*AH&(zkikecfrU1Pq+VS
zx8Oh9{)^}B!OAg<>xA+x-dch`k|kK+*oU$N-`anRe#E#fOc1<mcHk)1BY%XZvHPE>
zGcK=Ix-Fm&p+PQat;RQ8ED82C$<?%?^ystWTLtfbs)E-ptuW<5*x51X)hk5CvPdG9
zOCj-6&giVYN?t{OzKUKYf8zf|Yn=fl0xpXhw_?Py{Qs|EG>I?Mn-T$P`Tu(liv0gq
z>tEmU|9=(#f2ofDpDqHJ7vVo!3J|BR=yQ5234BaRAV;-ZVc=F6_`3@OMPh=#+_L?*
zY`@9&CpW<PC%3%+P4fSO^v4N&d~|R#7Jxebf8*;C|G&9;tN;J_{J(Hm@Dvg#T09TN
zQ^^2%!m(A84Ok?=zdp8D@D*{2IP*`Kh3TVJgcO&9i$LBh6oI_=?bf}oKc-0VKo<$9
zAYGVBegSoE%xqFsIUvPv<?%XY2FU=L0z+%`xRn=fLSA@Klou5IM~H@|xFAnX$O<J!
z`4`?vuOi9Dh`hg*=M6EtyC-`>jMzW?spJ!&<xWz`ZD`NHPjdM$IqSByBXW9iB)kfO
zck?NhGV2b}C#{^5fI3pXEa5jgn#c2Ac_>SEBXUbfdenR1Z4A84KDj0(W2;Y++>Ae&
zJb?pRB(NyWV_u%pBcOdOE-4jBbr#X?Vm=2(X^fqZ9t|iNByzUmD_o7U9*xD1rA?l+
z5<Up-7?YKhaAE~U0U$FC+1j#p*|uU(;rK<56OdVZ3~|8O6!z);`R5%w%xg#Z18`o9
zVvE0lbIxJ{YR#g0eXOTuaUE(fLK43Xfpy)(3&{B0ufZcx{jP_Z8>w#~`)W}MoL|UY
zMW|*!s)XVsJUa`B{*%kKnrg}M%e$qSnp7r|em?NuTmJl$=KtXh1*G>UL2^^xKehQE
z?tgW^$p5c@_4Td(|1aSGnHvEVSY;frs{ij?gT+72LSXLvH*bQ-`z}pSKTWm2c?oWc
z$DjGp!k?}M(b_mpU`6v8{`6n@2XxN%)zq!Tfc4=9wVwp@B*1f-aC_}@7+Lkuch=Ut
zwJ*H4;cUxG1FD<`{7mMbdhq{g7SDI?d+9}ZmR*LE>|*Es7Ih-uSoNTcXvLFWCkAlh
z-yQW1!swF_3&AH7()z>;DlNVyTT&xv(d!%qr;BjPQl!#%{*P?e)t;}6Yqk-0njaPF
zkATaO#tlwwMiPpqL?ba3K6;{lXjuU2;Lmt4o$Wh@M8ynv$YNA{`oF;#*wxDmcwoJ&
zc;Q|85k)n~QujiI$xFaN(s-tq_tTq-#SA?qyNUd+0A?JU6aL~Lya)mhaE+^HxO8~n
zr&p_}+Ev467k-{gd>V7XZ(IzHK|j)xsV*^PJj7afZ{u(R^5La_l}b(jP+WDAu}yG`
zrAR);lZZ?DK7g`+ehz{hX+wu{2))e|YoFsP5a||kL{Bc^CxF3)(*=YkID*_9=CnJD
z7tsXZwVTf(McynJUqm5*g%WMy&cYd$42*(HZI}UO%~A?>01w5R>6^k;ss-dHM^p$d
zMgm{rM#r2OG5|!q^3XCutB~7QJ#l&5bhsq_{FG^Dd#U)-q=uT5t)aRuVc$`7?ce|Y
zH)0Bia#;wJq-Y>{>dz6a6xJfD2-Ie(0cdhX$Sh(|ib;aeQbz)Ai|oN{-IHJ&&0q~$
zbY+7jD!i2>?&em-)7aOv=DmOaUI#45O7Z|eE-fy6cQWxn%EwH0Ge8(cSUjMG2^_|-
zxH!X<BPztwZ%lK<7f1!gNYw+-L6Q{Z_2M~OeEK^5B5O?u@I+c52|zR~8gI(~_Bny9
zTw<Q;K1@}bzX4f@>c`4E&-^Q_1r*Q143WQwCw&=Cr}$-f9>qzX@z4Da9wT^ju+p>G
zS9y_Q%=)piB%o{P^RCh~9*021@tGq-CcSVxeEndQuN8-S6I^K*E&rY>VU>|WNTvAh
zxsZ8rI(3<zbqp1d80eVc&eNSITo#p-i%J7lYhC)&H~Gk8g4jq--|MdUgS#uIs5V$R
z<zO78t~l*)ml823C4_}Gz|~C7^YqJllYuJtT$i8P()p#nC@~C$J}D@<QZkq50cYv0
zAPGmD#uu?kCk9syNkNegXjy^H@tB>nA`&K3_D+so>~WfY(f$$;kVk`4e6o9RyeDqb
z5;#|Yf`n;NZzr~4B1P#KSK>E${s-IXSxRw>V%-f}OSMn@X1n@y@h-`S=NY{_4x*38
zTX>=Hw8&!4ABT#Drt@GNo`u20(~<yxA*=6*M|a>!hBV9+N%VnA&gL08FQd-^{)}&b
zR}CT)Y7>t*z6hv-&o1=N>3zzHmjlJK8>BJk4+p?rjDvY5Urv13Qm;oegpBbx2Pe=_
zIl+PX1>OsJB`y(8v7%V}4H&&)<EQJAqy+g~F)y5jxCCj}5g@&J!dW=%d{re})(NVP
z&UueQA#yWeb>6IGwUF7b=`43lXM^tA%YXT+e_-XUwNTZ&u+3S{qpgo?O({%CrSEc9
zX$vKk1?*u>=Rw8^j0N+Q+V`Dj%TTObs_1sPp86z?x|x)U5bNm74MtVNr*gUsZu#%^
z_vAb^>S8^2Npn8ase6?&Jm&@#<-nH#U{kG5u6rSB$%yt)6evmao0DH_k?=n!MZAov
z7eap`M86O4Ml`=+^b8d2O0BLPX2{PUh5TT(Ch)w%CF`Llm&Po??)zx*1KhQBx8_v?
z-l>Njjq7MbH1nylpqs_W#;~yD7pt&o)IM&b5z74*OnfGETky^ZJivycB1AG!ngzVt
zq*yQ?0D8aHtcr#(dK<q9CQ_j!egNVIJfwQV2#Ik*@lLV!p!B>VJ(#oH8jFUsb2$t#
z*Gq9(`1~N|^FFIb@RRctf7sPiof{63S~U*%p+;(mVYB4JhjTkF>nwZ+!;ua}K6tp*
zyxda>^i*2e7m6F}{8W|!5m^F1KQ@HKB6<_Wmr717Rs>>1%I^;XW#HXKvl=XINj4B~
z6>>XQm3IYcd=pmDQ3t^G<~L*_-xp-3x?5dZ0Ye9qcL4N8i!?|`iV`xIS?$O&U@id(
zh!^OFH7Q|<Olb7gBoy#T>bQFyi%R>>_Yd!UMEl>5sDr;r<6o`)@BaG6=6ccoxA9=(
z*8ca=?SF)R0s}|}Ad3u1KR-Xu4KN^`kmHfiRimT$hlmoY)_4CM!-=%Z^_M#ivW}cA
zGtVAB+X6B8+>004e39vIDm<oi)Z=(I!}CNh?!3<|odj>8Imo8akV7sOiKt#hwnfIP
zL#p;d7{#h|DNsvfbNL|}VM~_ZHQ#>G$TVdGKhE4#j>$dr5DT%4O<%+4;Vqti6wgL-
z79Oq-H}A;eH!V#>XcaomuTjxxBZ-&c6IqU)f}SIP9*%Oy#dR$@3SG-avv{(Y2GlBw
zZ4Gkkx85dilq1&&7o1fYV#ul@Slt(?xGKP|$3pvqne)O-s;=g7nuZ8dK<_y@_6iQs
z#&m*kkI+c`{8|sZV0b>n8$aMH{0JDMQ#i}A(MAOA6XS_3gjPE@+bra2nHJE|q?*wO
zT`ei}Lw3x6qP&I1Z$+>eN2=*09MXmmSXLGxE-T?8oM#xMB!21X_FfwNNkVZWlhGIb
zB}8p~eZ9LdZ;=I;u9F%XTB^YTM=RGMd1DyL6(&aWk$PD<M36)xqNm`a2)<I*CP6q;
zJ|l;0K_@qYuJ<;37>_gN0Hl?|$vf;Bu~@h4Smwe-y*$~VV4RR&tHg7;Ln9LRUaj?E
zeg<9dqDrk8^i`^R#vdoa>EgU-BjH8fh0#_YB2bNCa-f)g(TC5Dp6(u4+>HylQep6_
ztmbAZL1#j^NtnPA;eS!_p#fai>%&2gFDI-&gg+F;Q94rWp;V+WR^R*cPY-k5!Qa{!
z;|uk<Us;(g@xwIWZFa`wRf2Six+9Uo5juuQrx#$9Y@|>K1YEMv_l6me337d5L7!R?
zlE{jNFl>PI;40tyTZT^&iP%?ll?ubjpDa%42%Iu(Nc3gUytToC)y^002CV^xnf;Q$
zpCW4|$1LJT;R4aN^YgZ}%fs|~n**<-I3fzb;{(#rES+1yIP4DLr|z~JpE@|$8V=BD
zfi=kGJU)KT6HnrRUpg9c*y%e;cmDR<Z;})B-=LO;SzGoaqX=omld8PpoWqd0S<ItM
z&sKMc^A5Y-+SA?t-t#)}xx90)>#a&AsngYg6(ork`;aW6M?67K&NL8D|6OV`5Yx(M
z*Ra)E2nP)Bge3gtx>vOE0GWEaKn#`n)Xy+Xm5ulSqI?(XCjiT@_zviWw5hiYIu}4F
zU;!CWW_~ul=ylhIUwm%`V)s?L`YP?cy8N;a|AAKh)i2S)k{1gXOu=A<h6*fYMzw{?
zMlUyt*}nA!t5%z@t-va+9v0UBUaWNTWgnJF|6S{v1v6=#o^zpWEKyV2r~;=&hEpQ4
zCyKTTeJt&u1sypl4K!I0N68WoyW(~Fm9?o6SsYMpP@q#^&Et@18k;IJ=`$jNx<#aM
zwn)Vg$VDO-Ll<KhybFfz2ZQe{5(%_pWgtiazsF`67GTx8;BBqx9Z^uCc5vAT?4PrS
zJI2LvVP-$GJu1*V18xf-^S^Nz(F@VTFZ+XTSErhEnjvoKJa~uRW+a2eQPus!7Y+~U
zGzcPnAP{+Q9n&i>oB$8WhHU>dej5z+03DoYhpyXa`%hk_Uv^%tyy`uA^3$t+2R`lW
z!2k4soH+`5JFcg*y;wXpbG1?TZrJVgi3-@OhP*<^Z*_<Sbk@SOTi{U?(Bbvf?j~<}
zpw6V?`T-CxnWMmW(IX}ny{Pb=U|%EBT#);KLLKHWvNV{U4NF%;aH#pqtX=M<FUlkJ
z{6m{04Bo1>XbA=Qa?m5?d=2HY#9XP!DiCTV$>p7)chv;9+#Y}%)e!0n%EXKhI(#la
z=o(bCW_I?2q+qg&r<4GhpG0H0F8<oZlJy-qa>p#`(iNgRH4@M)Nb`jbQkpOJDogpc
zj(}p;jz#I;?5h(6dGgx!rD&&_0d#|*!5oOFJSC`^KdvB#<8AOW-&*gk^se@;UR$~>
zPJ@+;nro7Lp@nHzQSw$nbpWf>7wZyl4ZB~HFLh_sN-xx0*1hnPw?UfiM``w$1RVG<
z0wQx35@li83Jq)8nU$<-$UfqOB1I&dFUrcKUr~;}7-(slkc7z`*uN-aqBG&CC}2@o
z?5!*ZbU^0}jFKF7`z7*=aRFhp&=)|9I0NyX4wv@=BFN+YqrFEb&yIc{9q&EgJ=%po
zQGkN+w{3=bS{{zlcV+lj=vX)bchLpyXet*pa1U|DRT=cNbY`&UgQ%$faSG?~X6fwu
zv>l-aX|yeii$Vi3YA2}-2zNtV6F0=aDjK#W!8byVZ;CV*$aI~)Wju}3K-|0Ss(99R
zYPzB49WCIA?f~GzKZ1_r`T18lhGInrz&&Pyj}KB-kD!ZUocO@x7C6=~yx!VdKUvFW
z^R--GzWU;L?`Tb=0$crM@922{*<ruZZ^M#5=?hI&C%LEJo+?wIrxmpm8H|*-Y_Tp|
zNl_=XwDuLTGe)kBRDUR{E~9-|Z7z7IfgA=+4Z6B^YfF>UNr62HGC!QA4rdT{I`K8{
zlakZAh|6MSKiy9?JM(c{%K4M7to%=YL%VAT)3q#K1Ed+Iad%*copA$yhks9>K7Q<K
zTe@(KI_Q^6cJTVeF2mu_Yos{Oletx$gZ;TC^lht?HpTf@uh#y21^@p1SHJi2U+@V(
zy#BI}#_!$`{=2f)b&?57$sam^(=h7xYs7!yuA(aefWe0AH4UQT*LTW665-5j^x2O1
z(y=6dQM#3B2t<9A?ytK?hx>;=ZFyoZ9w|qw_UgzNAo0fY=SXgZ)fI1rCtf%jIo}7W
zVu_-4>qZo%ih!DhWJJvOnCl2>+-{{>!*UY$>?d)r$w}O6a1!a_?2|ePUXOVa_pW&o
zV$7x|0dHhcsIZt9)#Wa$L`Tn#k*V#7RGFP>?Q*R}%jsh#=R)shOwiwLuEthMb<J4@
zL6a`#_$r~Nr?6c}T}r3I)$L=N)l3Il%KO)~<W#g5s%v1Cs^N<@tIf#3d1P}?vgncp
zXU(wS6jRV>$`JG_MAZo%HgHG*C6e^vAULxjW+HT5OOUfpU{Yc93zK#gZ5vx6|1P%2
zhUfdf+Wz=ynICV^Tv%xt)Qy7MZfkBCObu*x%Ew><l;&-(`+WE0=N;F}0k1}WiMFs6
ze66|}2B->aRt?utS<8{w#a!MQ);6wtSqHTv6l`uh^#?GznHmo4*ce;?hZohQ)ULtA
zZSz3AAVq_r=s}Jx{#fX+lT5d4vb{4H<u*=M%&K2H+qUK$#hmJQ;gS6D8UI#F_EqX#
z+;<+ARGtVUlw$i^B1(kH;M6z4l_VBj@f+IVVk}a<62Da6z4o>=A0z!Ahn*z-9IY22
z{C^rGk3%2tSeGtXw;rV&IEKrZ1I?bpD*8*0(nW(tclrJja<+P-dipz9ES0N&J@A12
ze8BnCP<CDI+L&L;GQ5&dtE(Wzq-~z~h_5Wj&A_9$3)ot4atKK2t**jCa2>BZZ3{-$
zj=0kqGIyTzo7a3aj4AKmzegUydfW7NPxgO%y2tJZR$qhg3`hcE+Kwc+sD}Y)6}Sd!
zB2gJXbgl0N^R%Zv>7?*(+cZ5iSf^;bABi637;E%6>5b7x&e2v>W?e1y$zQ9D;%lYm
z?l>M!)u4ny$5$zEe_LD0OhjpPSCg~uz|*@p>9FiPdxHvQ*?(T>z7$_Uk@&)%3!`i~
zHd(6TX)u=gBDNbZTprD})}8AO#c_%~$ibU$K`p0Xx|NuYzBFaJu!5IGd!EeJb$)(@
z&RzU$zbaXbyo+5yUZx-e_cZ2D9dil$hsP(o2M430XU|S{UUd{qUUejR3kJ*%xgD4-
z|McEbeA_hjRwv;!?c8x_smt7Rjz$I#UHDq?q3)~Jj-ReUcg2zZ{CvdX3TvBp$g#X@
z4O|wdg<QdSRtj3K^01ms>@s}|zD{G+h3w)^z-lsoc3qQ|32Zfqg;T_x+W17*BSs4W
zo?x!oDLZUnNjrU)sA6B5ds$KJ{f`*5tNGnfel7<k(F|C+Pkb&2vw{yZ0SDvdg$@=r
zM78q@ful~&z=43Z;Q2ab8LebZR)%Etk~%GXs;O?A)C}vcGpX<?DCKwx(iAN-4uc7W
z7QlUqWQ_|cp~?Qh)}AN+Z0LD=7)3A^)q-}P?*p?vJH;R&90=2HP$Hp}3r~16o>v7M
zU(MOWH}X1w$ZVbI)PxO_`wr!FLq{pfRAmfm+J?}rK;+-hTisCB3R8Nlb-duUqXtp!
z)}cn+t}OeF3{}FsEKSv~@VWdQv*}$By<W^IA@x<f0POR}Sfpe+oZTk}Mjog6T7<gT
zc2`SF_!s({y*hsRudUZ#_P6N6<lo=C@2iO`>?JF+0P)F@isSW~Ov7PBGb=~MQobX9
z9#T+F5BT@K)dSQTQ!G|drMJ%)%9Gd>kSntk)p_Y0FgZKxbv|F++)P10{e03H=>C-h
zF@{x(X`%rR*>9E{L(6u7k189X6N-124#|s@GBwJ}lG6ueLX|@>_6|7`Uh+LMRSrJd
zSaxP{e&Nl@zY>3y4s2;2f+E!46az@963Lf{^V;YnK`lt;0F^^fd!`Hnk#Plg5Cxa`
z3+8jg6aZHkIbD~?L+l~b_Jg}#M9pl^TFN&?9z;%3KP}Rzu^C%s%?JWSm}sWHAWR34
zE{HB+CeR)*d>Q8xU6*6b0zXoXFfH4aqP;%3|548Rev3qXxr>z5iM`J7T95<9v$CZi
zZoHmzWK0NUdL4Bnn-A}9U|FA%wD=jcZ_czbmn06=`yV-c*KKUcw}#1V<cF8*uSKK~
zsyjBy-jCDC<n&y(TID?o<j6Lpw`o=P3D2(;;ca&YED3P>^ZCHrSl_&FcQaQEu#M|1
z_~+#wdD`Oyr%UdEO)WNtf?B*#G(bbv)Bw1kzzojv!(fG-Xl?g3#oI!c1rwaXQ^I~V
zJwl@Iy*YXH@TV<rb)&>s^|S$Yy!F1lh5~MWWeU`6Du}bYrbf}wX+1+NFwJ`i8>FF|
z9H`6TvYVf6)!R}1{tJ+3A&gsFrJbv+{<j$w{@(fjMU5XBQUBrde{5j+-+RUUA76iU
zoB#hW%KxEZz<@atQTB;4DNsC-C^!30t_)nbC*I~aUw!*vL!|TgW)&8-aewRn#@6QM
z$1e?ROS?gNr{oE`(rpm;bezE&+$lGHdwTF33ydc2CPvl{xfssBPfw~$f5jjiVinf!
z#D|Ao=AY*tMKXoG&-IEVrqTL20a}lpR381jdw95a@MQmBPgH3=d?wY7@ceD`x0hLm
zJo&Kb#M6_%Yz)_B-gzwesWr(xp+N@Vmw9^CWZ|N`thV~iz6*>ZO+SS-shp*vIsg^z
zRc=TPK?bKg+WYMUCcWpJl<WvnU4)ZR!CA~#Aq%*&A8q}Fk9H4FMyU56J>NY-v)I79
zZ=Y7BnLv9*>c3O-lCKp-J2sh+r{ND>G=1`9|MkO{ck;5w<Q|j{SzZk3%p_H$PzlVj
z2Ry92TJ>-~+<m$S3;4>4m)7yah^{~z3=)%kT|Y^>0Qm?lLT&eP{Nm};-J{=OmT%h4
zvY2M!s>mi(JJHh@2PgXn`-gkleBU;hFG${U=5(<s!k~E)XYn|mHr(OQ&yMjrY^=AL
zPaIb3`Q*vTNjKb+`mibb>KX|0bYEPA%_b9(681V1o&5eB@o{srVzNjQGCDSYLP>7U
zgD9XvDO8{OR0On(I@hA|?{X`{<=m@W4y8u)jLK}X5T1zh4YkyhO{U&^`uybg(b3*d
zd%xlI_p3nvofJ0tLAvnqC2IK$K6!EY=mcI8?Lm3aeoowZ%LxVj+5D<<HVI7u;w2}|
zJtD=VUoSnWeA`uN_m(Tr;QUR4Yh@<8AnaD9Vu*kM|3kGdL{{@4`$8*YGi*dZ_r)4d
zMo*r-I7F<!S9J*`C8IzZ!TdyvS&*P{r1`CX4p$zhs<>d^VG@9F{7`aw*ExXE@yYJV
z{-YfH_bRT|cj(iyNT%k@MB>!69B1_%@HN>(MaDUCe3&)9e?RUX@4YxW5XA4^g9a#p
zscksDud217GpPxdu}P_1D*iMYEt1fi!*(X|YF>P|Vregq_66@HAAoxmcQj3>I!sV=
zOtaJ41a@?;0`yvFjvL3v2RN;`rT_KAswTHQ&EK088NT?E?2C^i7tO3Txn*I!VMbQ2
z3zY=p_&f^#;3`XNcUFEnfCD%<e%T%A3p$op0#D_*i(!<~2aiXiv<`XsuRzs4whF<w
zWsYy4%yFpzlO|%zqDx=YSTQ(}US98wWZC8wiqeeYPKt9KE1^!mg;MJ=U@nhk5oejC
zCbP?Fev$eVX>sjtu-i;2Kc3)#1a4~iBCfLzG2A|kR-Q7%s=Hjij$Wh1sc4?c+C)lJ
zlj0cw%UBL{ZUdB4wH}zcc0o)*KhR=$aK}QPOo4@vL8#~yo6OLDgNq_=Bg`ml)Z|)?
zwV*99$aB2cuP01NWX&ViE$IohThw#d>lp8isFnQoNJ^d$)3x}(&<K>tka`NI6Lb}v
z!qQcG?Q`?@Uf(iQX;Y3o5qe;58Dud!B?pd(((*bAfYCGD8!px*Q%o}@j<@sBo(1RE
z3y!2_<kZNEC{Jjpy@bP!*ZEw0@i|$EmGFU;WahAK97=GEvSs?Y#ksv!bLL$3VO(4j
zIea0*WN6S@O)7Lx&PhKfrA&*B6xB=4kzYi<NT(`%WI3cAwOY+*({)QXw+Epsat`=Z
zXf||pQS;GtO_6hoeSw8?iqGL-KL;elsXp(t+KN!$G~SKS7&V`xq$zSv^{Akf5{^@+
zltC454<~mM;#jV)YPDa~<22ta3tjkHeU7~E=i;08$5}b;F;Bxa;6LXnKJOH@R@Yns
zv)8pKrK_+cLJbUk6R%_01t5FhbP+UNhv)0Gp3seFaJV2KnJO&t`m@X;z}|dHO@ZW`
zR&e78Qr1$9c^!b?q|s`H#sv+Mo4Rqn<Ila%rL_Ec{^*+8m8IsdBvVZ$Z$}*s*}Z;V
z)Dw6@tso~vY-%&1p~iAfsTnGyl&NiyUSXSpYpI3Qow;Q#ozKNzKvtGL^`gqEf{N1Z
z?R?JH7^XB8YVAn}s;!*UJx7%oY!LnfQ_U7BT`8d)YxfrF+A8OKN<oGSN}5jEL`zz-
zCbJhbKh9}S9C{^5MkuR<khR)F`1tt1eVxRMM3^IABvS<iuU0w*=#R008mfZe1g_BW
zJmK{Cte)x)Y*92d3FmUkOrjcLF-iOAV{i4{6z-Q&w99n>1(^dw`hS~Ek7=5o({J4H
zrk1?)tMp58+B==zODszG<*On8x8KoSt3`X!*q*35jAZp$vo$*-OL?xSi>UI4meSvR
zkzVwg2}A?0OPsJH<W{IXB-Nk{U!~Rd-SIP)1a5_d2Et~&<0+9>IW}w;%SWXgjV$`W
zKJmXjJ&mE^#wR*pjy}xj=gNgA+KEu>3FaKI`Is&N>s*$q0kZ~bZbpFC)|JcY{kAc>
z&6isg)6}ACV|QDfxLA;;-O|q#Hv1UPv)8D&S5^JvX6IA72J#$$)`%Q@g=i1=Uf;LS
zkQ9hg7VmOMM^)-jsgSvQ*OT8#?xN=kB(yHklB37aHCEDRQ_sV%VsWQMP1T>A0axY0
zRrX;UEbbzO-W7rLf}F;)Im~k!PEmO$6jJa#oiXdQcSM$)Tw&HNY1w?8%;@?!a{^;v
zT`}fkf>v{JCGU8@>QHC}mK!1u!>>9i-*qrAqG|XBt^pec@&)$ai|P!L51YgkoA6d~
ziZ^hyb!Yf%m|f7Bq&276AlbsFb>6k-vV30L;-n6Bae;*9$$-mi`8B~*WE3?l@T35}
ztu3jGO#yKVTM!EIT$`Tep)#>IUnJ+OUuW+|)?)i-8Tq17Ds9~&Q%?=^m8|gCGRdx0
zJ6xpr#om4Qy+NBrlzHdjTQsjS<JtSZUmdjs|0VOE_)NL#kw*qd0ROuXg9a-2N$t3h
zHMtQcETVlHu7}eW_fNUTsfaS1juC`)N4qkXK)!#ye3iV4UVllUd|kqSJ^caItiaHx
zi!ck)ITmgb@t>!`dB`EEvCL+kfGEWNV|n5VT=8fcL|pPTokz6%f!Fa~Wk&3gIDj2b
zrbMA;>jQldy*-7N!qx9?TYx}zFqFIfS-glSL65crO8T0YkvGAl;@^XJ^C|LxomWvu
zz=dMrDWb;0#mjZGlCrRH<Risrdx9O@%`o4*C}W|IF!XRG&5Iyc(E#GAJ>M{%qBun%
z#b~c!HwIE&#Ahl;s?v+f_8tj@7>ZbVQM9aga?H|DHzCQHiP@|il$qyDwv>q)&ddSi
z*O=%V%@O8L<|)F1e}>_6XB0lCWryn~U0ZUHqKmfh&9?9YoGn3*rOS;Y6yB*ObLXnU
z9ng_pUc}h*0*@t)u@D1^>sXBeHSA+TL^D8AkO6dA$BS_~je(})31Zv)-iQFMv$^G#
z64YUik(A}F`RYs}Zj;Wd@!4W@=es@$&&~qW2#RFR#f-vwMQ-%l7QhWSy51PiKc(s<
zo^t9D*@ST#cox-7;<D2Qov#dSmp4XU8AN4yRq`y<II8xEi(=Srj{BPIMpu|7<}7xU
zjY|c*sR;@g#*I<m$}Fw?#dqH3g9qh0)3doo&#~peTfJ|S&#5Km#z$GpN+3hQ*%-JX
zbKacAjbkMBJIX6E16%XOb6WT_yg7)~?3!L|X2p7QYc$S|*ZJ;y*j&e{OK7*js-#(t
zEGsmMJ>g^nT2w`ktS8{kplV=P32CfwIM%yVNk(CX)OsYi&4_HtlX$$CAxWT2T4-Se
z&gg9zFH&XuM`yZO48$WG)8%(1A{SSdMpY!SRVIrphE3j}$S*s|7JN?CdcYQnja+eQ
zlz!KQke6N74X54LFO|;FS&F{CCvtk|ab?YhQ4oGydJLgD#9PgmQR?e=UUgvXR~;{i
z#xXL_@WuY|v(<0DdGPJ(27LehLxc08K`_0YR0eAU6|>r`)Nc(LyAJX}Q3?at{P@He
ztF%fOp4x7`OT)bV<>lq@@*epYZmzFyU`*KY_#&A3tFpi<_e{gBl)gWR8L1spPO^!b
z*35l1Y`7<{cG#srHGG#&UUeSc@xH_7@uAU)5)FR0Mn6CU;YaWgOE+F*vuO&PZRk&-
z2TFv-Y|^XYb${6TZcTQ)(<$c1BXlqHJU<5#A57q?`Kb-Z1-5i?L3-PV-4ZN|gW-m8
zIYu`F7vI+|uwZtqUSXlJLhOz$8+pw<_A?xM-OfYXXf-Ef8D4UeuqDfQ0Jx&X)d4wm
zpW%eqaoK*~yPo$Q$moP94G@Ee!iCCCCP>nBT6q}oJHg#sW?W1v-08N#liG37`c%1K
zY_Qadd1UvJ)d893(rzc{3sA9q`D|b+!6Rsj4|4Ni2Z$VAw_lB3-gj%FXX}lyVYlJ>
z*#Msww@|Y>AT(9j5BEv>5q3&48?Zo1snmIuV7?eqn-spM?}S1HdiI?H-A~dt2c;bm
z?veQ|HD<<9GP5srFhw;gvjtKKg;ba3be&R2$0Hm|x?H#7Gy88Z*I(P2T&<1rDlZM}
ztc~heh&$bLaY|HW!CzKkOP;udhm6c2-x+3dsIzg2$*)FmGnVwh`5n%C=LDP|IvD`e
zNYAAZUput5@~Jhb3uPjkaG_Wd-&|MEj&Pj<dVSWA3Rsb<u2YU>wM527D74JsbrT_O
z@dx)~Apz}O#HoBW_!|SO@YnLwP`Cw_evZe=`CvJRuuc8G#X{__yz8ZR4N$)d#~bNb
zpyM%Y-@5h*HODBwlWsQx<K5(8ER?~i>5;wH9=1}OH>MNv-Y-ijp2+?LCN-LRqv(lD
zGnd6nP>^odPC?XoR#KsU&1r)As^;?NUGbL7Pp*3|pAZEtQ&i3esFIC4c8{K{`cf^D
zP+ThO9Po3yYgJfo@$FI(+72P30e%&eT?{>Mcbdi?FpO_RLK7-Jr1>hR1qTYLMh;ZK
zsLcc|ezpatH9}ugt+ayE49IWCpJ_QsD?^)vJC5k9TyDf5%f}#TFue2=v`+#QALr$;
zk~daB3MdZ$5-|SC3%wCQicOb5>4cO@+CcWdW~K_w(2xhm6?T^^CmpNL57cz!DrkW1
zdOV~7<TNiCTdtmQJw>Pp>?tL@*Y&V8kZ>U3u#K7(5Vg`<PzGXh<n2~DaJEt1(z2Dm
z8oHHJ=}L!dJ^A#~Z{*cxuD+QT-vE8CJG(CQMSzg?06>zQ$7zqVS{5f}p|YX~b8#i|
z$~BEyDnn7mri(Rbpw!?|qkjpTX%L&?U+pm0!>%f)V1;poH4Jh*b1t%}*+>HzrOv({
zuquc62!PV&F9XS3+!6q)SNZC!V%R{xdTkID;%I7XgVrvtk$p)P7RlJPsKti8@7-qF
zn!etawX3}j*0Mm9-pW<jCRfM4`n<d<e5xQ()f(J^*Q}iq%gZ&b(9K4K?DSd=b`!==
ziZF5#d74P4@J&~?{c)kox`r}vTlFXY1dEE@2wabk58Q8OI&B42TAqWS5mB*~98LQ(
z5Q>j7L>u?5QqC3usx$&U?p$;5<q4Xx8x4#KTJCGpHZNG%ott1`3xRJfpM-{5Q9JsV
zRia@7U1)h(MfG|+WoU6@PW5NME&{13gN;$>F86xLqM#a|coeY%cbrijtM!5Rqlebl
z22<(u!MQGA#hPuuiPF?Ymn#&!E~<O;)VGET6Or|r0c>gD)M=FKDWf@(Mg`p)uGq&i
zB`FIr2ST6GET)ws(^vBpcI4|xF*-_v;?L*P5GyprR^=1<+)KFFXVHAPWqM9zgo9~7
zo^L%Z*TX>MHDq6*evQT|KaUl;gMnx0u*FoUpticT-K?5=X+5=VEv6js=bxU?c36ME
z0l~<~rBK7rBT)HH^50lPSsZ})T6`+=`Q-;*As;^HbdTy@D61x&4ZmfNc=fLYzjEgr
zdf>F=5Vdsg8o;#B2bUSD7J9kxx*Pzjh2QI-W2K1s!2nqsLwkahQ^uV6dXfN287lMA
zn<;#TjtH)|qQq0d-wnP0(Q&)EYrT#C;i;`9XhdQmHy>?}axN9c!3Fg_Ekl8sQuBE4
z2u^YI{Alkd3}NE+)TM7@*l?h(Gb-;8-i)3-guv+%?9h<A<Bw$*E2%F#C|`3+;@JK+
zn+l`s&u`W_Bd|#MhUwB`m}s2kTtj)Im@q}MVlMMCVX0kgkw4`&8ca(NvMo?_sdp@B
z>aC#z)85TSQXH`ua<#x0S1whX^#1*OjV2Jyzge$*cU@lfO|flRomdq*HXPHrTobIW
zsSP-mF<!#WjqVf>__!Q)oCf1Xf+11kH$j$qQ~wIS?7>p{7|SKIf9BVMxok6j%R&rt
z4EZ#!h})0I`CQavt2IT($3<BCz8ufr2PFP%v};TK-L}ul8z*}$zc+)8QH(rt)AlA$
zb5YM4eqRF~yTI4rekkl`hM}J0abud|e<?{!Np|tR_mmRA+w!`yb-_XE!`@i6uGcTs
za+|$t)}Hm;@`t~y&9>C~fvMT=weG|7`uiXen)M?+G|q9EU8XyEjoU)JCnY&h$S3qF
zl&2EID9N<luf2f-JP1F!s!xPry@YUhFd^JOT07T$b=*eX??$dVHE>+J*<w_I?WJO`
zvU}@`n=57VC7@D9Nrkq%$a~unRc)<dtBi4Sl;-*l!&v*-4#Uw})Dv2T(W21{X<0`l
z4&MY(H?)WLCaNxt?Z=t>QK<Co5~=9YMu<2dDLZAl&1v)R{H-xFM<c7tDk7B3_O~of
zwYmXirthO8|F!ru3s3KB>82Ugydzm*#pgob-f@P`izkU6rDw?TAMG8V^wpJ68gW!>
z=c$J(3p40<qq*ist`O&MAu>=#m<okLQ5S9w>=wpumc5ax22Carrkm?Y4d%Gb1qWkt
zn}<FpCwg&ofUmjmUiB%)Ull_vI=TJ~#3jK*Sm*{!-FbB&IAW0aWeBXnX`m!YflM3)
z0O*Ffv@F;ZQKiqJ$H_&gWKK#MMFP0hq6VbMdxm)i&ZfaT`59Ib&gN{Sabqal2$2Tl
z1lbR5Wlk>sM*stWhP>yg>xoWRKRKkWL)dML;~)G~fyedou8g_RalJ0hr0mibjh*n2
z1_NwX7fM)YlUvFPKh)XFisRrjC_Y)UU1doYV;Lwo4$;hN6xyM@U#h8&cvS=^A2WZg
z8aS>sd2Wum&=FAUJRPFCZr;)JM+3aoZ^MbO$NES>rtx_=hDYa8B+v5`EUqDk#D^(o
zSLn&X@vYZZB*2_GrGdh=rLmj5Ev5u!E~#iXcM{M&Dy@hWT`k4c(q$RdrS|M%|CUt8
zHG68D9#I-OOB>vEInH(iho98tw^W!@+-vbgzmc9Vzu&3~6Wr@idUd#Fm9VshV(#oz
z`7<pK@|P<i{68MG8yfQ8B3gFjZRfZa=rz)=+I?O=Ii0Hmvdth_8m5Y=%fVzJzJZoJ
zt()fTx+jW-<zM7=yHBsEgx_Uw>fpeG>~V1BFQyq<Kc(^q=te>AtR*4oWth=rama6D
zWFu)Pi;uTXcy)R$i^REzKqcsFjr#U(d6_zSa<1h5njN3Ds6ZKH*jcsXUrPjBawpmd
z`KC%MZDaE&-{MoCk#EeeCX7#(V|L%-!Z6p!0j^lxw6#5=Nyd=tK4UGOu%^$KL#HMh
zS5X^*0(BB0(zzt`r&x!SGPS9St(56a@FvTcMx;<;_x8vi;DQtbM_b_<tT8jLH(1P9
z!9#QZ8)BO)wIdc2oA(1p$5zK$HfyZMS2>>mGBB|=tCBNLm8S<cu6n9C*Cra4rH4fi
z-=sdLdTwl9mcYaMxaUDq#UtzPn&PqIgC1b+Pmw%dWC0bF(Fqau^S}jPmwEo|Cb;J|
zZfM0?LzQlkVp`2rxosViYf1|)>Q}t{qehui8gu7TA!BFMt9a;EoU<h-3L0SHukF8%
zV^(}f<E^w7WtJMb4nURZ3>qr;ZMN}iIQEnmTf4}Hoc;}yPnQP}_QK@=)x$DYLU5p5
z$)se){O@NUi|CT$5EjScyau<F_m=XOwbXzgbt;bK6etZ!r?l`YyQa#eJkfULH1FNI
znX0;0*M8JE087MQeVPiQkMP{pV&)PU*$&lOqF7V(dcOc@K$pK<nY8xvyHUt;*dK@y
z;OK(#Azs5dv%D=U{635$=rTIWI>e~tpsvI7+`Np;0UYh5WTTITK{29J8u2G0{zzyX
zuASwF*4HfEe4{wyn^;$M3Kx53B|VFhT*G#IO}@+eeTF7RJ6-qy?9KI98?{*X6KK)0
z);hHE$<x?>YsS`kOiq48KGzbfwp+PeRpxCd4|!d(CJVxeQccY%8z<IM?M31`uW3du
zH+>VH{42uCzKWoU7B`=_tO-doGMdSyd?K056l9vCm<nnjEaMM1fM)e&2SF&OWLc<C
z2qUAW8DJnK(`tsaWn9|DaeFH?JiL@NR@FmU^-9qoAM=rNCu8&EVwQQW2ndbXOFfSn
zA_e`~ux4*{Sq#fyt<2EYI*eu04j+F@6I^9#xvDS;y<<%#pC&+R8IfdmUSj?m34|^5
zlG%;j>O~c}o#%ZOxm~fia3)H>rCgv5uT?jd#@)R7Ti}hUlI(1eX6Wh}M&s#X5>Oqu
zw;}s0oa5s(k{+Veo^y7@u!igcs0C80EKUY;+|xzoMKN>^#&1-e%#g^`%%23qDvjhE
zmlKM+$iAIvkVz*AX`L3Er*$O3dGKyoI+th7ea=JnRwO~9o#sCL6|bq$qm83UIbET(
zP(`Dzxs!l$93+BgE^fQ!s2Y2gPas|Xd3*sL7ryRJCZ4ak$|-LbbTmvch}G@r+a?mE
zGTy_87byiHxk5vzp~PHiDc5{=n!C#TlSwItNh~-IBI$Ooqcb<j4NS<^_Iz6I22)t)
zcknwY<ysf#E>R(OK(V6&Jh&zf7A9E6i$?fgz09K<t8;s{cP_dq$0FhGL7{POpQ0P~
zCu;9YR9awrIj-S3vG7$e2{zIK+9kfFA!k{e)wBG1du4boe?m4)-@cyd)3WdKsaUwj
zT2gKj#Re2zqplzaYK}vH4ec+J>2_4JHqF=4u4*@{;AyPfsgFg6ZMlM5ZpMoF>8bei
zE#GZpY`c~|u-4}A0Ubb=+Hpf8&1d=Oe=Ds2uzZk$NfSn=vh@dlZmTA@zNa;-75qpg
z1Zrqevls5hEnUS(L=+XUS{%nzmeN;>PA`rQ+5`(p0R+RfeCdTF+;ljai-J7!QOi=U
zEBq1Gdh4ds#+p&_`2ABHC~x>NtauPz?jwyH8b0g;c~g&M>vzB1q)Gx<?om@Iq0Q*k
z(zAw<vURVTvkGmgNnZY`HcYtGw=(H`RqK!VXqG3hc{Hu7Ej^kwS@A7#8I?2S<irsN
z?J9$c7so)C3W8tj0#pq)AS%{#Tf&RDa-NUDNf_R@<>(3dJC>HG#Fwqo)+o7FbABOD
zVUc3RoxiMQ5d`BU_14x%*Go-R{*f{K2RNAv|E*+oQjBxVgRPe$RYbKN{wVw^=S5b?
z6Wey*8o7u&NYQl#{RTB`%ZOg*5wXMqmr;o2YrNx9hBk!GQhF}6^hP?Z;x#<dvzqAs
z@S0&w+S=F^-r}a;CgEb)<Wyx)S0n}tZR<vMsxa6(?^7K{)ECe)q7Umt;jS>)b^B#D
z-DD!V#O}+|jNQsO>t-u&bl}2dN?{p5nN+$PJn8Ww&ElDc2USvAx#9q$OctwxkVDVg
zH-8LMd$K+LN9I;RHOt62@C=BdgebH36w%UXDAvpWt94>g(}woNH3|w2phClarsgZ4
z`dtIppAn#e_=>Gp`I3;SaumD^(=6>35u=Qc|F;N}U=(9=6KcFB8xQ9f^RD|E6mD2;
zJw5A<BLd~uIx(;K?W&J0cQ-lTnS}68!;50u5<J~*)Jx&2qwCS7f0ZiirfdbqS(V}R
zmYj(0M!}`o(hWA~Q5!g8;tSl$Q4-9j{y6A$hv@t>vX%mEYX8<tUi7O4%`n~1{U^+Y
zjBp`qT~|qgB^HAfoC(35kp;q;gKtKg)m(2qc0qpSEqj{mcufyz>6N$^kRzX1%y!H8
zh>B}oan)NWEtUb&jR2??ICW}?`kQTe#?|E(zp1CgyhtnPW>ij{8K)wT9F_{&@q%~r
zX*>yf&v#FL9v$yJ-#ywrd3H2_TM&-mCF*tMb->Y#;#OKNOk+$GfhVC=>xm_!CBeZq
zfc%g5kM<tHjKAlTW8L(8?dCsV=RhWbi6^|r`axPI!dx=j!HH3cNk*!kUK!lTVvc8<
zQ2suddruS~Sp=wXh7NK-PAhm0ph~VNs+0y=Bvd6S3xQ)|f3*vrRotgRKsxI-9*cml
z+0%Fuo`u1rt=HlRJI_StmTr87zLidyA!Y%WP=Ejb-To{8L&~wbG5mJ8zD9i9qj)w0
z6vJ2L#^%^qU;pZ>``-Tt$MALGzwqzg`d9bv@t>k0{CDHQhIe~7AK~A3-@{4YA!77}
z2!~({7<gm;13gZG@I>r}ddK6IKR=fqAgOnsh|&Y`(+?=0oX5!(94Kbey2H{NGsy4{
zC!z2BMRozS3I82u;koyt|K<(Qq3_c4^aohfFbcAV#fCotS@V7je6+)THx8!L_}pwe
zj^|fNcz%%q7Jd8e*Q=ZB>)(>o?Jf<HQln`&4x*G+gUY?FwY7K-UvR?KI5}Sv4brvK
zbh0Ww;Fa(W;j#Vk__24u-_d9?@fZAi^vm&<x3WLk^0a&8ZGQ9B{crDkxRlj(SkkxN
z`d3>IzTVo{_<!DHakluwTM^5O-UtdNmWA*eiv6t#7_KP*rj%Tg{yl-m(evN>;gtM{
z`In<$8lahSeYkN4>9;)QL&_FQ@-_#~0DYZIiPA%>vT!F@OpDa_Bq0W8;%@QV(}U-J
zk_L%rBG+&Lj}yx60?ATBp-WN;Aevz%!i(UFgdUYI69wjI$T0U4QJGL;>CVHvA?02c
z*t&LS<)?#ZKkgnJ!`q=F_(=4ehD8fV<r-mGz&1>Rbex29k*LzOAgxuCm0<Jgm85{e
z*?5tqoX27|1GJN?D*{Hg#f6AAm5Weg+n2CQgXYi>YMj#UnVEhley*HRj9{M+TdKK)
zU$_s5jb{w()Hp*5!?PhG`;!@Poxrew)clt2r4AST{BwMXP|LHg8iNPvmT0$X@zEdq
z(<xw|vHHU(8gLCu`YjZN98hP|QBP?cb-Z+O3Y_M^y9~1n^xg}A5KZKez$S|UF-I5b
z#CQm1VG!j6V1<rL;i7&kB&$ek?xlfPhW?<h?ej{BAQ8YKVBdWlq(5}+JcpI<C5s3a
zsMtT5R7Grq_Lf~Fa%$4nDUiay9`llY1$C|iz`xNB`yO!rX*?GDr4i$~DDim)BTt3J
zf;Wuf!<~W_Z!DiKB5l08tzsjgGKD5%wzMKA-!Cp@DsCJpEGhJhwuBL3soE8Ss{j{u
zZU(X(1?fD-7l%=P=y@+vv3nRB9Z(1<=vo6t=qbK67@|!Is|RI%wm@w0P_Ig}@m$ZI
zKHWWhJn9|4c=TxR`1sE!yZZ+(j`scpspe#V_n?2rq4e~=7>OpZ4nIoyaIfM8<rSw(
zlcpeKz?b--WX^Ho2zCOJojPQuQg8~HQ2ow>M5uKgL-dp?SezgIt?9#3kg!vQvY1Dc
zjd_^sE=W_-?dO2O>qcLylsXH1i?G2gz$8Hf=StvT6nj6PJUu`Oig5sQswF^tg4J{$
zj6nn$dow?IvzX`W*#{~e<8k7m77>WZaNw||3(Vz=sLTjs;t9XQ`8|C6?67;{J$rHT
z{Kbj4d-(gw&-;fzeI|D0Wx>0Q_7g9%`644C1VU}G`-|f}TK;E*r_>40R0u~#rg;ij
zI)y!YKV@$ONG^j@dho<q0vi+sIRIcIX-tcV;>&^eCJ5#pNTkUXZyf!whz?BskQZ!Q
z-QI8eu*)M5!S_D%c3HQ%z<?xRdl)1s9MuzCT#Cu*$2_Ry5GFAJZ)+>@!&G=M^#{Be
zKCiqb_mpW<wf4h*I?pP&#4V4c!0R%ikLdNN<3#z5(JAB|)&Q)ndH??RzvcVh>pN3y
zGQ5N-iOEF(%nRq&6ewG)y-+B}Dv8ud!HlGsC8L*^3VKCnaPZ!~s9ue|#75``$@iEu
zi%X|WUqOM5LK35sf?|JBTw=aBo#HJJ-^xp2H3dl+uBcb>u2_6USX~oVxumYqo5E!z
z#Z!>vY)wskXFWgqQtrWGCs*vY*J>cwnm(&ulmUpUWue}>M4UQ{=nard#j|_=BS+|V
z?C#OJVq1$&lq&0%%iON8`K{O^DGiaXmXUwSqqw2lWXcZ=yG7{j+%4cN7Jw3>tT3AD
zQJb(mrKqPR_h68LBnADF>jQQ$b-ioe`}gm40(Ter6**PehAS<%VuvL~{D1WMYZmln
zFyLB8EvP%3wno#pw%`>z2PQU-J_=qG*JphML+$-J6CI>@QTh7(Njuv!GEi4OB(@b5
z@X=QglPw)ED_qSAIHdWk#8X(na1i?wW!6wIpp&S1`WGSJphNNO^Cv@pgm1JQv;H+N
zoWQ{Gp4ULSv}d`{W&n5gZV!KLEOaQf03UNA6k%Trb&7vI)OalgH~OWg%YB_k2m77=
zM*@9uzhbQ=xJ$&@5zbSx)2NF!L+(_9wn>2Mj>&l@WyY#}DCkd>T_o}1{DOcZ+Ikb9
z;jA*7#xW&`Aa5%ck7RFbm<EAR!%9UH>0#B?a2zpZ%LVD36*ic%1<3sqcq;b1p72Kl
z$&4JffLaRWiro=QO$>b7Vv5F2GRYe@%s3LBT_;B`_6GKGa3W}%pjlZ8yR#rUm)fd$
zT7$3JW-dXP1oR}pC{XrMy@B9FSUUE?03OIB8mjV$JQvmtilcEsgtBm`RwUl?g2*ot
z?c!c<G@^K&QQzs{CT#H&*Xuw>i174cmBV9T+$8+r3<SGH5?o(CDPi*p9gbGWb3z5#
zY|hdvb22I5uhRKJ*%=B2m}wA4SxYek{4a`s8VHA8SL#i>6@tPDdeRKdS(xIkw@@V(
zsd2n6{->MQ3L{PlDVhpKQ;6W;c_wq%(htU{+crsWGQYW1BT@vDj#JS4jL)_N|F(u1
zi>d$eg3y13Zo!U+&K<n2x!qF_+x>g}J^9lQyWXFF;uVAo&%X@3)%%zZ4Sst!n|7D3
zRJwA8{zS&W>oj&D*hM}j9b^9;d`r&Ertk(7%~7SzRm<=tCf)8=*|ayV8c%<XSL<*^
zE5d~@?&?GOFT3;rdnx^-(jE^<AnO#v23OQ0M52!z3i?0xGr!k&Wv$e@p?i^LpIbqT
zo72HiH3W2!KG!b4KRZ@9vhmjIKANf->TYgVzB3)-Pvnl^tU8`Q#mjP~2r=8Rpq<k%
zu*>MmW3^j3P1$W$I;ri@JK`Q~w;hS?t>#Ghot9p3yXx>nTcKX6sydb1V!cwY?YjKe
zP1IWQLv_yUS~OAX<TF+u4TPye5keCUqlB5-fr6oMDxu%1)2-hSy4mAft7fo+nUIcK
zw7v3t{=%|}PP}*TdgU+ehnN$!LI<L3F{eiXy2jr(ESboS1xmsPu_k!Cra@%?`JuN_
zm&V_TYtLvrfeyT6LIxUNSbXadf)y~OrSVYGY~N&%ZX8XoybbiTO#E?1Mn3P+P2jBd
z!dIcA8ztX2k6X?$?oCRCnCh`vTTXQ!Q~96w`e8hc(?D`t4FbSQ60PC<;579}Q@jxV
z;I#5;jgl7{DE}eZTbllI9|jm}<`RAy`4U}M<T1DV*V|yEGN{Rf^(T2OQLD*O7T%k*
z`dqB8OgC^E`jXoohklbj!eMCB)gJ|b8>r!Ka&9{d7;z5lH3k%&FPJSxUC=r8X=pOl
z^fc0C1v-mXnl_}+oi;Ioc~j5pCBYf62+<hCLMHvZ0*^gk3L`KcU{d7hTnu20fZtmO
zC?eF`IJ_C$(O|4wSo1C7C$-#Llj{dJxrzfuMUPc6BCItfYf#bFW;NT8m}xz7<HWTC
zufL^_bMH_G$<+Ku*=MiDv!QfP51noe_D~OXsSVH78@Mg{UR_qr=D1K4+}h$ovxl!Z
zOZ|!d98Bkqqr8BhSm)l#H^p**oS>ODAP2pXBcjE-EzYw^D$Mf6?Xi)ZPnFP!HQ`pO
zW^GR>Y{bF@X9X4-p<x<oz5mPNf8yvy!+&bxf4<t>eDI(c|FeE?{WkvRuZ#b|WUEMW
zD9c^$WRG8wIY>B@W7eF%G#uz8p82Ww%MkzXQT)#PZXCb+A)EwbXgq|w_xFw;;(O?A
zezW=QSKo^8p|4gqzwtKjZLNR1wfXf&3m+1Gp%W})PU$DOhxXa*vN60rT=&hWBN1NQ
zD&)w5n4<sX1>lAsd0|Ap;e>%?0}4~BXTZ8gt>4y`ANkX(KZ0XArbigJ+^5+&s6ZsW
zKqvZVhh_;B7`r?0Hh_rBrX#)W^W8`Pz5CN16-pUBKic~VL&sn4uKquN^^eyt;eX)I
z_0?}jufObSL)4D2_AgXERnLTqrB|>1SnE>Y%o-bnh20$PXMDNkZNSQh>-0ZIkNCqR
zcq{+Av3YOv-hKW*`p)Mjr~IG!bfbFDzw8|y@8f5&=vR|3d*5%p8p413U%+2t`>(%z
zHTk0deck?xqg8-FZz`b>N-+HP+i&o!CTuF72gw=wifpa+tM~Hw*{_EO&vqZH>3dBM
zfS&Abzqi_ZIfPS|`|a27wlrVGc8#`jQg!l$ZE^n2<2r<VHMC)*wX?CZQj1zF#O&YR
z1fB-CxckpBHCjT>1@q|wBOs`x$*Onw%zJV87|!+4v!lIZZ};Hf*{^$#U7O>=e);zD
zZLPj$95lZIbbPf|{K~!k!thoAXl+asbSzmOrWlkFta{A;tF>M?=QEqogT8xHg$3Am
zr8lbF7Oz3{tG+!}l<9A6iM=)2R*M_vT$AO7S=*WzZN^|`!E7EUm=E}j)o7Y~75W-!
z)-TM+@I~PfnoLe$0DL}W?1>7VbOuYt(FkXy`Rvh>oUd%=hfxOq56n#xPlL4i@OjS>
z_0)@Rz>_}d4!ZDK1XB#)g1^z+orI?g*fM-VF%-ToEhiD&01BRM79;wNxSzfhe>%VL
zVaC%S!~Z}7U{~;u$e#nj$>cK2YXMdzh$cZaz9Lt{7OTm7j;N<mm*mYkOc}hxiIHQ0
z|4m~2Y6{HFDf~Cd_`h)q|8p6frpa4eu0Ibemk1E>EwRN7m#KQ|OTECVY~A4haB;X?
zg4;R%b&h{U2t2PF1?6=STh$Vu$g`t_Nem(eSB5D+;ke>4{;$vHncxT36xq;;90A#u
z)9wtlu9ic*n6Cmtrvw0GnOE6?n?5qryov#t<rQ^A0gg`F^@x7uwGeDPfkndM0{>7s
z*75Ja&lU-lgtg+)(yL;?kKl@>1qdYw0TTIWb#a;*pW)|4RBT{=15HjB;dG*Y&OgCV
z3~;e2`q}&jnxsLtn5&=pleTq^JL8>8MJ8%Z1>68I*%isKB){s>;&CKxg~MBU^%IUA
z%w<YL5T)cvtfC+<-$|Haq^+N@NjS_>3PFw|vUEvD;B=0@EXCMgcmrcEosniE_uZX_
zZ`k{I_vG#gCr)3?2k3DD+<;BuEkrk>%=!-9z4<#C>6q(>U!X7RzKpDuzU@8J!CY9h
z`|S6On(cv}?g<d1*O$2k7HIgMCt>cc%@n|hO=Jx)eob*QLRnt67V<qbsvY*U;F!KS
zh4xE%9u-|<&V>xZ_zglc5RQ5S?>xlxRv1a`rQ{cK=Kc2cfc)$*kXav9bQ<v}I&&n)
zm(iWM2LU+`PH0Hc-CQU)9Esnwp;R&k_6S_SGp6+OZAaIJu&tW2A&{@SmJh)5PvZqu
zr4Tep9~t-&Y+4%5n3lvX*Lgpg`sdg@q#L*pdK3(D=UijqB+twXZ@h8#W<KoP43UIy
zRccCowOo8cWaLGTxV#+w644u-ERfG`V(=(fIJA*U)_yoI0L<1Fw&|7YHMR;0<1Uln
zbb&pL5y&n;$$C%YROQ=!U%BZ?P`76bbk(LuRl5dB9sSIsZsuLaaK4iTrOw5L|JTO-
zukYX2TCOPhBi~dmljz&e+uil*WtnZ4BRApiD7^^JFo&G%VD;(#L3-k26KB5ALWbMp
zE0ED<-3pIdT_wq_9jP`g?ta{UYb%-c1PisAoMEX+UZSfkp^@Uyxtm3VZ>(tGPC@9(
z#LUtu+-6gdMcs^wEr3VnS5&Za{a1;BT4)JJ+Xs^YDtL5}w@y0tRqP1#n#FH}8cQgH
z%u^)1wA5?*d6cvEEAgBG+%Q?Pe5V^FOD?3%DxY2<vah@<7wPylLFOmHdn|Eq_U3U&
zc`?Soxnz_xG7lyKCgu{jO89Rc1a{>`0RjpSktw5of_2A*F*Vu*oaU!Rz|j(k5DI5V
z8~!;AM084->ODh`PkP$IC^uz!s~+Mb=Eck?y6XEPQAZwYbKrHp6rjXy(uO<zs>o_5
zt!Y4GO4efYR3&ji!H5HqT!?WHpHoq3<`5l+hzW*pyHnJmc*s+F{AX_+?JBU^ARBlW
zAZ`RAA}LHmXEn){S$dA&%M3h#lb1=D1u_N>hX0^WT6kQ%l>w~<{+Dv_Oh)5miUB$z
z@sq0#2fyJDcLY4FxyoBnf_Buv7Cu9adZR#Vtq6zDVd+g)2Mrm`%kZ*3T9zS5?C?4`
zz^ka!_IY~57mJhJT3)LBg{t<S$!2rBoLUIyV?~kx{V>T8kUnlTtSSfq4<U+-*de8>
zmxprd(aP0BtieP`*v4D0F2iUNU#72cOB5uFQGFtrR8ZrbrNkHl(!~7+HX@Svq96^C
zu(Fj^T_K0c9R<(trABBK)l}l!zPD8l(UU!ykE8Iv9(^}ZLrkQ;t=s>A^s`uhKyEfC
zq<9p(w)V9>^3vb=11+FZ_9NsUTof7u>h;nX3F<gf(ps32^07?Y<?;d)qZ~>1*ix{)
zp$D*0-9{*smhwW}1^Q7&A%YN7F8IBoL<l*2=f3!4kf4N4Z~?^@*d)LJ!rY*gZH~<V
z_@$CP@n-(t!k@~wMz{oo5sy$wJdSj;g(c1%L|pGNCIXy=5yqBZ1e9wG)8q*khZX87
zQbLl`dlA-zQGfDIpKw`_Gu2Io`o1k&QS2vi8eoRrV}ebOM}gZZSK}!A!B3}{G}l0A
zwiHhoQ&7>&h8Is*UOZ`f(Qka1i*0bJ#~1lZc#6U$$M!pNZ4K|8*`N1U^4|+rS1TAO
zu|iaGiUp$IZs>hU4jy*gl;I2FK+voq{Bem<l?svEh*lNN(9|CjwSq@DRY`EKa9_2W
z@|tZ+?!vU%;l-0BNN!?R;&KUGZMU<cU9fIndWzJd{m<*cLoq<b?7*A9IroBWJnY}Z
z1|O@5Fp)^xEtZXqOKwux0KMLYk4kLVCmikv*yfR(Y5A>c2Fo_v)eV!^-w{6E%iK5J
z)Y*RZMVlr(8aH#z)VRx_p~YVM$!zU8TQ`^4R>AE0$!zJE46o10?%Hxo1)Ht2#7K~4
zic|6PXb*ZR(voT)C5;*hi-Zxquo`~>>{gIw6&jx<WEI^^fB_LbF6wTFQx7NU1M7Sa
zFJT5;NTp}dz$g%ZZMX^3XbtGln5#oh8dN_x@P6Tmdbon?fKPY69MFFH%_^=^RUPp*
zy(K-af11YA1u@IatzwJnLaWu+sX-m1lB%5=mC6HID*)A%|6B=$dF>`@Bk@>N7TCe-
zBEE3in<=(cOmR(JqwVVIN;qm69`x-8tca9bt<c2-$UNfqql;kt29M~>s)^_H0%6Lz
z1+Z03Eg@~_U$mR?ZZ@Uf_A?EVgj3F(kqHkub2PJ-W1dE$_9}KLtt3BJ8V`>(a1}dW
z335A|mOOzwyzB~<YWMZPlV6Pi+3+)Y28jO^<2OGP*kQGNo>rQo5s8MLw?{e8Q@uW?
zvMzY%e}wZn8j8?Ao5Buo%=sc~X9pT)=YQxHXnWweUQ0j~0L?ehOvkJ_o1hwy2%=`R
zUVVse<|pTWuurGV#%_*XBvP=3Ct5G7sYzCq6c*9E(3>`S&oD6S()j$06fW8r=0ZhU
zDy|%dQ4YH&@Gd?(db)dHQ(cvAk9ILXG|I@fa7o*t3`TI8Xj2^O6Tu$+MB8DI7Ff&2
zD);<xu*v8wr~V|dN~Rc78p5+{VV0lyo*GlbtYI_E`go}I+ic3KZi!gO+=+Jjac~J%
zs!wXiqJdBt-Vid0b1g1@^mgOV@^_n6Lf)F2hbb}|cU{~J8|&t0(pYEC-gOm;&%M5g
zL&@UZqBW)rC(*~s@2ssUpSzj=Mx+@f-$>s;^Nr#9YMNc)waEdI7cxE%(10wo*?<Nh
zCS>eR7EdQ4OUF=4X`Cd*9gu-`yV%4qDZz&U{qV92qZ;{%77>Me=fBB@@6w4Zn6AE)
zS6TmN2E1~JTJG1yGO(fr*QLz6ERrz)p!8c|pp81em<u(gYt-OfmL}u8k@)%#9L)X`
ze0>^5HN%SjMnmz_=^~m;wa*mrq3uJ)eK<xI;U5MlWpK#r!tuTA;(b?{Jtar|M0{!S
zq|=Za`dcztCrRB)VIi;_8aN5h$V8TT><eAgBa&~i@TrBr*vb^6(il^PRlPuR1e(TY
zZWV1JLh2P?ql2hi9K|t(yf%Ejnmqw#-VX$$Ude=a<@LJStwrO_cjEIyTvxYWS@yNz
zGqW3AS-BU->jKSDRy~XDm19TZ$>Js`i5l`LeOn@i*LjpGA11jsnzxp@k-MlDO`FP=
zEo97PWX+Etb5>=vbJn4spH(`;+<;&&hsa;TD!Vk^)=503oLQ6^VdBM+p~xdb)$>y^
zu=3}S1^SFgKzS9ukj3Bn4yIG)zLJ#Cn6BDmgq94v)KdJUZ()nR5WWN5)H@F%Earx8
zp;b2?4ghzF#hZI_3+3!GqNo!7YvyL%=(0EGJ(=H7>(hF`Hn|Jm&&TZj^OM}Xt+)kr
zK^_M9*`7%&Sbw^I_>+?#l{MU3Jq?BAPlP1Jr$COSJwp78!*j_ocX3X}O}_J~s1Zue
z85C$E^yIVvZsO>F=_lyvQ9Xie<l6TnOh$mfXW={D?<;pj<(&EAO(gGR$KGeKgj1{-
zxWEKo=t_c_+K~LJnzZDgAp@0au9ZWHUAS$^5HBKa&Pw>4S6p@K`C&BCf$tkXSa-$w
z;9nAm0|Q=G->;8#Dfyvfo&NJhdO^?5&munv-ylxMakO{x;^?rTbcNFg(l58#{qB2C
z-2R!%wWNvo>3-)22q^6>v3Wt>5FeqvQwD_Mxe1^GJnGqwrYuK8cB3t;LB2bJfgs0P
zlmq|)>8oxvgF<Nhk|c*BSK?qeTyCmrOnD(%jar+Sx1ATEGh=T4F#L$&vhXC!;NG+&
zXeSFYsE(3M2c;d5&itj6H$yI4%aV(H9WWR-69a;vgAtE;aAAmbe2o`JxQc1ylOvV4
zpI%W6CzaLh3V$**l=BxVni(G^{z`V}>qT6K!`vme;H+Y0jaEP?rbkaxs@Y^Sjr1!3
zr8?LM78aPfyyjcFt2><c@MMKkLn`<Xv7r)47L*m4Pbyg=8@}xF-pCon6uRdTQFm*0
zKFK=grge){6=@M)T1&g7Y#vRq@`XqpK98(sO||Gr04R|JlaYwE6?x1#(6zXbH}LfC
zcpXMGZqu<5ENy3koqO4pmj<&0!Z`LU`OPYO)Qs%yl*W|>r}1boIXkP!EAPchv2Isk
zdkTVK1WZjxh2ZK6d(<qP)JPbl+_mk2s~A+y+Q7<Kg#tnd(oujQA%!ESF;$k%#%}z#
zb^GeRVcilMerrp#?^r5F2yBzRwpIU*T`m_x$<i_-DlPLFT!b;))iFAlbAy3G??3;v
zKaa~JaO*-OOCWP2gx0fF<Tx$A?Ozj9<Tw&n)VL0cQG1457)bnPp5TWjC#3cVEa5^y
zVhI4Xt*x#s!VoD8%6|vSO8+ypUv-10>4edS$3=SZ^%#1ct^DzM)ls9q>X1~!5`ip|
zW;l02<2f|zd~^cY7@u5WMZ5f_>q=47T}k!_lMO^Fg<!RKT@<Vfy%bY0Lm;*aJuUGa
ztpZR@ThT};5|E>A5Rj^MUVFQ_raHT$X{Z9FO~5lIx2Wq^AG$VbcLtgS83?_PHDgL|
z#gDE;RKX%0js5BLlrulrYQ+(}<Y*FPoh*J6L{xeTdUx8#{a7R|X{BKNHx%8l-hPc^
zlCE$qsGy25Ou0;E)q~f^EKP!WYAdU@f<Z;2F&8NsPqn|!)L%1ON6ll6?!0E>Ap%WY
zE8bYYY{8t(bD&jYMtPY(7^Xn}n#0mwcKMU!D~m&@{h34X*K&w5duko#%s$LnX&CL{
zvJNz}4>T(cq<E!Lg*0N!O2hEiau|bqb9lTd5c4>TDEz;L0<n%V3Xo<){@TE;sL&LR
zZ`z@$9@c=Jo_U^xO`@w^v@ai?DELMPT-QeeIPWv7?USEw-s{ZOi=k0opM;XDpMG}K
zK^(2Uxl_&jIKGUgSUuTiw-;G5_UDt6=R*&Z{-p3`C#jb%&d-BXIl$Ayr+nVA9U9G7
zCt*5|Q_>P|c^82{L1$?!#q393vWT#5fh5w3u4`37ax-l37H#lCMWOo0q)qsRWK6P4
zY5MT!ea3jabc;QGWItpeI15zXM2xMu_N#(HdN)c`QBr$!IqjHa@OU}C2%-uS)EWcV
zgRIvepOP%c-i!T0)Meoxsk}wbR1x0EA!Zo+xX9*<yra@iiH<>WF2Sh~ocu^vh4@n$
zjj!#=e;fE|*HC@Syg&Gx7)LuLg$jd81A?|DiawQ$6K$2u>8O?|hqD$(+DA_<wM=zP
ziLmbbz_v!KtfJ?g52|3C<FQ05+N@t#q_AnZ)^r$WVk0ZKFw8&0;~@(TWBO;9b66^s
zLd<IsO|P8m3Y1Dm#p-H?9*@E;lT0GsMBZLZvx`5J5iVNHP6IOWoL*&4Lx&2Z4aiY0
zU~9+f2J#t;=uHIk<V&D|&>OsKJKe&BREQN=ZA`<Q4>5_OKyJd=1^U`d1B?|d4V=Xp
zU@Z^t*oHA_J{t&N5m%<|dct_)ojiJuf>{&@A_PCD19osyh$a5cDMR5O-v@e?F5)yB
zU@5XekR(xz|2s?1`}rCu;e}iTtN}k$b@><*)xEj)0x&rbiA(0pvLjxdh^RWIMtpbW
zT>ze+1_340;{1veuZMa1M*Mp@eH(^(<B~=BZf>SuojO;^MKaa!{Ke4$ZC)IHp_7PQ
zr$iUFR5+tA=wjmY=jxeTt+c(kdZ|UKOKdkCN>a!f=A*(WB<hjHOrD@VihS|bgd-7_
z#6+r&)SX3`>f{mR$~K?)nKR5$?n3%I5&ZyBh!blIf+8U<pK=wx?3%q;@|zP6DpM|F
zDbdbT7hwYeFn$wcs}%494W$_}A4D7*;*)EP3j{oE2}i@km7*_6@OidK!Na(Qp;|Q)
zPP*LE86rd&yk(0yA(dpGf@Et;!u4mkM7_RUv^Uz|g&0sOgn@>4RE~O}p-_c1Ymxr*
z6*ZFg^X7H=hN}0=doj17Z9?&%z=2v;!FN-vpjs=zjc&`ee1!Tx@=QKb{h!VC`}ZGg
zmg@g(Zr;}a`K#*xAO;M)@gmLQS@;K4S=E!k%F->LW=WvGQH39Q)4a`ZzPkU-x~T92
zEBe-3-`skzzO}yj(JK5HrFxE-7PAD}re2SQh;zcp<jUPbVa^(+U$C|_ayzMl41Sua
zTv#?{FE6hkMQ>~FbL=yceaJ1HQ{&QG%jG2|;+fq)JU-byI2b+NKkD|$!dLuSKE5l(
zAFz1d&(B8(`#<6bS9mVx!`i-M_^nvSDtxt#Z|vF{U_RDcxfG6j0VmD%IrTL#gCcnu
zdW$V&5*v22%P%+%lPgR>HXH}@3|ajI1=KZ6rF0o56W|ATRbr+Y>3Srq7A81`N|csT
zJ_Xh=1<~6On0fM{m1%~hQU;DPg<EnNNQXEa1%W1vQpj==*GyTVgYg1{sjC4|8W2k|
z3iZ;)$KGlRB`7l-aMUk`ceG`CBASEsMO0cAZ@?^+%&zkImFWO31CpJ?=xzK4)g^-e
zqyjjB*TIwQc!EU2r}4C-YH(Um>*&Sd$?wnia`w$AY$AVE8Pn*zr4>T{OomJT-8RUh
zXNOPre;PgBd$RlD;6zqFkz-0SLSyUb*LaNa)EI-;2Yff23G@bt(+J1EALAf=hpN^o
z8e%)lT~j%XT(UkR6OE%d&X$<R=-dDx#vr)J{ENQ4o5FXPaCqipZo?5=DtH|1fO@)n
ze6n{WDgsq+K^}+M#R9eBm@SUFICdFnN}J3T3-%qNVq*0C=-F?-H`|`p-m*7iG#f(X
z%elsM#vm=gXAIW0!wZ0k5|kZS#@o|m`PkEOdCaj2yP%xfM!Ze=k>lJDly$rGqb`3o
zTVHt$AvhMjH?KLI1?0iI%nkCr-%j=pDbq<~phFiI(2Jv4z^;;mkS`YUjJUXNW02;v
zJ4ezXi&L7fP+^U5&IQYoju+(~I$~IUZNCl6AnpwSpdBaHV#4Ae%b;RDTzA;5K)y*l
zb|c^8XOEhroosADyL_A$)Jlz~AAjjy4J}OU5KB6xcKUW2M(+LoxZmQM$;Oub=Hs;3
zZ$2K51D{;)HhNlDoZ0TlZi_>ct!<~4kJRSa)QHQR8y4ZRZhCxn?%wmGCqFgcvTSVG
zaXwBP{!@;(#C~B{_U&F?Ub?sY>#x5y->z(I*={~gi|wlMme?-r%D!F9>*U_=$=>lv
z^9`%kmK|#&wb*h#;u3qtt);GA&*oLTe)_!4uAe@4?^=!2YS(haJC?E{oJhLYuTdj-
zL%p-3CBngR>;3UXP;u{fAN{=7;^wR7w!5#5)#mo+V}58b5ism<k`|Gwr(Dz)ZSkIK
zJ*<zqF=DHiT_5>FgH6K5E$;wNU<aCbh?~ng*w_N9e4G|g%EznV7U}>nq=J{j-m~M;
zufS0}`}NrS9yr3_UC{NmPzJODMU;oK0|i9yAD<oXH3N!lYynC>P79#q<89cFQ)<mP
zL$l*pkM^GI9UbjG9s%t>X}FVOC)+WX#%*)lrSY`{=jDwqW`6p{zP%SucaQ(O*`~Ou
zWh-)w78{UbO@eVe&U&=KUcX;K*RyO|Mb}SG4%*OlZ0@A%JXUME&ST#DYJJ_hjWj%`
zM7|C!BMeuePc2NSTH6$j`A99cppDo)pF0>$+=7$-;RucCpKR<{e{1@u#<M*Tmlxsq
zqE~b|rELy8lh}>7UY$pa`S~mOQ4zkiMVhQl<FP+ogWazYc%1Ng6I?mpRb1tN@BQBR
zRn^)%0HsE22`f3O4ivk3xcXIv-70>Stz49Yh}=3kCXU^PVws0nv&(YQv^PO8Cl9lP
zYii;cbYNtx;2JioLT54{tB(9cWz`t^<kj`hHq?I1(zeq6Y7~woQ)YGH*j-tSR5-nH
z$vvx6o+<$CP5mo?_|8MUQ@J*$to5izdgCQ$1mdtP4c*Z_KPi1{lpm#et(8vgwPqQe
zv&(pO63$qK=}%>dH>L7mKiMR&uA&-B=TWgm-g1u@ImkDGroOH~c`XDTzotkrcuc8$
zp*AX9P;%3Sostc8SV|d&u65`DFS3@<0?jc(tY(Eq+0Q(0&rhad?%67UME;fOg%9kr
zhpuzzhsUL6$eEsZMe}Pl8PR0UzWTk8T&DR<xEZT#2Uy)sI&Z4LcUq!eO*k?^1k}Nw
zPOmgjH9;>v<|4cX7~S7@l?Ik)U&cFyUjlmuR+KFND3@&gwH613nVkHj(ZG$Bqk~M;
zeh~)a0w~BPPWIukZ73WCUBTH_?tACc_!Q8Zel0_@c`0477+(IqUIRFXg)lGS4G?Az
zs`0~0Xe#c*`dRu`=sBqhJ*)rp>n?Rh__I)#kx7sRI{7D??d7L*aV9=VUjltZ=~jTh
z%L=(%`dybPs5dgV=5K7JmlK6i*sVNchLw4)3}G!~GY#mlW#eA|298H7vt(FLi{^9q
zJQ`s(Nz3YqAy5^X!&C)pP~OFO%HF=pby?tDF(aAWo^ZZFL$`|P6I*1r;y)>nu=!5I
zd_Y-ws=SB&vz%H9?{}g~{`Atn!o{9(L9L9uLfC;w#p!TLDE7;h7SmD*@*}gCzCt-*
z)l;<08N;~ym@3PklG9w>=vqC827^cOQNC;kRQ*}Jh$yFv$j3z)tVCsHtVy2pjK)gB
z2)Mlb4XR%Z5C4Ql-|^PBwV!~4$taA~Sz&y?l$j-esr9#ih`eN+1R@LsW4Y8juX{1k
z6XmPSd^~_~i6;v$My8q$PGT7A1MYsxFpdhB(e5o9g;rt=l8&S-Yx@9yxSN@`OMovu
zUXprfkC-8RX_4~0Z&MC2AHfPQo?@?f%!6_jXwyqd6w#CpWD&p|D_(@-Fq2+RX>l3z
zB%aNA6<sOj2_O`ko+mK|+F{EAbP6r?x4!fqd;;)d2OkuzgeRE>IOTCB;zpZ;%X=yw
zyc>WTmf_BV5hHB_kmV1x8))6G3pQuj+{1{V_{`&p3pby`QF9ojSJC()i6bJZ;%%t{
z)DaJAvT^AAdLys`@im6`CLPCbgC^)DC~Fm{)?JX&>Pq6YNHNF6hRgXW{eomHs$c^0
zG73>zuSbqv%K!x^nUjDSUT!yX9SeMu19o~OCDub^7j<zLUmiX?@m?J7J@)>8_TIg{
zi6dDY-oO1R1|J_JC9-@8Nj7p!LVzT^OMnNPWY5px_>85oJqKB%Gc&Srg1`IQReirs
zk0b-x#m{cArM^^GS65e6*X7Bx<nZSw2MMcZ^g4t@ZG=aUU%Y($@WJ8ZN3T~xSBg{F
zZSgGWf96A)5+;a&jYH5<d;Bn>?#Z8X;BMtrAwx*RAz$E-2NZP=#^ch)#iE3VUhPkd
z5v?9*YdX!y6oPVFd@^@4A2Q9fqiAxXMiuHbOnu(RjU?v<P(hiFh5(&$weJ@3!hD}%
z@dDI@ij446YlEPlU&wx|#T3_yZxK_>$0`<6x`2xn8KP-O>$*}rag)I<;)%Vs#^Nb^
zn~ml*b^332)YP7<B_?i6xlL+fu3ypQ1SvxoVo1=jJ$jPvgYhLq*o=DtOmS1wEh37!
zjK$*Vq8R6=)Yf84s%>%SkacehliVtIi<o5IXt9_i5Xlns6nowC`eL&6zg4d#9&xCA
zv2z-SK4IXzMf`Eswpav~*%`=ASSl18+gc(GYenAL!R5|kw|aEBzgG;#;K`F)N71V@
zJ3;w9hva|g&DDf35tvBZ-y*GD%x<67etEGd=D@%MFw!H}0&Upowy>tU-QBL3CLQJ$
z#h#ITqYVy4nw;ChBY(4LM&YT$j1r?J5dqGJIFR5UK7F$F@TVsb9gq?X(x@De#6ZiW
z)eWmAEkGaR7BIw~vQ}ck@R}_)H_5ur%JgEB1-vRwlD~JVWUwXD_Vguz!OIc927-vP
zh6hs~eLEsJG$yzO9I^+%_k}|`-L2t}4ga2T2ydIqpHx5kCJZDjX?Z>ykon-9jj}bU
zeKti=_{HOgPgRv2OM5jMXZe79lGWm8Yb*IB&FSM{S?R6=B5UyN5nlH~PTotdi#dIX
zgokB(mNOo_-F%<JnsjN9upBXfD`nLo>fv_#+cxnxA;LGhg$&+s^~fNk!U;+uh<hEZ
z#H=6ipZ4L6&Y#!U36@1!+a6+F_sMngfAc)6*LH@O`QQqi7U(CtL*Xs{#V{FXC-bxL
zBNAyq4i))7)?M)<ks~MSv5h)rL>w-M!M;g)(EYMQ4{o`Tn9!4ef|sybmn{1QIvOCj
z)SS)wsMc(3NXvzAXF!&xElVnLOXR1yt!iQIrDIs12Mg3siF%ZSpG{V$@NYVqo#QWK
zx*w#?G@VuFh4e;q9uAS6f@R1`4ybR;GW$urYMOVEI^VS0M)XeiZ5~ccZ(`gO%;<uT
z_tZr2YMQ^@go-rGd9_0Ssa}ZCp$oOHxS(x^7vU{`dwfB-yZcZi9XqOQR4Lw%=tRx5
zQ?7G>I|O7Qr8xtGT=pS$Jj^e$!{TXvxg-T~hy2@N1>B+D|6B?Z3U^K>uuRi>4)(hY
zo=EfRf<0u#oL%a%A3A~j+=*!pVQtG^(JUU|*4_Y_SO2O}sA5K9gcm4-_dgJrSAv~4
z*>yg?WkHUj0g8vHeh6e;JbO^w`u{-&crsqqs&CoIA!8U~jggW(AZ7tgkto)OIgXB=
zM-e8CSb6SP`dH@RL5NTF<789nc<lR4c8!l*PGMfBU_wxH05zQLmV2*Y_G3M^Vn!7i
zDAyLzm&IvZ<>O4|(Q@<!CqfKQsk8DTXFlTSHj)a*NuFeN{j``&imPhfog$SLpqyt+
z^~1EJU5Gr<yiZudHTM{B_goa0{3_?8K&n_Q2tV$*;fL(ZB{<Y!K4kdQ_0}>X`$yAj
zQ(Ib#nrqbG)m_5UowHSGi&YBBV^(~v0~u!M{%9Ya)-(P$`e*jNH3y+|NtutpKNc(8
zn^oRuF$@5pYm~`67Iwj7$dw00gt@~h2NgQ2br&iq$mWPR(hI_2`gCQTRuWlgBtyHL
zRfkk0d1Idd9v15arhtx7OUPHQQ5&2`ZvFiHm&cu+9CQGqmZMHYeJN$l%2wLd@AQ2R
zt!l3=y40ZuEN>h6tQA&VV+`Qv#NdF@nI4w|cTJ_2NoR*pB`W$gp2{N{n(;b;BC&Ft
ze2rPK1{T{?px3EU*=@7*yPraN;i*;?WR;G<cj+ObMOwv7EMNhTJ)T>4|5>0gt5_JT
zqo_Ji-%qw(^g$i=BS~2!1cEX>eOHjeDMVN(MqRzqr_cDAh_vw`VkIl|mOT;-)>?wX
zdD--s`AT<e^%qo<{R!rbq>PV$d4Bkqrx|(vkB$$2Ks-MlzECkJz}*WMxN{se>N5_d
zldy!{eOlAoGqu+9NJx63+*-21>*ujA_5#d61V<?CwNlPJ3ZdIHyYRt#Z8HwnESvWs
z*haa;7}>ddD}fd|q(<4Rt*w}RuXk}|U$LB*tU9ma)jbi0X(B5Db3n<59uJr3BBc<l
z;p~<;WOaE-Mm+53&$bu3|MJnwD%n;l8fcf8ibC)b?>mfLGAJ)<9DehyIqDY~r0QRQ
z3Vf50U}zi)yiv=>OLncX(9!|!cOqm>UP%~hDO?xx<SLzF4IBvDrh$RQG_%T8per*-
z(HJ0{Pl4uG+!U)SfkscLV~C@sG=wUHAmh4FB0H0bFKIGU5(w=806bh2)Fy14q<j=$
z1+;Nk7g9@LETI<phH27}%pw_Ved(004TdgCS;5d<CuBj@!mgrX9QC_`AmVh3puWKB
zw9^H48~L5L5MfhC&%J>ctae9OT9dvgAy3#+1eG9g#0VKeR8V9cMC_Rx(zuHN$Fl2I
z#v#X1X^m^<QZb)iJGEO32*%nxwB#j3My43P$NI@QZ(Xlv0jvblGS5Kw#**-qU#Rm8
z%p;*iAkvHk`0lndxHs5Ncig0l_EIgprt2a|UIw#zL{Iut&@xyAK4wn$G+=z#N2Eai
zp-Vxz{#_S&I<6d%h7@7c8<u4?7d(Q6&&rxVR$2kDd_izcT8^3Zz078lbi^yw$r+Sl
zX<B)&fE@_>^#P&JUOjz^46CT+J5-?l8k~hqYWjllc&Ua8-j-Q91eV?aC-3p+12;_C
zf(dMd?z6I{OUtL^1GcjOq1Zwfxh01$Up)qIfoe`UswhKb)f;k?pQ)uWE(xKgeU@Va
zn5M3<1sEqY0;oDF9p!a=!Pa$FD@{k!|Il$d>mkhpq2Fh<ek{F4(`hu|JcV6hKlT+l
znd9ma`2woZTJ=;Nb!=e}r}^g&=ht3c&N!Y1c&Z4mu=dYCcdFBBATh$Ux8~dp`jua!
z(a;8CIjs}NkT`3cJ(<qtHA8{bMpt!|5p@vwh*&F9W)Ijiv{}|liR&iXXLo~WO|%@8
zs>#a44Rls3`MOUnm5P=G*QLwRS>1LGYm5j@EugJQK+FooE-Tl3s?=Y%An64PS4mQ|
zF9MypK{%?&HK2r~CRA9#r{_~l_j7f1HOStkP^*wA02i44hk1K}@?tVP0O1|AJ^>;7
z8Jb}^fU<2SuNoK0pYY5vE6^2Y+Nlze-Jqd17#Y3etP}6+@UXbJD5mZ{o`Pbui&0F>
z-W!wcu&IFiJeiIr^Kk|)5)_Or0yhrW1`gh*2?&ENwMLy%9c?&Nt^#H@LNby*ychEd
zpDl#1K7U!%=&jR>Vx15{t)5~6<DReKLgrBA&Y@$#BLkyK+u&#19+?weI!FzMQkA<m
z-6mK)oad#xcmodS-OlFNM5RV+>3Dod+R?K{Mrd3=@L*n_mEnQb()Q(Yv&|vWRKk@X
zvTg7d|KR0+ePl=t;wqfI4p-O<P$LGRWA)W;s9Dou^d|+<g}x`m!ROy?L$;(cB@Vyn
z7DbXVNW5yk81>7RhT_X~;$!vs^q9^dMT?){oxKa4d%ovN<`HAYI)*%Sdycvh#@3O!
z!DEI_jb)3Z>w=HnliLq;XX%JQQBeu@%2RWp>PtB6RZ+fij)d$!uN2Y3Fk>T0Q3Ja7
z_7OXGgv3YM?m64tEOHfrzgHJW?=2;6Gs^0$cgPulqUTTowX@z&*73<2#)rePZk!5D
z>{5?eFVN0~L!-U-+Qj>4nEXiYHb;ykZZPaF#L{$J{M951nRQJoF;-<tMX)PyV?lj7
ztB1~EDS}iHmF80FGI`e!$jDI`ov*dQp%)+1g3AVwi9zu^?S+jSSXr0bE;LkBXquqL
zT-r`L%+Pd4Xrst$x0q_GGuEp_R*NU((@8$-(qF0hL<sPF#-4(MAcI5RCh{;*#mrQ7
zax(GG_V%{TquCLMUPm42AVju+)v00p(9ytk>LjFg2LzNS^zpsesn|N=t?3h;sRg_E
zg#DX|SFr^Q@5+9_oIP8qRWsaKyQI;YtY(}+sdm<@%a>tM1VPk3s91F|DacWi4Oh4I
zF?;O!7SQkB<p57(YNu<Ycz+9fv*`Y~k#8%(yn#9ILc`m9<QMP+s1(y)s++ZRTj`^M
zF%vK>N)st?pR_WJb$wn+GOvj`OZoxtWwuh_?7X{ed$o+Nv8Gd(x0#Yx3GyLbm3gi3
zOk8)Dzw?5%vUeLMQEe#U{l?PvrKOUbm3&F-wa+qiKt&I^TQRL#J|OJr2C!7ZGuu7`
z^OKqNlbN-Z0TnlalTnl#i?9+}D9|2Sk-;IydI{xVtNbzxa_)X&g66b3t{fzq%Q`e{
zFNoYvw&ai9maONBb$zC~twi|)IVp*JxJ$N<{Ig?8T&0x3yG|(!I&0PfpHRh>W0)qO
z2E&Zf%}i$z2G*64>^6|nH=o)(&6f34iQRA0mhBoAU@t;;aBK51%keMCZ4b~OXl5pI
zZb}HdUO<|Fy=ii<I!2kG3jlJW^PPj=K#q!(8$*6W@8FJhJ%YpIH-06{R4gr-x!=yi
z;u-}IM*|xZijOq=Hh(kHK+Q3oVaj@_nImsSh(mZ<JdiV41_dK`9K!J={o|V5JqK_P
zb?GSP{mzCaW1kfDc?W$w<Y$l>z&wGb`o}VA5&p!}EN{5{eW}^DR4z8>qWg3h`^pbl
zamzCB+Qe+RWf`xk$GEQCmV8Xl5Mc7d$;e&yix~I2uy8f>y{2bV5HFw4Yv%)fF_Sl6
zXLAOHu=0{V*HEu_Lt^?~J{diN8rGzL3p|gC`Gm&UGT%sHeH<q1$-qCifpg7CpHezC
zOPvZL#!uirLlVcw(G8~`zaQEuXHv|Ek?<-U;*N(JHcsJ9?fX+uIQdChzgoA1&eK^u
z4BDk;oYsWS)Y+g(OFCDCPXLR9Iwl}YQYGf1I_voW9$`+o8Y~{`|Dk$wZV$fseF{55
zm>rcFovO*5?@tjXvf5c+4%b`F`i2P|J!(-c1kV_6Hs+27V^K2=Q~@9`Ks!E8J_V;(
zJUcCd8#U{SDl)hrYP`gPH3y^(+N)`sHy4typ%b`IoXzPR)L#Y|=Mo11VnCh0K{t<?
z=b#klz(@BLA!t}9aATxx!|Je6)-+n~_#!>aN5}s+FNlbCT+WGTO4yUqvhuarR`rO{
zq^R(asB<WX53vi=@z0!g5O&qIKV_YV_RA2yYth>Yp0U7-5y$t0`*_z$P}Nf`9~(UP
zhm(qCM0X^^)T8rmXY0RJj`Mr<dH45&&wJ$GtqLCd#WKmS*dwzStW3t+9PJqDhl=KE
zenL)UR~ef8IRSFzy|-WYnoJy!EQ!c~^9#ESn6gr9s_p(ReXdQ1&Uad6EuHPbPHZTq
z=tgck_A4Qx3&MV~?mGW+y`OY;;N|&S+b4%Chum|W?>kuGicrC<sHz+?Rbh=EP=weG
zV0J?SgYtUhK8MthCv!AVR~cj)A>8g{QjFdtPo9f73fcAG@X_;EhY2mV^?gUnz#+zi
zV04&5-%chTDR3z#VsC9Npwd#E9mE2s`Yuo^DP~`}|EP7vs|z!@oSq25P*hte_p!a?
zBpq{Qj2_)}j}E=C#O=bE4^QmukSp#&V@jT&MZQinm^Q6zuN|7`xQiiUt<_fEsF@Se
z@mN#`Do!CJ2Gn(|(NiUm>tQe$G}ueM8;^JxCR{V&$NYczneME+Jp}Y++SUn0OE4s(
z&yt_Ax?-jG$oUuPA9&GB<t>TUaYNN(O$t7y+{3h3`#ERL6U7GvLG@6oC>zp=e!)3(
zsV0Y2{T`$-VW4m*`3z|Y2|j4ep(+n(DUiRRa+xTTTq(%}hR38VKz6LSxX3&Ms^sm(
zM6DOu;OQDE)e-umEBckpM$RCtrw^V?Wo4p{noG%TNWCZ>)U7-T(?&;hK%XA%(I~X8
z;9sE6!2EL%M8YY)h?ij?ZG%z;kjB9!U(i}EysjhnP$3&Rff5)^A;bU&+D&+=Mfk*H
z*X2wRT7+EIn#3=aX1D_u*CQG{Syc-&0po}!uz9^&a9Ei*Ld-aN&y`Yv0y0%l!eMcH
z!!ZK`PcFohq3Oj7l^i@g5hqP})$?4t-X(h6&Wx3#g@^9|#BLHEE@0?0Cw2;Q-|6MV
zMuoNXK|)4Tt5{KQulb^tJ1Ii3+im7r#5w~ztk;9<uCu?1Ixrn)Z+j8ssGW<ZWo$rN
z#$!GyglO&se1-G@sh<#y9)x0X0iR7pLLt&@SLxM<oZ)W?MWJDBJLsXP!8+K-**uPl
z;!HSa92FSs7&R->1y7}b>kGAB<Pa!i@=BUL5kRICl3A%vDC^=9V(}jUJ6jf`C(Iq?
z^eV)e8i%7?8NDn$vYkhS^X?&EDMfA5Zu%Wv(S7(x+2#gsR|AgV%H!s9rlp8hI2I=y
zK{SjwaFZ$BD2Efthm~1wCY=?MO*6^d#JnpStY=@}!A7R2UWlml^Zb@>&EK4?%bNGh
z@7f6mkb&;~UMJQ3;sP?!lZ&JnwYWqyuvyl-_Y66>cxMTno4`+hS#$|B3*QG>0ZvU8
zfd96-#~XMZ9IWLeP3;u(lj>gedXi4S$a~H5X~ac%dBINb_BPaiqQFBMddTejA76j*
zB_xT?YU=(?Fk4)hS_RtsMd?w+o6zk>DhrC!Fb4o6q?m_ZEFR+<UbR(?i0X+7j^nN1
zBm>b2pR7<@FQ|Q6cziybmt{7sC)cXj&0R%#X?uv)`s&^$eKZ_{%moe!mqk97KB{S*
z%(4QAt(w78-Xu#)kg9~}TO}vg@MxBg$$Xxt5vo6TMYfe5`vf!P!{l}XfzWe*JH=Uh
z6TM5#T!zA|yR4g$Li5a}B+?f9iR$INv^)ICBt7@q)4XrIwx>09neQzU-`U6;ylz51
z|0Lt!pwmLqFaf_%^|7j}yr!NI<VzO_<d|O>bgd9-h2hKB=s8U28gic3t|2hm<s9T5
zsGU9mmaEXXy>2p{a>|AwtFdrkqA;?}>?+@RB$*RJMQ>u<q$o6~a>qeZjOuYVS``R4
z3v#_j8RdHOX^`)wr#0rQr^Qv#;-)da56O7^nU1tG>tR!>XRw<~#n|hcylDPXoX&EV
z{>123!E-2DKPb-u5JvTf<~c7}E+{Q&A)_gip*)|0S-q_1vwosP1k%t*nO}I^hg&8;
zbqxuRoTN1$QS~Rs6h%{I9OeDR6U8I)TgitRg?lk4Onk>|%%jL-)VSND)6J2(O*`KC
zh5Mr0Db93XWQlY|*qS#EyJ`+FV+iIvp%Zpr_8i8*aI2xo2oqDAB`v!Y)2RT5+c)AH
z97$eZJ%hp$9eh+*KVh9mw&yB?6u%TB2LW+jKQPK26Tnca2g?;VtWa{5mi!yi*_<^=
zetz)m+2g0-oT!y>@|Mc+1R}(U_)vfX_XnJ3c`jyIsb(x=U(Cvad{H-epD{I-a8#2c
zT;y*dql$diWk3`q&6-9~4Xo@GqM(8a9c?~>5`yA3&Ah0^b<cuT+~Uk4moQrr%;P7g
z2&tvjIOdTGzh?T_Ysf{8hyI$!NFvfZxaG)1om*JP#?upXa&Fcf0J$TV6~AP#8t<!F
zH7Ke0%qL{4zjH!%CL*wZ1-jKpPSRR08EU=touwHU0irve%Sz47&C(FPEQ<PHHCKpE
zvQWKqmQBYm()yg@Np6&ijD`IAaXkMa`(QFeL(~(a-{v9qybqI+^t3!(-4cDRfX-G;
zZ+=ZA@J6UHb6J<~A_wzzr{P8KOyoaD42U?+0B}aaVKPSJ^DeS6oQbr?iLCq)d%*!5
z!8*{fabk6I*i7Mx0`IW;eTJ*}C8w~!9;5syzj_8CAU(LD*thKg1(O}!MVT-GUlJNt
z(3Yx#6s>W$m8t}84z(y}`gFss<c3>Yj<dAmC@nb2!W?7~&Jo2i0^E4z9AY`n&@u&C
zqhMoc7eNIvSa$8Nr!fYf<RXQ6SHg6MR);aPLM3TZb((ZOX0&i<4hzeu`NBeK?n|Xa
z?cNbF``#-eYUmGO0Bg0<C|g+E0$pnVofv-ZGas!vj98wyVgGGl84X(82MgT=ZSR4`
zJHWyJJ-i?7e?HdlFb*!y^>3Cj3z`;|Cc}@9Zd9<Zn2$1KJx0dMhDZ0Alm(}Xy4G}&
zVR@Mh%3dR|0MmI&@i96ts*HxTPB8OAorU5^qHJ1@x;~JMQoB8<UyZorSd9fynWipS
z07-8k-C+o49kKjr@Elfg!?d3AOwaX-ak@$JU@GHx(aX;A^WnZQBdGX;X)x+O3r&M$
zjU%-@jok~&d|;8F^ehDl65~H6*;zVaFUzejU)T3IRAb>EHKT`TI7Uunov=8}04v-u
z_1qz6lj4LgBIaqlpZxgX>A~a1%o~+77c+6f&bAR@IBsFxHIp8##af`7a!Z5<j<y?<
z6Dk5-j9sCdFuC@bgLO$~&*hp5!z}lB;=F=x8kgO8Z)*ILZsokpI{~Ldig1RoPR+2D
zCD<{URoQ%8Y;rVLF7{}?(SN9m7ZQB%Ux()Atn5-Y2(<l;%v?fzce2xC#JgvUUCHf_
zZN$To|Kw(G>oOfR53D2w2)Sxd#|Z8aK6JT*!vUpU;63`6y<rY{n+^=|QbV^J+!F}5
z#_I{v;(_adQV)rhgiwlE8)4gQ5G=+(6PIQ+t;SblS#$Jcki+*eYs$>&Ob5xxagKpI
z09y>=CnV-;&D;467+tbA+K3o}LzBZO@oV(jk<FmemRE|h#=OJFWGNcNS4VVcLUldo
zXpMFY&v}gvWN?tl&1xPSyVfPvXOFyI)@7YnfqyoH^$1w?qF*JQ%y|)Jjx5~A!5J2i
zhqJ$t`FXS_r;phJs}2*yO^hlMzU_6pZsU8bS5#O)-A?$evA1y2*3}AM>RsZ!&RY_e
zJYyc}YHtB<Hb46anO`stGN#veGZFjm`Icnb{8r(h4_&BaX<2Dv4=bT-Xm@=HP2Id-
zO3wbAtn9@A0164zkqKd4yI~9ymDIIq`p8_et$Zq_W!GlaM5*Hno?n}5+{sWH0?fW?
zBf>Pu3QQO&^Jh-QM1T##ulNJ#!E4Noatqc{5xe))o2y3ViR3|oO7ecIW;klouLH7;
zuOrLb;kPRjsSdSOZl&UWt^&b1mlLUjtgtcVms!<153DzNEmy;QCp#1^zG&9xke9#;
z5<su;0I!0FNb7xI-O&l7-M2@)yz66euHqav(kA3@nH#*%*v29Z*A`JUHsq3E^xxcu
zQmi{pfP~BxT!J#KhlgMrs?IU9CM)H1nWtc5g_=Kgk^K4nB%i*~X>B;v*M1X`lv^u$
zteX8q#@$n>wLtH1ucc3J3tv#*VAl;XE?yxyP70)3?9nQ$3Lq?tv+=dGM^=#u@zs$<
z--c)$8B$Os5vp0ZV2snc)@T5Xy1o|m#Jkh>>95xi927A`FhkpFpj1MTJZ$dWyF{Vq
zMFw6T5n2(YNR%uZQ}Yw!WElNaoEpzR;nxuRIm8{-lF*FREQ`-N{Sd0PF+&^tikap5
zy#KoJ6oT)_9<Re=$2yOnTDRbGIlg=S-=$ZQgPSd7sB9fPcGIfVJKwBvF`8dw)0(9W
z#e8qeY@4}X`uOz2r7-@e7*!t#<Cth8<nI%OadL-4vi)1eyK9yeVE+Z?%lJU}=NUtm
z-U7sB2I0gsjfRGPGS{-mH^yHI<BHGadq+6SZ?ZJLxom6T#eN~z@?`sZEsst|c}7|&
zIZzrVs<^DHrXdV{gx?5+8VM79wMEFNm0Ezg8NnKHSJdMI=L}Qy20aFDvTfQGoMvN1
zg#Hg)G7e^K5uoFi_6S90ZHqu~W^lL+d;p85tZhhq!hW%vN%T4*=8vhWM{^Z8?umqZ
zlJa5DK~v_|;$1PHODYSxRtqyZN(b4L+$<$^fWZ$4#1c}?RaEg$we$`)2d0K*8OOjE
zrKqVF&QcUbRO??^dDW%Zr|F&^)k`GpG<!$(L(L7dVy?Mg5#{S+OsWCV*bHrMcw+@D
zIiFTT8KOknnCBdo*SVl*=T`j_D}s#PVKftxLS_v&4$G}2=vnC)Lx?s7B0F1{ku_=9
zF@Yf7n!nJuRY_mFgO%BX)f@M!t?I(L%>_Q|%dRaSz_<m{UX1ZV9GDtI3zW#!o6v0x
z{|%Iwz9?8u300ir1xE}Af4x%cVqSu+d;rzPY}YjZOCxDTZz<=$HYcS-yqU4&4yQm@
zdJ4nb<?*v_8A$DYV2^rXU$w8hWout#&{ps69z-l0vlaop3(BUPMlnjrVRkVq%CyWU
z*No7>_nF)a;0C3g#3Xq|DEYT1hd(C|AG~~g=T=YV`#DojVNOq){kRS7wJS&KHZrba
z9}jAB6*)75p_&uVOhw&8D0mR*;Y?)GP<f^{8-ufUTNN7A^>wqDpIW(4FXrbu43kNf
zT!Aj2V*@@p%fvkZIrr0MQ;7Ev02Z@!DmI=z73WjM6+LL@eaDiu8D-6JBjEIc|D94D
zTm++;;3~AfK_?L2STHu5lPDiNGd~YtrS$+os=?o|dW1P>hr1R*Gxj?)>@|Y90NJp}
zhaZIBmbM(<qgrc`vfVwozy*1$m!ukVC6N;mH)`#=@B&cxxFL`>94C$gF5us_R3?jf
zWVAv=quct;S_?FUEGE2kfS;9R;BNwUuKY5aqPR_S2?LS0v8nqF9(X12iN2NX?(><@
zQ<^Xl>Xx#=;m)f^ycU4NQqlGhFHJS=1j9HX%(YqC6-03ve}hNu61KdBeG17{;!<f8
zt(s!P(HclMn+Lviv$x=Gk6%e&uwt6^f|iZqRNld46gsHaY=NtD7%oPq9&3Z75+>-6
zPSqMAdm)W_blP)!6sEKMS6T$C>p^j6M^w;rl!Q`~w{eFU_mb~wj=kX9=E;P}g*MuT
z>6*!Ry!6!&zu5Cj*v+15M%D_my))OB228*$(Cgjjn^g2zYFdA-81KA}N(lPImfVuM
zUD@~ysZ;IX-i&8OLStJ_>0++1vR74Mps5TH8l4x(`oot`4xc=H@HBb+^5yfF!-UgK
zB8whl?2K?9W7Z!Y3!~J$BV4KO`U}RR$5&1>v%^yW%U7TOK~<kg{wCwmy>PynPjXol
zX4!Yw3DDT4*NaOW3XEs7Y%|L^^fm@(iZBHxfH28~sY{{+eS80~khdl*(>%YypuZ(t
zHQRVsOKf(1Rp@0C%@eVSF+M&x3@}CVt*AZP$1>uWy+^3|7BI5BDS?DwWj0AiS+_HQ
zEdwo=eQy?+#yWDM@Gz~|N2pAIcuXr6vCj6EV^G_1F&$;J(-w5vQaeGh7?4;yzSJKV
zMV)bnT?zr;IKFKA9%J47Cpb$^>lsuRB~V}_9t7k~xvwT9Gyn1Mg`&&%ZXnjK<^l_H
zCn%rFM`U1*>_Wc~-hYx2p-Ke%Irp1P7fKBbn@*Z^8*N3$WL-`CoHTJG+rg|2Mr}nG
zXz80~<iBKF*k>+SdBI=a#8s^n+C4uw{_V-LN6&vdfE!G&TYQvm{_%Rag;k1SMz4Yu
z=*Fh^zKE~}O3`BWNk7^3R+pt-?6lpV+cy~Y_51Igh)LFe|DFG}9;3A3x>ev1@!J3#
z94$WZz-X}REGFoBM`z<JBjHD3Cu)^mWb1~app@$QEy=8h+%*vHSPlZcZWD+Gkd-FU
zqC-dE@v@&e?Fr+&f)3sr^@+?iMlKY{IOd{WhE4dspKR`6%CkpLUOs+!`26L69UnY?
z@!;hH@~fRqhICN2i}v5fA)MJ<i^*6@^lBcoJ?nZ=zQmX^tr14x;%Il+cfH6sEuq_L
zE-(6>+G}<)Rsv)Q*Xc0d+g6fyOh8I};D>W)S1?Gc7?hRAdMz3vV#hVyto`j@@&~qS
zb7%0)V0#M%i$};Mvgzph(GRdQtC(YFd;6=e?j?UCi2U04m;8MB_3oEn(O+4^WM^ml
z>z(9ppMGxt=iBedCa>YG@)<q5Dg_X=gypg1H%kV!!bfk?Gt5@RTjE0%6yaD)=s-We
z;I+Q1<Q`@n`jUP1J=CH;gG(vFLJ@29Cc`0t1^@>9ES=Zq<W_>8!{UOl$X^HWzlX(J
zFn_)MJ|AZz!Zrq@;^My9;U|be{vk^*(N>lb_44d{#%5^SQ8BwN^Rx4s5ZgE3e7(85
zz5NZ!vk!2P3L8!GQ8uj*s`I*@4Y#%mvf!$im!oV@lxJJ4LA7;KjW^jJaA=Zegc1I5
z@F;moKf}?upiX`s{(3M>HlB=!iFw?T-M@eJ)!)BL0G`e5zi)2uCOcmbzxey`%dh`m
zGM=B#|423%Y(&7OKMXdNmu@kHZV7BwIVcbKgQ-f>%QT;0#wYsC%M6M}Wy#Lq-e5c3
zS%b@+lf|<v8?(CN^nvi4Z0H1itw}3eJ7Ic=Lv5iPn|;5w@zc}iKRkGPaMU@bl=t|>
z<7bZ^KYRFJkA66Q^6cR7!Lx^t^=KCc(P2r}r_x`UQJJSY&u5@0)K?i+9WiNkQ3`A%
zC<nFvI?!l!pb_hbB|x^@!vs11vIO-I_1PGTqMEP8X4a^vvbB}``RAWJyJt>z%V#rE
z?N2AyT;G%;ff5M_bzGH_RWa#2q07cGRYLbx34&#$Y6ODIJr)>nh%tAbFnx=&@aTu6
zJFn)DUMm@p&&MY{4HPX-A_4{+LYI>aKoS*_NilkZD!Ty$e7+nYVq_mI&j}8wxuDGG
zDM6+M{V=#nfldR2x7JJtkpTTT^Mdo>#S?xDQsfY_!4uF2qb90iJk4H`Qn-uhCQ-58
zEQKa%qw4GowmTMB4~arTW_R4)iG>+tyzjtj+~VNC_{`yu9O;{z8})SG1@>?@$!dJ}
zaQe3<WqRcTZ$Ma03J-0{DWe$;i7HgqgriiCe(3gG=3(RTJ2dB0u#BU=UKi$x;s9uB
zG8(3tCEsa_QaRi^{N%Ar+XfsI;+8xwad#z>?lR|5@O@EFqGg+uf&a9FrFJzWHd5n6
z<8J07HmAdj3VnUJI;dj8a9nLU5gM^mV~kYO26b$ij<T3BhIG(L#&-EIlG0_tlEE#W
zk=rgflz?<TV_rV=j@X*8^z*=MwEMt+A`FgqOXtE7KTkI+mbO`9FKp|LdZ$m~gg~?k
zl?u0s4RRL)ZKyIp!!wJL^5|GOf3Dm|bTyPbJuq-=I7Vzd(T-}=4&xd=7~nLWNW2J`
z@RuM`l$)9WI>n?+>L_4d4Z;Kih^KGmBGC!yJgt5MZ@~w6B{{A7cK{6W@}j|D;a*Fd
za%`*;ey+|@uEB<oJqP{;>-4~#ca)AN5P(ThFvsUO8F+FA$`N4#4R+`rath0<V|1Ma
z5j@;F=mQhTO46Lr?`Em|X2P>XU5K`2Iya;Og>m^?(oUIyeC6d_1a*0hxjP~8Dk7W6
z8OZiUwM#A@<su4=Ty4~?lqYH)XQFm*UJp!p04k5$B7ngb9a4;)J_JajiH=zX`|M<%
zPsaB37Roqf@*Q-Koati_ygwos!8`~=yuL_l`8o$)bZ0aXC(e%8fhCDsNKiV=L~cPQ
ztr9i=TQMtt2yL-2Go-;99$u2}n=_CPJ&%0!{x8$K%BTp?dE}6nA)hgmwmS~C>sTb=
za5M||70n?P?5+b#`;O8nra5P3{EqeV;RzZOahDE59=b=<(*e%ksHm_nU82Ja`W0w?
z$Co?r?9X=J>6v#_x2VR-trW{O8?YiW!tBkNCG0YH@(`UG?hP<XWa1gpR7-AbzD#Uz
zYmvJf16}LpzFED~A9ZAz)Y!R?I_xX0k2}PL)|}=9pt~QlPyPN(F`btRs!z3u?{rkp
z(~0EXc~(WyF&{DI4F(^Ym>(%i_(az$qw9?^cK}eG`b|E9h;j(w=s(fc$4Vo{V5}>H
z4Xfoi(<fw@n!$z~iG=pq^JS`nzA!SG#P@W(7D$jtx`8v|tn->GVC)ZNlZ?+nkafg-
z^B;BNoWtQuzo3qmqwvXL2<>)KenJBB9l2_OV4k@`K=?YG2{GI^l!PiEQ^y0xKM@CF
zDRAx4nisH=X=rK*(rcMqUD~X1w~2X$prB*jBOmIP@ZSobIKIVyW3Nd?+EI6ZA&IAX
zfQ6-=N04gf0>Tn`hzA)Hvpdj9!B-NHO!S^UQ9jcWEN<g0o4GPxI?2=V*$VnvQG5vO
zb8t;W@cRsCJJ!O*YC_v-IA3~af`2^`7okpf$uHUHO*U>id)P1f_+jgXPN3|$^dZEd
z+Mh$#ElQ~n_@TRPo7S?KFUKcoA4U-A>xNMFjYm-!kN}dxP_)s#7@@iN$B_ab{iBIB
z$tpA{7?~16-xGMAE3?rYtp-l^xey3e24F`LdVKp^hSmCIZY%3~^ju!yTiFyUqA*Dl
zsx|ooP8+G+k#<WRn90DLc3-`G(p}b6>vyCUG>1g$Usx2pe1H`L+p7A4wSnqc)POg%
z4&~%K6%X$?s@@@w!}5Wp9}Pj<cPhP^y_<~ViEMNFEPa13&LZue48`gl&Tiv|cy2eH
z-Nd=)FSd3qV%|+~A0ZAF6-?>-Wma0cld!5$t6L5a0QmYL)F~pN&Sz(3I#yzJd@5B7
z8Iw)Gul&3GR4igj(=+_z`E!V)Ri+s5DymNOh1lfifX`QSvT(i<mQgDfxAUpMZeK;O
z8CCv@eJ(Adr+Ep*S9yO-4<b;xjKYiM*qENnN3Ch8*Yot!OpKUM$2n9ym4^tPLd2nP
zZ@7S3+499Kr{V4Xq-8q;Rac`zdvhZxmeR;6d=}3Q%soSYcSd#S!oOt$71GUjykciE
zj4)~1bD%dQ0?}Z~^ky%#Usz0`97bqLX&5;Ql_tE&V;$0=SiE7*O-xIlYO4(zD(Tkk
z2joWh@swwe5i4Dl#c<L<GP+3o9c|>VeTC9SWQryCvpqn8I+9TU1+|eFP<rk36klLx
zEdB0#fu&J*mn=)};^>PIrZl`n@JTa5T-_I6cVFJYhF*T=9+<VwT(L7q)Q3k`+6CRr
zTF6<_8%6h&Ke-luJHnGMo7QD63!DpMJ}{?7FCN7^#gb5%a}7)NAiP45^%|}(=0hd@
z+H`nxRNSVyG>E)Z)-3futZx%T?XU9sJSiq)BF^if2=>d0&%sYfly?0<T8Zj`kkcyD
z8gKa2@}ay|cix~uZV(`u`FdxSHyoFIhs^_blOj0TD^;X6-mV|YpXOhFlXl13wTaiY
z6c*S|r^e!CXB#xqYu|m=49{wp!!-Qk-C6uLc(hSCcQ~6y6zUNw>%4;Pa|X!JfcQ&z
zU@6lPW}F!37(iwyLpf=|%JIM`PoF>h$MI*-oSd*}UB$78V9<n8VzL;$>26$rFX29&
z>G3~3*&l!myWj^rN8i$3Kk58Nl&j*ZO1|l|mceOBF_`xboA}i;n)2wFhsJbO*WMpz
zF3$7MfBsX}Ku6n!sFehrk}i&X@bi|ov{)E7AoT5+A*XZI(fko%>K9ot!^odmQ9|1O
zSy`M+vWtpxJvKMhH?KO5r9-YK*2-CJ)#XUc{hXbLxGv_SbGxZ4cZAcsGdQ@{O;P4)
z8d1+z#cvU}0fy{5{SDDTm5b~wfU3M=#R>@Pn@`dbdw0AH#NMc~6H+as$xHv54E+5m
zOk?4yuT0-t$;>`PuSX$z-GgT9hiiUtrja{dRA-=xt`C!SOdFznPSn!%^<H3kUBb0`
zr<9#&tAiqifEja<6*(h#E#kMX5_;h6%1*~H*&y5pHn%!Y%WT})3+QID<KutIj@jGM
zWM1W$8R^^D@zpcgaXzJy0f8A==*f@~j_8QhH?XI(oP66&Pe&NtOediH%{sX2?b2as
zcNh(x6<3%$o@W)e4n?Ugt(I!#4SF}R?XYcTv4`n&G$|^pl{0sXdEjML3_U?r?L*<y
zA|3nO{%O)Wh_pmIs*=VT<qo$OPm|=Ym>iwqOK~E+o~SlbM+oJyXLinpWL7L_)5lRZ
zPBF|?<GD<#BrM)$*MwD(_V)RCD9#TIr5nC6VCa9=2io|9_0GCG+d9nQNp=Q=OE%;9
zB0bAT$Nx7k>Wt7RQABf)m1L*N*JfL3G$JRlgjh{Pk>=#dsQFYSVQz;8g|?&t;$0LS
z03h(%Co-oMi4*}6S(W3ZL5j&_R{MC!Pwn%8RG1X=+IvVKSGpREthfnjaWN}pM~a?t
z7li-Hb(l<L!^x<Kgy~m679;hmla5z3;e2#2?j~8}B%nGE2!g7hz4t-<r??$J;{8O@
zGu@Z=RO>!4Ui`Uq!D=y85K^A$D5f=QxQ?Gs^-};%lo+vTLI{_9EJ%HwJxRevu(EX2
z<gI1J0c$wKN6AXk5r?SNBV4<)W!MGovX@Nvdm6q@8CkYOB&s0-m`_=6FD4?lF=j1;
zL<H8sIm@OPHOo7*MEpNxQ>eT~4vFJ!1r1N6<K}&JuMUe}ce^pZU)WvFN00#I6A+~-
zsXMtyP`zNuUC}COd&AKy!t#G?@%H8()NIu-$pX)rEuJzLct?y|Rk-T2=_VZYr05t&
zeU2kEaMWS>jK=VQCtpsTwu0t<N89damQWu7We}jqD(9hj0wE>3DKsm|8IleWZ&)Bd
z2!(v$Uc1^$6f9m`s4c3U{Tfj1>|>(Z4NxmoyXRQ}s>Q$yp<1PYYJRdPVXIwR(6-tw
zMBW-?3sbl@+eby@Eiv!w+Je+WnD;`qFu|`H^UKjZD}oz=Xx6d;ucD}~jz&IBE3EOc
z07>2gy~>KPO^8dn7H4+ytxt+-MhCf6YyMWDZ*uk43;`-xm|FTlV=RXut?M#Bsl1Ll
zA)k|otqPv?z;4AHbaN^0Q|<y}xowL*-yiYLMX`|<5~VC6u!z%!(^F(gZ;?ejMoetD
z_3YcyYRzFqiCL*+8*TZO{EkzO2&k)B;>J|8VP)(@%dr(sr)9!Y6nk1w9!FHweQH)v
zvSER}rYOhxG%c@{;Z40<Jq4Ol&d<RHJf!w{A$wl}IIIQF$xhor^g9HP#QStW{Y$LK
zO~1r>^l#~fgx}(?;#*b4gHaP%fH<9XJ5oLD&}C>wQlBTL614GMVtkYgxnt(uCp~$U
zdh$vfeV0<U7g5@26gd$6UR;V3)7y_<5{|WSe^iGTaU1_yF@xe`>lNrWW+BhoSxdLt
z2$x#V1FH8bbQ#rb(g`^EIlVf4IR_jbyLV!?Hf~m}%c?<Wpsq;gR!KZ@;Q5Hwe&BHV
zJ+}eq=(YQrvE!q7Ioh>wAe1Yeha<7o&8K|*@2~#D?yAZ^gzG=-+}r(f=WDvpqW;77
z*I#Xas{inz>p$!&<sTF=m*uR+N3Gka_V5=h-muGSH{AQ?9;@9z!1^ZH{%ZK;*TbEi
z4_CY4CD(O86#*3r_xRTbPoF$`aQIkvWpx&F*!q>FDCboh*uaXn8};=(<wfL`S_^AD
zVLna#k98xmDmf|YbCLOQXRwVVvrGO}g+A!}+k=<So;>?$n0%H_uRmkiB`cbVSd5Cn
zh9^Wno6pELrZpBTfwjU2byn5KCS9|R^uC0)q*1kHw%Q^W{d|VoLeSiY(IDn>n%A^L
za+Oae%onVtneIh8cXTD9(Ef`agO93&#4fKOq0|D9PTMBQgELPiUAL>uZ1U{+%U>Qm
z)e_<7Q?h|s=}32vqwU#wXN!vqLe>PO00=8ANeGuY4s5a5-7OK_N=_p7s9e?$$GmJz
zduD|9`N8o|^Q@{|9esWLrG(956#nj7qJ3964S!dyB8WYJyn!Gdz}oJ4J)2{aFKrdW
zAwgo5jhVjv44vie3I{HD=Vd9=2k!YyUjFI=)M}*_<YQarY{)X{wp)OVQPAc=l1#cR
zZowe`p4$jzo+vdpI~$yVF9S*X4Zh7A6p(!b1Wa@P^eJKNzGAO|6zq0A)s96yotP4;
zX6dC)lRKr31+FUP(=#Xt=+JhzwvvnV4dG?;5{-xB6IwThChbSY%`^5JQQj=syID`M
z34r)K^$iK?^`sc|$ce=ID&Exe`WsHqpapT~!$F|PFb7%|@ik_3Bz9orxxsjNfW|mK
zZ6dAb2V2-KP>YwtS+Nosd}xQ`o5q8ZeIppm%5O%t^YPodOb^g(jTTkwgk{hGJmQmX
z$LH+gOBloJ(l;Iz9HY$OMgv+IyLOlYGJqHn*-*`goj8WsYqmzIAY9~ApBYL{&!@b<
zugr=)8?8awT<P0TjvYGR9g29b(N03uPdZT{fA%`Q)z$$}wOR+pW{k7IT2%kG<{sSM
zue8%1%GLgRu`jBtLT3n{3@kyD)zCGD_I|IfQCfW2XW_&O!PnA;b+}1G@5!N9D7ak#
zpl5Im&QNeCdL7R(-}f;M;gAi@{DsEJ#R+$5h3eNPs9zAVohGPxV#b^a(Zh(ckY}Yg
z(dvtzUmQO_u%a`#i#C3H%OF(O)l`abfBLdp7Bm&~0dMWC0)+3O*JN(RJ_DsBrsP%`
zB+07^stge7JjHaOHBqnN*|XZ3l?C_<LyZf|M_DQFUeY23^;JQDpJrt~BID{_(wLzL
zHQ^Jg_FfcKjk-)R?E|jf(sBnhI#tBfKgTy&epkaJL{XZ*?I)*YmJwC7pN!Lzbb=b@
z$v=C2B1KILB6{X!P8yxhplO=Fbt9Uq;m<26tT=B&H3JwG2JZNUReXjCH-7Z|w`WhE
zKX?S9?IJO_ijf^p)MuTx!)#2kfVK9dN<=B5*w+<(RE4g|(0nA|5r9_48s<k~!hzv=
z9k#2TWa#G7Q>c{f=X%Oyyr#EEgU$~t7Wn?6N8QNDe4P-ZbY!FyBImRK2P>MrJn=Om
zXJHh&$lT{ui|e5EIk-~)pP0Fq#b&Sf{JCvBo;LPmS7|u~>296<GE5ekvSluo*1L7*
zFSA<-rp9>B`?bKNO+HJG*Iar?fd{)z=mz;>q?9k{AO{8sgYjVam2zSD4H+=}0xTH*
z1ttvt5;olNq`YWi0Qr;)l7f=No!938_Wp_|KAm1Cui)|{H-4R6tdx?HhNB-j_W~^7
z&cDirxz1mDYa7;h^wS0RtBC=ySor0yXH6D>t62TcCWVzyK!b7d*65?-JXBJpX7X8c
zVuucdc9tpX33O{atE8$<m<x0oAk-Jr0@&q52c44cycbIP0JPFb9FDavL{eB0PUk5O
zYW<k#uJyuKyyy@gy=fC&yb7BD(Y#0J2l?4FCDUOtvAWL6X@q^i*R$DHK$P>@Bzx<!
z8A!vx)*CWdHsQvvzQ`?14mwfE!Jts(Fpjl3%D4l|q(FVJ!A^j?r+|Ql1PEiEVeX+M
zE3-3v3uX%&B>1?^{^BEY%L8H~8z<>m3KT(OvSofO$a4VigY+>Cvi><ANG%J(gK~7f
zN*luaQs>o-BPOBXC=89hASj<`aO)h`&uIyFf!)aKY*e!sHBLIGXxHk?>|-Gw)IoeC
z>yldtT);KB-ifn9H}S?;aJ`ARU>z+%b!RaOo17dQeXE<i)CP;ljddT|7Dv-EJL!U^
zqXF9pSiAgCtGIfyw{<oJ-hMnOAX_}41;Q&mH;<?BZNf*`H@kf3WGo4klmFuPclKEe
zH<LBT3nE`>?5QTjuZYJSGsZp9hwN000;m`MvexG{cMRR?ZP6Qak7ZUJd-vU97JKc{
z)9_nQ(*9>>|4U-~cgMxv9B&%qW8}NC$^w-qU~{ML_#efs5hPeL%*ufYwm}V{!IroX
z6Kr~GdQ_0{3n*!}PVgueH0NjbK2?@7T%^U`BGv6fSHa?twu90ya=6M1tt~?WZN?Qm
z?c<XU8D!Om*pm>&w1q1krZ_<ch*k-6C0f^<=x`Ch!~tT37rA-UZ4%|3AXTm!Elcgu
zhm)-XWEf-ET$&6ckHiwNs1gi!hT5m;vZrS~4v;Dax}_M{qwHc<6Ip?$+O*tS<oKO!
zkDnhX2X-``+eHm`oQ-)5_L&qkb#8l6ebR`saev>Dg^<k_RQ8;*O2oX-l+63>qVv*5
zrmPd<0RIxl1Q<hKDTu~tCa<We($3@h-cQqV;L7CXE|PxtE^+xs!lns=`1t8zF?la=
zKfEuhXb<>Gfex@9zup#frVO}I!VCc}#(EMKw(nqJ%V<vMWl>D)eCn@v`jM(!EVVzP
ztIomDz7o|-_23To<omg54Q=^_Ew-q@f+VAiqS8BrO51S9e*-;!F|PTMs{4yC=B917
zyQVOV2AZ@-2r$uBD%%IS%%$mmXl!MycqjI1UEL|Zzn(sfBVpW^Bi3cz6YSy@G5g8M
z93F?R;pJ2Exjt&Jo12IpCDwHL_m3dn8s&(VI9nKBgVrx9mNEau`E125<L}RCFI7@o
z({<SB{}qk&&9Pqy;xdZ%$7SbikVlrhYnHWkdbOja6rpJ2#$tOPFm`;}`@g{6f5h75
zN2~CC2%XLEpcARgEvu6?lh%83#DMr2A_a(w8Ey}Z4klXZG{`SmTJlp>Hb^oXke$U6
z8cbmJ?9lOlIkCYy+zMt)nc&;bM`^5v#7j^3#;cm9TZIVmUS;tsG)>0?xBzeqi2_l(
z&ZL3+AGa{jZugg<fK|u_?}=2G5)~|uAJH^a3SbeIbbAttkV|yJ{)<W}8r3ukDjhA4
z$osZ51FS(8WVw(?IF}GsEE(ZI<m&f(EMktQGQFt6fe1qEh#zk+CWXAahFa2v9D(#t
zGY8g5QB1OQ8p`(W%^6SUByw6_VFIpkaW!QgkfOGHU4X4kaH2k(lyrLSfr5Mq`_Kmy
z7S{H|$QU&n9u0TEXHX1bNGDZ66Djf`jUOJ^Fv~_0F^CFYIwEvfVD>>_o@415&eO}x
zGweliNtOxa(A9CVI-Uw{I7%XZ`{})Ux#P=W|Iu34%&TKo7MJ-rs|2b&mq^%wHf9uD
zS4DP^RY2Txd^<mZ{QC{x%ghq;69)ixe_Fh9Hm}Z+P5%s8Jb@R|5}z+$K7V=q^6}xT
zm(LuGOD`iF^qHnGDOA(*f>O+MNIc=^cZ@or1ePXA%bhJfwmOKOSFCjykSOr0pDT7-
zI1Uw_CBGcp08jIA@Bs9PG04Va?#SV7q%2!>WN#4+7G@!9-l(q;Z4;iE1t|9I0u(oT
z5eycnU}oLhyl<s(JS-Hwxt|zyD1FJ?rG!ZFfs!Hq>f}E7&E|b_0{(BFPFyw@mis|V
z$F5+^pW;zZ^llXIaC5P6NrL9G>^w&f*?!2yV{Q)F9re!Y_zNw(C#-bTOSR*VWxj=4
z4bGhZrcXi4^%GBU4)pSITV8kX1t*>|2#P_Bt>Y}K9o8^xEHzVSsgMmtlC)eTefbMr
ztOKd=F-=9O(V>0tT<1;&(~V9YQpZx<FN`*jAg&uAa$U?*!^>QO!2x`!1!TS~lLIJ6
zPEFYrg-_49Hu#E{W}6WmjqKY)xMM+k?NU0Z-p@(`09sK?F3yvwu<6vaLQ{P5!sYGO
z%<d6sr*3Z$T3N)|?ZlkPZF~1l-JC|2qx|t*(h+}jpq^KdS{CuhBqC!~8~G-!rEr^J
zDCZ^{XT7h&uNWZLm3PX&nCqwE)W!=D2)`N>Vl9_7#K>(s*ewamr>MDw9}!|OzxvmJ
z1!i3)>aFE;mKZHL0fsU7ncydC`b15k__VgcVX-c2->x(?EY?}-{(B1yTVAk;wGi>P
ztFY#LBwhkRdJTJPMTtSHa~Eg_>B3Mh9l&OQ;?2|Km$_F@;2%w_T%0WDq`UV+Zf)RQ
zA<-@3kgz;iych4sR=m6|!3JLZn@HK&b=5u!joy=T+aM}JCAY?~C_#!JZG2tO4Re8&
zw_o*#55QZE+2gNgBxoYU#bt>1YhYNrwKc3faBnqo!UqZclaEmnZl@8EI@P%3Z}3v4
z8`<z4(yUB--?BnQ;6pEC*)*6{n>CTokM3$;!Gjy|I2L#yv+2=u!u-!<?)Scj;!5DF
zjA1|iHTW}4LvcOs;svQ_(T#vpM33m|lS$>~&=jslqH^wuqBi=UR(xH3H0huXk;xFx
z$ooX^dkNchi*mkRlcK0B5pIddU*8SjiM6GknY#R<Ic<t?*2RK<TgLu=z|h}l#4Uxi
zMG>}O;BQM`E1%oZqW)6!Nw8=5OWEGBzh))m?nZA;Q85_ejD!d1EUhY5`MThxgcB@2
zOz`>qA7&<QwS2AgM&1}tL<3$H4W0bp9K8c9Mmd7M;t+Q4k`Y}#o`z$dquyw*!6i*E
z2kbJjvRj$IyD9`iE)OhwUd~4~q#CCVz{P2@E`_Ca&AIlpC?+(gI6DJlqx?CK?V_XS
zQ_^P+wNar{g(p(f1{eER!IY!C9L*<bY1BS<zJUWa@tP6{W(cp;)hUX;>@2Gh&Q6`d
z4z7~AynA`f=J5%Cc5z+Nb&GX13ZmM#&Bho^t#_d!s%Q2t5R+-3onehw*5bz;?nb%n
zqmA6WZW&p?Hx#2YC-ne{U<BWYpfZ#DagkkISJ~v0oUSK{t9V7=-Ul|gWoj7_BM70x
z<E21o;`sPjkkv73e~h5pio;1d7NiZv?_l>m->a4~%8`bZ*GK&R@M+4DK;s5M;$?sO
zD~yt5Op3Gac3-rGP@TQ@GET$-GhkcGEsqaD&2R8WI4>3VI-yO2%7KasZ0<%xqnnR=
zFl0c#WL1Ttc5g}bqEVidM)>6(D%*t}SLeliGDbP%MB&(QWfvG<B4rzKmM8-c2mTaO
zs<!YWy~q=&BH6lSMEY2{2<#2uwX82dc<5<fR&}37*1+|d6M1c%!!1Y^7`y`UwD60S
z2HGf4tMSSuYlY)EF7^%5gAeTZ+NrU#ThV0&*hs}FYe7d}m5EEQ(TB7JIV85WsJRxq
zy9;&JP<{5+tT)O^(Pve`2*=?u7PSx-Hd4piB#sm2XE+n!%xez-@MGZtL5Ga#;UL;x
z$%(UBQ$Z-J))e_q=e2eZ6YY8<RUJngi;ejPRVt#vi1MaxC@7`s(mGim>5wszK_9)j
zV3p&%L=EgZHF5lX*_n@CH!eteP&$VjtLB-+@ak;Z1j#s#B8HFLfR=-<2Kh^@YK63S
z8#AwnI9r0&xK{SFdMa-u;+qA{dhWY=n!T-|#14dnVhvFt9bh;p)qd&S%I<S0*i~kU
z<^sN^IMCuq!FyP_uch^zM%(NJ()aB6Z=tvl3L+81|8$1IKMY4xz>h!W>y0Y{67X=u
z7Wdj|wGZvdqFW*@LIiW_phCD(s=nXyuC$9Ha$V&vu?nwUd)va-d6TfE4;po&gP@BK
zGI`yYB{=zFF=PDFq{OLcGLcktbzW4NW_iMpbhR5s9$%g3Wb=wC`<_r0Ji4GdNXDHN
zCFDF>Q!Nam^L#QUK)R0qxbXN2Iv(02;c)noaHy^T6gi*Ht7cDFmFKhGi=FNOWxM7;
zaNp!(&*AYOqHG3%Jx#JMZ+EmqNVUG6fjbXWUgv(QoftV(+B^8B9RbL37kxPSb>xj~
zP2Kpishx)S9!{Us;A!1m_3f*<zWOi>=dMo6Iw9*T`^i<tPVYFWii<4a$XaU)x>pc@
z6F$i}RC^A&KpM>9*5Ro#q>UVIo>4mO)L!*nw>#RpJI`_8w1PU7c-<agat8LhORZI}
zBhjeg{a$4!Iv*w%#fq2-2PYgwuDBg{B?zwM3(9bM7`r_(`}V;kPpht{qkD?Rw{&eV
zRpM$hi)#oPq^sZGj?PYkqJ71vb~i%#Oz>e3lCv_a@Xx8FZ#)QnOaPcvP#lsRRR|PF
zNA(=S1YD!a&Uu}5*&N_#PUhi^ySL_XTv%i)kwD;vuq+{q?x#7T@V;q1nOsxbUA3n&
zMsN%rHH?N_C)W4Y0?r%iUA!N27jM)w($MpGEFV)XSo>6B0^Ma2@+!dzz^4Sm5<=E~
z?Ztu%G3r~)5hXb?;7W?aFSB-<Vd=J)&fjSkSa?KevYRz2wg9{pl}j@GS_d7JbvU03
z{f|<;KoHxf=e|$ReV?BD{@tGYR^d^l@NnCwYU0Y@w6YvZ?b2r`lBvv~5pXD`zRaFf
z0*%!g{-Q}KVk08d_3J|K^M53p%qvRJBOi%~!)0-jo=mP4sztYb=Gxd>K3Rs-`)QE^
zqILuUivHvf>S4m;<m5WcCae=mc+y8+P}H&bypp*#11nx?wM`DIi-8pn()$SEUU7NP
zTdnR%PBt2+Ho^TE?~=>3%v1D8Mt!-w%+O#|l=)dsjs&<t&NJQUBerK>UJfRk^_@>Q
zK`0a;>rDhsr?vn7T2AZ#S^26A-P%#~9z*v!4T_IiTySB2HXsh3aqgVKz0HtmK-gZ;
z!i6?<<meR{a&39X@O^%OUPqXvd1r8M@I{|eF6QAari3i`JZ_(9yfNQ-d{pV@iaYA@
z<&NXCU1vJpjoBOF(VgVrvXh_YM1t#PIY@Gz6uyZwUE#?jJ@4yYO7Kw+QgjKIXSiDZ
zqvq3b_7<4qY0)A3c1jNFbcDq%rb%(~zuCyj!fYT#^CwqxE%R5v(>XJt>9%AMzF<0|
z10Q-PJ<_9`(Yt`vKKf4gZKrUTbGnqKNKZ8ml>B)_(czY?TDf8AZcysb4M_r*pQ-hQ
z=JXBwaBkzv`;D`0rc_LE;!f)Ca4**p7*wlye-6{DmrtGj^%X6eZ`t9f$BsX~hxi^8
zWjAPHJ)?}P=2uJYQGfJi+{Q-_J2>9p%{CAd+3cvN3@7{q@I{|tqUlXj7(mFa(5c?!
zvl%cv`=T20@;;5>&#tG47?n19P~`&9Qu4At`ns>Fz-7PH1k`*Qzfvetsn=_i8zZu*
zQUM+BT_TsYL1ae_Z2`v%5%S!Ne%J-!^?&CVGq`Wi&xT>9^@DHIlYWEGED{C_BGNgT
zVC=gxHiT%(Il0aZ*)hDCi%^H2OFw{Bo+D|@4D)-Tl!{W&A8U^!{F_d&H@*}wOtp`)
zgIJ$lU?KX|AIcT)w3d<%e#5K0B^=Rji%b<|mTl+vu&g(sa&-mr^Sd&DMe93jVdJM_
z`ZTgW*g8SWO0jM&gbg-$dodxZ#I{{x#3P!@lfA>KHAXPitXbk+(P!n84QQTTchY*0
zzPlTQ=TI=<O!lO3IfY^?ll%{W*kzNv!+J*V;QEs(A|a6|Soc%MMOL2|V=i9eX#HfJ
zWARUf_C_5k49A~=t~Ux2Ec8+Q^*tFXD$DYG;~|}g#gtr%HK80vEi_UzO?K&@ZmO|2
z!8Dq~Vk&p6N{5J>G#Nb?#`R@%$jwK;7unj)7DYuHJg>}eKscvklV8?c5h|KZ1fV>k
z*rmMRYwDm2VXxaX;@YjVz&J>*_Sgy(Y-?R^M-|}@cuiBv*P$7uRVERa3~d6S0~<9W
zwB*`*ju9oQjWOxh1ks_nWEmH4;zA?yhf$;gLgy){rkpVxR{7cV`7A5bx+uF!V;9Pl
zZ=HxcPn`?V_Sj%O!DYyi3BwO>hkTlF-h1AG@9(>}<bH5EG~J2~;g3f?KM{2Y_Az;;
z@0FX6uRho`&T$jB(r-O0{WiQ(uof@6(r-V^N~f87rFZtDHnp?ukV-9tbauAkC)6~0
zZQhma@2`do+ij=COmq($<iPv%4hYpz)Sz^mTP)Py8{8XgccLG_v}H9+!T0T}!M0-x
z`?qGU<-PB#qz3(xzQBMzp<oOaZJqUbc98(vO+aBG5(>DG8>Z*SZ_|s}BpW6jxQ9q5
zU{t1gIvtIOLXgbnCxrDGc2_W`z|5Sro0e7f^??qCTOQG`2)-6mD51B6^1btlnADx2
zsBrwP^Rk>|YLk6un=^Ho`|c*{F!$ZVWdEnM*>|^@s^i=-+l;f*bUvxQm!3dJQ)Mjm
zmFJ>5bK9w%uSjHfiZa{uIxTsg%wUp`N<>vV1*~dDNTxo;p8ds5TW%jXCQ|o$ZYL8B
zYIiOkdQjglkT-w(tNp;PZenHeEyDs20_<w$AUESzU)@XoMo{#%@o$psZtvXN*`-)!
z4avV>Z<Fso{oMY~x8IR%Uc)QvGxPlf%a@w<nk(`2n#}8blGoP>z5%Tzbcml{aJz4n
z+(X;!m+Y(WM?~>HE6QuK)1V=((c4M5yuw8ISvn_Le~A?F6FI5L4;eTKB;Ss*$)q^@
zo+(!M&9(=1PTHn#-el9{+p0S8HasjY(kl6N0RMYfyd?t{Z@<sS*@!eAkW1R?@Jk8-
zZpr_bPAeGu;(zs_N5$;A%+JniLb>03^Y!NL_Vzc)Awk^(9HPQT<Vq$gA1?H~u4luo
zEpih~t72Y`vO!UvZLtQ`)=4$qWPiXJOrB*|$qxsQlBe`D9F3dS$<M=I4~EIclkqUo
z&u+5&_pf&dAOOwg_TM*mc9NaH55L?VezE=klJWd>{ztOGAe+8nY>q*u>aSaDhqlD_
zR5?7@;SW5BCFy0FPr&6Pq2IjBCK=q6JA*F<+iM^_aQb?dWn&gQh~Y#j5p?>rTJ0DE
z2uWMVtKh@p;-Z+cm%uf0!{*bBy*09unvY)|KmSLk&sG6x)I6<zeDLJy<44$X+u!Qo
zA5UJqz-F6)vFJ<Ov**VzUOxWun0$KpnDp2M>jzu!gE0|g;i94Ci}9RLpA#a%iDQ&b
zugUE~gf9`(OKz;JggU%vDNcCajy{YD=J<S+yn6YRpbqSgr(_SHO!KERc6(=xk@PUZ
zn{wGx^APEv`Pfi;F?}lNabcg+qp|j<RZaUcEoqCFOw_Togp$bkwVuxpI&BEyXwOn-
zUZ4{QJm5T00>}wbfHk~ZP19L*UetXe1Yg3-QaYKPr~Tw4tI2;!d$QJ^1|U^B-a)3*
zc<^Q%2%Odi@;Q}*>1kq#5H~RqA`6HoXODqzCPjRijf%5r{s$DYqoWMJJt>o|`@%<N
z6CH#IkHQ!BBpLFT1&ph<ON~QBH8}@YnOq?mgS2J+6Kf2$YoB}rCIhN6QggI24C_`F
zMUBIp0Qr;|?8+sqwmw%}X(*o{e<=gdY@vyOgZ?d@s}i!0Sj?OUXCznXCr`HE5+mVi
zWw2=h`fUlDhl5EmVamS%<fr9{OwJ4EBFiKxlda;}D8mFn=?6u82Z^xFvuOaIKw!V)
zk$g4gOf^YQ39}`OhMd7FU+(ry^7s)e&x?#z1Ow&u&}c*W+&B~T!u_(i37!Y*pvktM
zbYM^DH(Rh>TXnHDDF`52_(flF&0=0yq$#stv-reHK54-#6z{<`IRem@2GJtulyB`X
z9Pzsrli+PCLWu0P=OdUHJ!C1I`JKoKi?>H-GvRY_LDX6ZG@d3X9I&8`9H0JD`|S;9
zuCEHsu}pm>9JJb40-Lq3%69JH=GZ&Z*LQu_*UYtZ>XeIYTwQR24{g{3p8b^IzLZ&h
zmB&<kLIvon1RZiV!4fidACF=9B+$VrvbH5|C|Y*<0m2O}RLzC&U8gld#ASm<6mrpw
z-ZYMUQWWF@pT>_(rMz^a>=ARlGsi#7E@nlUme<0&nw}UUFI6=6hNSV6Yc)45Y4Il&
zRiNREH)oH?z0>X8EQ1p^)d3msu*`zsj>&B}s);z-PpHg)nxD;?G>nem$<=vA4mCgT
z+zEFynwJhqA;6m+<)vd^6tC1D%VG+G)3MW?*VW@8g6lSc8bVq3?#4XtgK>{~<0N-C
z=weOV6pdmX4i(`|%YmTV^1v`J?lPkd9UoKJ(qHXSbV*4*>eKe<K|)R>Z$uq^IyN-(
z9A}y5=F`7(8q?ZHuBmYWX(94yItF7nQTkZ<yp+fc)6FWw(0UaJr|HdF4Tz0Ru@IJR
zREkV4zX=^bWCSLRyd>?L26H`-nD$0xyAb_cIPaQI<{t2w;1~{+R3udY8a0+_n?=DZ
z<bgZAwC>zyjfM$tvg?@KJfmVhCGfLWE6KGbokq#BMg+(@JLZSB+u2Av{f>O_5bmXE
zZ_nj7h@9d0DxJKs*Lehsgp3DroL=}1$$lMrP}hW0)+lu5)d+IEfE>y^2`bF_QbRt8
zS$YDNww&et;{EfQ2w4zeQ{v@p@Gy;KigzCUmNK{+hoURIWi3Y&L<9Jtk-NIX7JzBa
zl{IjuW9s+G{{mmn!C;^wdJ#wG4Up4M=!Gm9)OW(ikNOC8#KrKCHShF@PNK66hXeb;
zbw!rcalDzRRw>%ba81{|QZB&Pgf<%vFWvx}x=aMx9CvzJ%32!dPnW`>{<*Ga-3~J>
zm}uN$zk}S^=}Rp1apJy2k?lIu?4RfGPfU9brmhh0Dc=$DJAh1ds(D>pfSn4WtOhG_
zZugU(Jw2S#j0jXjriBk6&N-SU*`5S;q+0Ek#BEFT)+jGvj&y1_eiy)$KuOL*eNl`d
z>S&B!fNAiwP$`D498AGY=Z0EyW&6MhI)MwGJ3=d6jJTAO&HKO+|9LT?u^Bc#=2H-V
zJt>bJ@(_^jF=u7&z!m$tOvhs$ZLo1-;?d!LkwR)7OxA(3VkW1a$A?C3f{_fqd_OcF
z6m3p(|MdKY>I?{2`?w@k#z`ay+vEr%0)XeFt@)w^C?vEs{e3_`ACK9^!dJRvI&v2!
z*eAulriosgR5`d`ln};VZ$c6n^=fs-zB%it*s)3Oix^@6WLq8=LoPR`SMY){Sc}A8
z-K=RmG8}bP+lb~2WjQQsnpsGXbA6Wk+*<Ccxyi40pVQbdBCkWqKk(27X)k&M<Unzl
zm+k#1|HB_1q62B;{SUVv#a&_TWUkEa^-)2cwFqR%Hx8(=>CNHN{G@xe7EO_|xVNfK
zxh@sPj4B#JGWM4SqE6bFDU~catFyAAp4uK-XW_8b;*|!Bsx-{|-o*v*JE#0Wp9WvF
z7p;g|&2pVF7&h<c<Ot^Ibj~Xz24;+qTkgOluG<JwUB1a@DyA`)<Q3S3F7k>+=!Yx>
zel5}ADrg8$098}AM^nMBiqo1!@<V?;6bF-ybppxW#O29SEHy^*xbs9R<l?DMX~wwX
zE`|y>&{~_0M9VUnxg%lnUTp5C26RSXY_~6*@kLM}K+W@fKo}54ctj>zBDBX4pOE3t
zz<O~4IfnBo(Zj1*HX;Jt2;5mtAWbq6=pd^FVf7%FV0lJ}93*pA=fzbrM?K@=(<eTG
zN$5OX=-W@+P6x4}#a0q!O=wi;LzIwYC!6fu;q{COlO23+>NF&`KAE2-|MB(qH{0~6
zD!LAfgN2tC9LY$z;P?sFB#m7VCnbZSADIgk6ufBt@Z$6oo{kr(Al?GF#?ZXw_<KXp
zzR%_nj@NhEKq7aPqGw);=yY-8=^00bPUXW~!$J*SFK29AYn$sWI%$#$z(P24tZAH=
z(pGUMGYve-%Ygc~ie&~4a?{pd<d`|W=|O@v>+}=KFBhSLjd?jq(7>h{(-;7z;U+MS
z&msg9==L76BLZT%;p75KtNIsa6F`{PR=q1u`w%=7+<||?l%QDj8q9eS1T|ZVMYXWN
z@qKK}8xS(kEx%#Q9;IbAF5)QqgS*4u=(1|(w+AnuJ$d%i(6I3MP9>Gf&WYmFl-Qv&
zpN-K~1RgYIWl<NSVp7qP#yAIcWPA1O@V{O>rkT9h9?_0T103PW*MZLIK%MyXraWOj
zx8|<3kXlS3gA+JB+yw;Tz`G!ox(KCt9yaY%6WYB2Z>wNSc#+oU;k+YGhJ8LeCc{PW
z>3+=E{#7lS)7D<F8~z}4i`_w<TaZ^<5Rie8F8+WD9)!OE#eg4}2!H1dqPLg)cZx<~
z(X+kaEr%me4LY$?lLfS%3(}Zgm3f_|SmHivxxV0}&O@3Nf<4$0y^ZcNbv{=ZSVJMZ
zAai3Xr+^s@72v<kqJ)5fl`VKm^GnTq>QZ}*_dSPwil7E7Ry>-|CONo>SHhaN_km1(
z?J^@uJ<I|LTn4c?x=V@T2aPv!KIbSScuXm6&3RI)f_Ru8i28hQ`|Gd%o@~)*8u;Kp
zcDBE{chA%7SynOENtl*ZT>`TN4EN<=cd+B^_$Iq{?5nZX+BEfzvpO3YRXKx$ERez`
zyi2W3TdN@V6`H6##=SOadTyEvhwZMAkpyIkz)_RSgY0MrJUg1=Zz!C;ku~*`%}q8O
zH>c?tx=a>vJKTpc0WYy!WTllPkwLHoXSLIjqcf?Q=g0QEaLz&x=|Mf8<zv@e>fp{4
z*9^6xW;&-+p>3?zx3NghcGZ}yH1eJk%Z}O+m=Ipes0#4p&$KFE$1=6jD6n3XM_C%G
zI_jW1?~!XDARb{kUhrnNaPzF7ws56pWD9I8de#<l>0<9sbP4G+om~HsHQYyWj!b_M
zq_JDsE{QhHuEPAnrw@_=3HAcP|8!V4G*DxXm3g#o;GiVLl63yL%D2hcDVm2hfki~<
zEcYg9$S||hMPC9Vp00L4cRY;}2Mn_dLO0}D?!*Nf)LmM#Vf@g=h{GyzQ%=y%dMA#@
zY6RyN52N09<#{=JZBWggsWj9_uiXjL5ONWi#W(FiIXcfTX$D{iT4Z<@ne^20J%)g(
z0}32#Z3BrCC6XN8n5;M|JCpc;KF(=D8$mJE93wj*=l1n#Tr!*aw%8C$8fxeE$Qij9
zFXWh~3J84h6mu;^fz@67B2Tv~j1DN#_SO;0^m$8Z+0?a?zDA6j+ttanS9hf>N#j5n
z@3(xw&(lgA)(zi15xATh%$*bm0pVhitAwC=TqG8E*?<xiwGF*A8;lEw!GR3bP^>uK
zOdztkOKF(KXt^Ca?l@DitAi<-gq3GO%dbtdg!YveL>50CV*Y-~ot>{=A3S~X=)vLR
z<44bbd-nACgGW!E{p7ptDyT%Y?{F=lyw>yVvcV{v`XB78E8o0tRRDlF*cycmH{Q6R
zPStBlZN6F)f;#mIYzfNQU9BO89i)W5wKfb)&thC#4lTBQkJg~}R+pw&CC_oDh!aja
z<Q|<6CNjSMmC-Pfa?vnKnes}i3@hdUWG4Ss+{F9PL3{4gxWb?<)1E`E@6hgz<r5$K
z#K%4?A6pB-8-!J_IaVFXEdF8o(Cd__-B4hn2}SSYQHXF`Av#VrRMLs>(irk7JUED4
zfQc*`1Ym0^5}PK-D`~v$CsmQa5x}=Un$8MRc)}#b=_$IAilBvv(*>zWx0_Fs&w1Ho
z7!3)|A!BJ|i49g<nJZf{0P1uTJ`XGAHX#q|R+SQ(S&!~^U=-_RSGD&hk6p(tqa<9X
zq9q>Inz0lCs>TzV>!mawj26{xS{<P_WpfrhM2jAzTcDhk9jG{By7hzgo=_Bjz*^vC
z*`v6q$FX+B2da)VUGqvojkeeP64&PY=MeFiEMke)xcI~*J~4^+!z5yF<Rx$Am7Kd<
zy`7gmeaoD{TOzTQp2T>ndoL&QJ)*4L$!v+IkN2|QI4g_!jC=A(>()>3aksH@o+2gS
zKs-cNjM}s{#tkpWiM{LfUgG`E0IDfaqM?)?_=7ata9jcqhYR>9{vIp#(AGztw64qi
zq#_6rHK6ue;MZD1JkN@VFo_|`#_gw|#VmxmLYtV0IJa_Ju=7H~=#m2Ihq)Zv38tT}
z$4}SeM|(ZC5n@*$$gb?X-nu}$ic`Dn$-PBVT=@xZN1gBOB)?}Awm;De;O#FYA}_>q
zba9U|nPzDs=2@q)Y;fEeZ+oU!NPtV9*_daBTR4-qh=RB?w_+L&<o;pK)nus(j-vfZ
zHr%eMVv5KI`{>8|*oXSqNBZao`c*y7haTo{8jDfJy1L`mNZgYH5nDAddH2qMt0{id
zl_j=j1s-N)agv@)uF)fzzMJ=xlX;!|@4SK_U97FRwt|!A%UPgRWMR(0trIrC%!rnm
zU1k{MD{|X2cWXU`{dqc@LG6@jQ~d_5{-)bo*G%iuSPD`}ir-NEQO}=mV`77U?+>5n
zEii`OAU((@0`?a<2&T0FE=_(nzM$d17y(WLz}0VEF>MQt(}HI7dIiFdUT!>1fT5zu
zm*&(86(1xC1e2f1+6Ne&&a(Q8G7nJc)i-FW1fD}*C?tPb<YRj1Sjiqgk&8nXpA9N9
z1Jq4Zq>WBgMw)DzAUlxOSnVE~*a%nsJb|p-h-AzQKTgQ0H8-&5D{~xAQTBS}0)be0
z8t@sUp)p9@;<@nCj+ng(5k7YMZDPk^=7l1&Nf&0e(@JNgkom`%@AP{e<4bQcZtjXU
z>*L=f-|qN!g@SVc_t%^3n&1m7!(bNeYxF$sU>=RWOeXD%OtH#$I7gHN^;T3fMW&Ck
z#{DQOrFhN;_toY#XFT}zR;S?t(^hhGbHjiA^Upukv3r(iqkr?K@2op#T4DNVnHJhv
zK*NzMno0f;DyZd(Mh|Ttjr#IMD_-hR`J$Efu_?M$M|cTnn;hL*)LAjFXLBr?#wtu<
zh^Z1`s+O4w6qOP<J(f5X{`4hH{%EmjJ$s~6ETx6mk9j$jo~MG+fvYh!tdvI`{=sWK
zMYQhn&k$E7DXTh8`0n#*f~r&>>eE4_8!CKhK7~Zmr&uYCtXUnCU;xw#D4Iu9qLNhu
zO)K_@$*Pg|v3rlsz#=+f3O>3zqN8J9Da%++7>W0k&~L^um_9*~K$#p-3BOD9Pm*EV
zl2RHwv?>@pW{Iv$+?(gYnfo@fpaVWhv&4d;+)dMj4bPzdA_-v{3+4m$$_B5dZ>D4u
zMR_1P!cb(v^N=mIlNo9294o*}EGi|dXChbTRnp9>iNcqw4)>I`d)+xnkjp$F2ZAqz
zebjkPGzHc<%mv`6oY4B`3rrz8H?kU0j<J$Ky~!p@1+-K&|BQ1C3D*S5@H%sF8Rr^~
zgzR?569XlfgKP`28#rs{_1+Rzstu@IyKB@xq~<^)8EkCMSc~NVc8N$hpUsN0u3kPq
zIP6-3JM=FrHNc&&0G5qO0QiA?0-;|W7<Xsz1#YT2xRpWLPDsrL4~@MYHMaaaZ2nP`
z6B|^B`E#%|D=or0pEBe@-BOmLlh7enaAlQPX~+$=d<_C=o+t(#an)7rsp|mS)nSO$
z<v}wg0mmOsp+Mkzyos1`J2<1tHTk{zE8{%Qh<N?{aXzD`zH^*S)^N?FpX83gXIaCZ
zqh(w$zL#zs>*KSz@d4t+K1Hz=B8j`h7+;_9mA*AaUpWO-o(x|yWX5ns$JW;{KP+Tq
zKQWu<=FYx0;>rNB(<$<oF4w}FK!+~~_fD@m@}Y%B)6vvzaOg3_4FpUm<qCN-;Zy{G
zIHFllyh(>_QRc~%W?N#SjAo=SnX!FLE4jnmgx|Of6`k6{ggU*}*(fo}y5lMr5P5>^
zjzSo*hx8m@|Kya|xF@6cw89G6V8>8=JuNdadY|pR;66kg+3&P6Pqj%e<bCEV`#gaV
zy=d42ts>D7Nddk9F{c8j)Rg}2wN)`$WSnq>qeN^jcJrIBzv?xXiD`qq`yVs*i26^?
z16EC^IRwd9w}C;=Ib(FIa0e|+7+!<umx$;(Kbhd^Yh(Y|y4-a<LeRuvF5}1X<*wBf
zt%Wbss|fW*F#blc&9OyOS6?qaU6M-^LUvjrWXF9+NZ3UN0t8%WGO7&E8e{Sr?KUu8
zqZ`r2M~cOl8)CG5vW`;Q(jZoVq}jqw4QVZVTW3>b12k__cm0n^ezG1azC0}eN+R_*
zYcG=l!Ja*+)3VbfoQk$*e{=$6u2mrb1U>b@k^i`$kl!VPeVoWSz9m957zC9xu+bIe
zHRB&49hd!2I6B!@z_-=-Qplr<D>g7PYOq2XJ{cyRUGneVYV3!4xC5XvccEDW&X_;m
z(9$_RhVh%z7dmY$emjff-rJDiHW)N;*)#+}vzNGmjgfinp3YNYqCRZ0+n{o#ve9~{
z$WmL@Fr8VJmcU{M)2!|^$`Z{6Pi+F{Qo`lF7OP|H7($vvn?Y(3AJWDfZ85v24(?ua
z!H&>5h_ir(ru<0HXAtHn)zmkDmOu7AJR*3FB_0clT^8EWf3HD`4RL#rBR*W|PMBRU
z+6k`5A9u;l=F%N}HHv7_>AlAapSN4Y)2Pph?|RMUIq6Qjt8<F)g2g$b_hF$@n>S7~
z6hLNP?X0|vZI_QS@H=dramMqOqxV*AG<I7@vzg04Dn-bCqR7F0PwqQrN4<=&pSG}}
zdd-QR^ViZMy1bdzC31zWqivS7yrs0Iwe&q$Orx!)9`rU?b-e60?D%qgx$75H7qJ1k
z`CSXkkk2|45~I9oL=*;g7RSKON-(fvB;396naY|?La}C{#Vl&=%xS(=G@FSUO+~k6
zE((~8!uqP)bmTqD?M+CHW+ca4O)paK{bkx=&LZrz%to{p<&^OHOTx;FQ;%nwH(0~%
z#D<^sRV7Y$8Vz|2%9kP2RLVp&vH|Oxyw$qTi5+n(a@?Zr-OwYw32?<sWFl5cS2coc
zk!5f3HtS8MO{QOm)$5fh)}3H@f@5LpAnpp$=^!h?AOd3cx_6mzcH_|Yb-p7M#CXB}
zbyhh&I%V}1?6=nxr<5iWf>|J8S$sg23P?|h?nc@`SzmAhXMUWryvhxe9K^s6CRLGO
z<Q;vA3yeN6Bb-#5us^^_7Duogf_d#aZ#jj%xRMKYnH|=;E=0KqM=OqdQLw@Epcb<|
zWCfJF8yD4?h|y&S-dt66mDd<FOxl|C0YPy|r%ErgwCW5)aZ5Y>WSvhBT#?T?7!1}O
zN}$7BN9P(B)2wl(4jC01Qq$XXesPkO$JD1)79@j6DzNMJJM@k6<hmwA-3Auy0k4`4
zfT$INXnfGdT`7UZo?#2WUX5Rqt=W!|oA7Y6A(Q`1cD8r#ZATXW=?n-mT((D#ghuE1
zeBZ9r)QC5No3eJ`EI$<miFYt_(B_U8_DME9tIvTaa;s~V|DkfcsHk{3jFU(R7#f`n
z)+v>&M`1`O{sUMvP(I;f!o~SdKGF8;8*;)ZG`)xeq4V>LtUfQsq71Jr9p15yylIyZ
zjTL6(W)D3NQ&CGZlcx1K_5Xv<T#^F0N69j~qDgW;*>-t{JU=-8?a8x8&wo1riI22C
zJ0?3bI`4M2{`)B1{Nwd-E2qAx1Y<sZF3^ol@3&{s281-K`3V79K-^Dudp<Iw)&<(`
z&+Qv5l>Gbeorp=+fB&8T6-QmLZWTC0{5AlGwlFsEz-X`=s|)h+m67nH_z*bR+WRc4
z1+XY_F4<XDx-Vi`ISGuKlsrep7=$CjEDUnP8}b;s2)zbF9>`II(w{sHgE~&nL*+yO
zz-fP}&K&nX>F>U`$=H=55y;tH_3E%OB;{~ewQ&k82nOF0cCi<TYm?K2!~_`8w?AMZ
z`r)A=TPezidvhwH;=FishMM$UE&@Uwi20Ox{dfc8WQ*@y><LF^<Na8auXt;rwp6`j
z7}4>G)y;>21JY5EP7#Zh_^oTplMrP^bKIS%o(86Xib~(S%BXl+7qfy~5IGTW5qk;c
z<kUQNR;IIaXjYWhee{+hzYF;4ay}v(nN`O>VLL9Vlk0`(n6s>$T+<=-!~#%WfFc3o
zdj{@$T~i)HrAf}7%o3GTkd`A*j2UR^bAShLFD4iqluc_E(B~#Bdlw~**`aw_9Js*M
z7UIe<Lxme}JtJ(PU5{VVX+E111Q+Gjq1<60sjM`H0;4(IXlm~=_qA)*=!I++Ze~O7
zI*-|(sjq5lwGtTDwwelMZiv*IWU5w9fu1UcXyxT*6Ln_&{mA{AAS`;&ku0w!c)p^s
zQfj$KUa{96#C&a_s6C>qeC^qfV<3l6KWa=&>r`SElEs*F@onF{pN_{cW>+7^=ft1Q
zKm~RZfZS3_BeW(mvmM;0U^-mckY?aJ`pyH8TP9Lb0`64Se{+;eq>r*QUjewN5}8zl
z(n?Sg4#7O`yFE|~@C7Se8+sO#;R>h1Cv!+_N8f>H9ZYAM0}*ngKDI0A=JAEk_z=Mb
zV@c3K#a|rD^D;|mVbRkVbuK+8RQD`uO8)0Pql*7Wu!d{TS6)wf<YDJ#OwUbh*(iRJ
zqB?44kM{_b-)z`B=Xgi_w8F?c{xKm8UwSfP*q!24J<~4bzdW&xCZCAyUzpg!pLn%X
zOx%^xu=S!OvM3l<uCip5mRXXX6muwlHFR~`>48QpWS$Gi?xmKaC4ayzqLiz}+*woy
zrV;QLu5pRl&EJ<3yn9wNvg%1@)*?IV$dv?rf$-)I_x9IM6COxS>7zGfg?KG#LkxFe
ziYu9DKBHpqMvcCFXMIV!eI{x3rGVPPjY-8J4^IjS26voY8j&#bWO$#&q<HtB#}I2;
z=4n@!&vKDRk&RA1j-Gqbsq*XS^!O1Z6v6CPOj2!qgri7MiinFGV_)xouVbt-vnBZ8
zCnoss$OISUfS=f3OA*d##^A5t81MNgn?1Z9O)@DaJB=E`^ue@xlu2t|yB@8F29C9A
z_t1cuL`vRoKAl(Yl)ysH=kvTqi`tZcdss+Q4G#4>Ce)M{7=8}YD&&+j?MjN#@YpgM
z4u@a@?Fy@rZuYA^)*!O*9A1v`ZDS5=PFPiK6`0;0nEk$GZQzg3Klfu&?TJZ{(P~Ig
z^cFE%p_h}#en=IOw8pGo)<{QmnAcu26kqMpYhkh?d+<K>Q3O85HW{Oo@}WW|N>w-Y
zBgRc|GwDzwT|(pokniE+5uQoXXf!XY{1RMf;Lx39^;MQl_16S=lfZ{*)W$||h%58a
zNO@Oi7jJ1Whr5zH7{-1p@@(TxM$SnAI-xUDwx6ejxXF?nh3SbjD>$Hw^+K$%$oHZQ
zN(PX3jUt0O=E?tt%EnurnV-IL2~beNce;wxaCUwcxujSeve|1NvoyhF3`*~eR^RQW
zE7UpfV&)Q&`}~W&Wp6zm)+Z6@bEHsq2!7SK2+Y`~V-|BUy3DJ*&YUh`lmIXu#OF2{
z=xs6!18F>aI`vwu$U-wHWX|aN91;TpyI>SfR+vr;LinX(P*TT&Wb4RA2)@QVf`<%-
z@2`TtxT4<J64-`&a=RFOK;@KLf889WBGCDkz(&_kgf}=(B}|voOFreU&XfYE2g94}
zy0W^n^cn%TQu~w|6mRoEhJt9O=3y{4`8IGEFT{}orM<_F7k$Ea=QElaUs^QH2XRai
zDxFfC&*K}lW)n5DW$L+H`Qt0f-tOVVEhM~E<>>5sV#!l7hyWn1&V>txF%*0Gn@kdP
z1_O4@p8)YIrvr|BCS;o~x)4dK-KFi+H|{EwaM#i}46Y`Lvi7~-(b6;AC;g5)+#XUZ
z(2)IMII4b`r;VTpX^4&jW}le1@cV`JZqe$!Vxf16R__xI@3l715jPEqp^xctsh&@}
z8z~{IlZHgi7!*h3%EL0tx+<Ox(Vnna`&&g?hnYNAxi$q46p%CzT`{f#$|osTubo7g
zwm9NL=y=lEr6XK;Od)V}Z+}fXs(AQ^KT<JwV&L_)K@X0`63t#ny;rWnK^oyi7DL)9
zz9&I5g5oMOOR*PCauvQBO>#g=(23yvUyTaWCQ7^TjB}nK>e!J==MPr8>O}d(vrXGH
z7B$OJ^y4=RNQbH_*{9EVEQxG>HqB4-QOYx(+i^k*fwF_3Y^092IT~rQaY8;FrI5Oo
zv@&7z1=Co-#K5x2fI0C4lS*JtVt@e|nh4nPf$==O%-o$+;<UJ@7ki<gEqx#$>@=`+
zzuWM(*Dk?*=F<dx2#Fk57W1?7<mbb~7f?o`AY?O!Ob^xkj4U2h8f=G`yR35bka`+!
zj`M0(5V4;efMIf;fj=XfGYHWo<$TJ5j=&3E9+XqApMRE&^V8D|Wu@#A>;MFULr_t8
zA1twSLO&poToLL|>Z^ixmx(EcRJGy#z!8c1ddenjY^)t{K_-*3pVkfXuxCR<ZcREU
zk#$7;1tl=5X<cSSEIlFe=@bg_^yQS8uP=G^B%!Gv#9;alzF)KWMY2@T5m1~4>67N(
zmrz{L%o82fF*E04f+*rCovJc*I!Rb(Wlc2Th=OsEUW@7LB7yJNILa;wQs}Erw8oDH
z69CDbRq0XzP;@OIv#<#Vo{^rMlGz2AVw*%7eyo;(@jq<k{Sb~N9dok6#ij<3z(5Eg
z`(Szo;rKY-1^|YIR&YGfv&on#!4)Q7Jh?`_zK`w|UbwOZQb6FuOg{%e2FfO3l#j5{
zvC|77uPhSAAUGO<1A}3VO$Z_2<&nLeA-HgJ5S9X*Xig)6BnUD<%eA}4gb6fEs)AgV
zr5pm|%@W5dAQW<v)mh&jxGo4IXTy7zp-n1hgC_=7`we+3jCT0&#n!>W(}X=gAR{78
zsy?;82;ySDOYUI&&@+L8=6ON%a|lT8XJt7p`ZNThC*i=7IvfxJ2mH-rm-6b((f|;h
zqy};^X67B?_)L+rgD?BrYrOqV!2HZBo)I$bLNM$x{oYYEh44K9x!0%c2AiqJXW-WG
z86%<zP$aEG5e+49%jiVeBy`I8ViBSrOT2By$Dh&LeLBi~Jz2>k-jlAy*Gm8?4zgP8
zkMTg{8o6ncxX9mP5y=g)ZQ_30V!;Pw01UVVUJf?Kx$i8hw$~Zd<220+D0IG~(7t09
zib-147X{(WIe~*+yjcCH!ihl|PSP`|6jCDuBO-b$K|%o#h@gZM!Z=)NCR?Y^fsqwR
zx1PPEFf(Am<}s_22lO9062eJ1-#D;X88gqc9_WJrk`=KmD3}{yP9U7tP>)kJA892Q
z87vSpjh6?qT8NIv2rb5Yl_(9|cesX;lEQeyNTGyr6mqHtcy+;m^cy_VbDAzIJW^E<
zEvDWqvk4|ApjA5i%215b;RuFDLa7xO31b#eq>_$+abD>qfs_^nqXJ-fFwi@}xxPnN
z#)t{l1s)(MCL)kin_|KPQ*yGH2se_=PbT@uZ6o7b^)q2#n8N~$Vi2q;PxC&F#+7GO
zq+-xc5BoImD8dPNUzA*L$mPJ_6bOSwhN1@^L&=`W6$C=jXRJP4msc6y$D>J>(kiJy
zlelBjj&YS%%7|ig?G@WKA<e+WuwVzDPbSAudF>c*E8F$C(91*o0KGj=Kn2T+hgQGi
zIV8e>BqMIC3bZ}yRD?&NDGt(8+>sW0{aZeF2W}|{ABKM`N8QM#By&RM0Fe;}!MkXk
z=e@>!XAx=SDRgl0w@H6*!hqZp0EvcS1E!Rz7Bw&+)1vx8GBgUoZGenoc81Ti&h!IE
zXBxq(cP5|do$&+F*=OytGh?s|+YGpB%q$|hDfj$v2u}_~nuG`!Pu^${V2&9w*<TDh
z>@PS8%6Dl6FaK(45qg-^v~p5{>bS}RP@zdX9NzAZ)FCRw+>Z=C)AnEc#M(pCbB#8Z
zClHJ+#)lYj!w#D>u2}`EQ&p4U7R^m4zX)ezQBkkMrBJ5!30c<PxBtGq=NgFZnm!Pg
zlf;1t(#P2d!^4d4T&U9b-T*Ge6i&`D`FGYSXym~Se3+~K{bc<WCPPwWdgKg4JmTxI
z$@*E!4Cvz^IJzfY54Q$d(Ld8j<-6qGy)SU5JUL^r(=y|;Um@2wUJ83=ofb)%5Qt`x
z@5bqjO#i(Qi_{){l`v_>Pome+0Q9<ahUuNoyk_grZa3_>qQQy?dmosM4w212=0cas
zC%XPns@Ozc{~rbLp#pb@m1iIFS=TwjoAVMH0^B|m!!Xm8`jsbHIEt)LGH(5+$A|Rp
zg%h>4GuZjP{C&E<=kEjwxPFF}s0Yu{DU@W~KmB&g>0J{y+?>;_zADN$;tsSqwQ^Im
zJe)2EP<=Y}rf}U64JTC{txs9i$976p&_4Q;DM|Q)pGJNfP~3d~r_nY2YEPr8EuC_d
zklTEeIRs3ZtWiT?&tE1%ZFkgpO8(mXh5hME?C1dF$*JhIc>o`>wEMx)A!D9%?QyU^
zK1|PIK?IBw7@rl>Z1WdLNHjEHgTY=ez!q&>7-an&PHZAaYlG8*T;fyW6uPljroltx
zysX@OaF$I8abXJBoxwMQ?X4F-zreJG<lp08AHO_!^8A^C{gB#4OAk-36BKLnsbMrj
zlNuHur=|<wa+Q%Am4L*3d^81ye-WyW&Q!^&BK&)7jljQX8i8hy<#3?d!g{*1O<%wT
z0uL---8;^vD6FrG{zK7uz1MKa9}rv>W&TG>A3A?XE3od6;bV`yQ!<r$7u8?f;;I5i
z=LIz0bVB1w|E#ZEoobMDhKjldi0C<vvAF_j2MdBojl7g?z*{TKjCtP@(K|SghIe^i
z4U^HNs4}CU*4X&&6klJu<m&H>c51)}H$%H~z|1Dsx($u_AJ=7mK{!J`g=26^h_|9M
zK#stklRxXp)4E6hJ$(InZ}@xld3W$x@AvAn-+%vO3$O!Yl7FzJCzBzES@ZN^9gcQh
z_oz1$0LVYweeKLtX2SLEzuA>{w7v5>=^kxwe)IazFK&9tyI9CL#=7~m?kO<2b2jqk
z`^gvE_uv>9%$7(FKB=PD<l^IqR0ss~DV9fsiOX@j+uMBt+z$L_7yk1F{O3#f&)1D0
z*n$`2+~&$Jk$)9wg-RTv%tF#Fvr(2`q9g{0ccwACiR3sG&4jOz<+x~*n>9IIbtVP9
z4qB$GZ?`^bqK4Oyc@63H`J}z|2w79Lf!|N=-8PhPHBJhmeT<U}NIQT97QamD{DPc>
z26$C#yaxB@rf;V1TB$#6IQGU<7eageP~JU^2M@`Kn;aCy)Fa#7$58@R<8;4Q+@oUu
z_jSVc_FjMX`$6ybb;9wwd+!L->mk<*PZ8icbfIa*E_j$o<AqHYWLJ0n&B8oPK1Gp<
z8KHL+>cP?%v%16@GK!P4N<g7WjCuiX0mt}$xv#v24U$JsUOs+!`26L69UnY?@!;hH
z@+*h{Yyz{A`W02asp2h$B&)ePvC}Y};_VDqp=)Uinmtwb387yrkZjD(XEaMAI6uVH
zr?FYWh~|wa2OpnE72JV9%p5k>J@ULrd+R$dv;i|_d%q<r!=_q}!Ii9d;U_$FAL7`P
zq%PJ84%jSVu6va{@QOv8o`S25D)X49L1Z-MDQcnP3aLVRBlX#2!JS89{+<hiR~WJf
z06F6leN?;(W6@I7+|te?#~mUKXUw_-N{Bj3)Qf==EBwQ&S#NnFMei`jZkil;K|7P{
zM$2ly(ZTQzU@y>Ura)hHbC6iGhrG$besU4E&a|)sIRUq=H2aAcg4X%Ibquu`x0y*h
zj)oz=u<3fC(g~tF_k_M#+uBNQZf^eeZ}|f}Vw2gBz?}40BsYe{aI2YPXM6jrukI!P
zKYQQ)-^7vZyT2a(ib2O=q(qh<JhHKYV2qRat^-`#Bzq39x?^c<&q3B`H4=s-oWK2c
zJ^DG_Gb7oMWEX#SgDrJezpJaNtG@LYG2LG~|3+|GY~J07_;)NQ{=IkaUi6pGKOg_+
z{<mV8Z(tz6mk}<0M9|jz(jT6E=e~??NPK1R)CMQ=0Vpmf0ECRr^V)@;EQf$iOiu9R
z%=?ZV&CWUJB+xre2AFXP{KsY(7Y?q8=qARwn4r`wk7iTo)Wv)>%b+Q8fFp+)^`VN)
z5d9IKCF3-o7bB!CxW{ma%0m|jW;2XLAfil5boU||zmG=g+Z4QS(aRHsn`D$r=XvFD
z*CkNpcQYiX{pq7(J~)@Y<LSF(K>p?32u(xev@GgE7BGxMP=0IRc@4DA(s4RPCqJVt
zC@C1f$}!iKBf!gDOtTmX4KEpyhbt~+4+!p4u=vS58_iZT=pZIbLOGTsgoFI73v)cm
z&*Ws#0NzLWU@)J`#YfwAB=Z-o_coK!<UGN?z?OjAFhWHuGISpVC(aQl%3?O(N7>mJ
zv}E>M#5Lsr6By;3yxJ1wil{_@B28sl8UUJCsS`RMLY=y8b;|0`Bpqa@?|EfF(S;hg
z6hMeB2$?+3Xp|Z&w*`~8(YxK->_(bvlHFo_mU7(lc$R_ZE{@G^6XQ<M0~AkJF=Ov(
z5PG72&OtbXlaj&gjmvWbKBy<}VapP(4f>CZk*Q%YCdil3BfykD1K;H+dXk>Z&(8Sp
zJ(A&K(k)sK1HVqto{XINdqBT_oF<S)>;51eiLLU8fkPis8~Nn@G&?(=MPO69vnu}c
zSF;ut8fAlYTwr^gY6+C9BA-tOX)m9it#N^3?W7p4@*i*yMNiYq=<(5$=zu;$YH}UK
z&+bo0ThYq?a4WL!uW0k@d$<338@lw(>iXvD=ACHs_SWrhwr+p@-_dY>I{zhF;hu@b
zW(QeMb}OE!wel>j-H^=lNcxzGrOc-oP(wTPJLC;p@az4_G{yOnk<DM~xa18KBApi4
zueWQJ+^j9x>*3MwV4G{Q(Nc`L_~>kup9r484%y!yJbS!zaP%_n>%_xH$2+@!>mThu
z{r+I@_}SC=HIBMjQPYSn=jnTD(b>&yPWahzZyJ1?LLX_t01@0J$M+}{@q6GE%wZu+
zzz8hMan~j2%Po^7T%M;wM=Y2bWCML^K%f)QPfC<-aLNXtBtr%SDY3be>2L%yDwvlb
zj3JoFHW4Q^QeKA<zM;)}%tnrL;02@kFr}9@S&U<XA_-vwhP{zB9{gC9#{~oq>1>6q
zEljwGgU}rFsypDx-gi4M4vzb~I|m1k#Rv5pp<F}l2b8_zFL5K2@AQrG77_Q7^lM*w
zd%P(4E;1K(qzN0Fq=30At*hqZDAQmVtyl<YbZxQ*VjO3XLGHR%;NaQ!-|rnZpMP0i
z!!<b*{Y<dZX@-fzc8xu+=Gl(B%&D~4;X+!nk1?a}s>3zHk#nf5m=NSjup}r<?fw1u
zaPP-Gh=Hh?N|hb``nPk_$$a*c_+$Uco^Lnv*8R^%UqKh1jZvC871x@UKUn>=!(?Re
zhB@i}86eY)HTpHVh!|2rr$Ju+9CV>ukfB)=!8`|q6LEAvt_Fr8Z+s9lamgTjOEe(P
zi;!A5O|3B(&tDw<u=DhZn7X(dZHUn?+7mprqC4K6bY)k-`r5QRF(qGGwj<O`mtUS{
z+%X`f`bM>|ht=JoX}P^vZ;X&fB`((td;j~V&kpxQQ+F0_iiV4mJj~K|M+X;HH~C~A
z+Ph2b{pX`qL;Ts(K}2|03Xyd-1BYT@zlJEx(YdSv6&y!p3NqQ4^aJCj<HSAHofE(I
zpFVrKd$4nK#QU;Q=O(0!$r~XX>r|Mfb9k1{ek7-BRzZ;8fqo_A{(gTZ!E8F*<Jt~C
zd;EWnpB)_^3Yp2?!j-x>u~E?rk}6?fDB-QGMQ5gXrB3z=ecUfNZPl$Zk5wTO@sIBr
z9|ZlCkSd8HE>Zkc(Ny`QHQ6$)`)jJR3+Wezu#eWNCi+WI@A>ytR_NHdC+=4l4PuY2
z0Mite8A^wYDFIOa!A-9OUB$#T3)gwC$cb&ecL&vSldx8l#bgRC_7{qcr#*&7n4Xo@
zYYI3UQ&8zA;&_e4h(Yoj&kG1wBohglZlZz2Ou(0UA?;^6&>oFXG#&$kLP#=~27u<<
zWZE236AG{N*=}M=1TH`tX@x3$uYl27<J4JpNBLy|9e*#QSwW%!W}S*7%C<GUx=cG5
zVgm{}X+BDL0-aTWWf!OCPH%mfzP<WjAHP3<MykgA+(0^`i^*UiVr-D@81Ox;&Nyic
zRd4bcdWU%WW2Hm(A+Am@1OqOVj%MCDq&`j|#p!$^W;R8OC3REU46W{+<T=D*HlHoZ
zOK)SPx}Drt%1gqYCfWvu^JYO)h+@)AsPA=2ii3h&857v9&@W;9mtZr5Z)8!p0qIO|
zGm;jxW(~d^a^8F%E{d~V9dY|<CWDQ%^47=igjV<+*gk)F?un;1s1p*7q=fuM+i*d2
z;j<}ChC{ex`p`|VD+>XE#7QvI>KPr(1w*|+W(R#D#LmflDinoOLebEIUEl?k3}$mN
z`1b^11V)7v;^AkhF+zlFU~gTtH6!RE=)1`*fv5fGpL4OPdke2*_{8zNUh{e~ehwW$
zaHUdfCP{%w*QYb^%$ZtNX_pKoBap<D$tDN=KflyQR)V0BElsr+LKXGB<TNS4roe=o
zj3Zaz!_`7bSaW8j?fKNJuJ^n0r=sXJF0Q3(x_+=F7B8O=42ufR7g!VMTzR@C$}iF*
zvLjUQGUDdU(u!zRtT!N?(b~hBklA9Gj;pRd$mW|UOs3MT{OCzV8$d!$P$0HMW_$NI
zXd@aX)I|MJc}E*uo<vUxH7h2=Ri7#xsnnb=$wJF0tD2m9=F21{x7EZ#z)R8;hiD(H
zYzf^895D|-SL%Fly1}<DqIHYQTHoJ(6bM%jF`ywm*HE`SIQdODRLkv1F!?Uyx2ar_
zYN5B?GKJDEtsLR<kB+axuHEsrJCbrGEs(fFkS-CvU46(-7_5|Adyy>Dz?(Vgth?1U
zI2KvsCH5LB0&MJ%fJ~aCoH03HT87t<y$D-mm=}hhPuE8{UFF%tY1&0?l5|Sj%A@Z$
zG~K$;J0;cBcZP3ilf)-HzFli<5L;vSHTHpbvLjccH?ew<*hT4tkRxy6%JdPcx@a52
z^2Vdcd6(s5N1pZPSY5&I#5|Rx-zw+J3JZU`G~s1&$F%g7mpE1r?aH4r#<AmckgJ|C
z7ajt{1885jzR-2QXi4CFCCFkKWGQWp)i}!Dlx+ANPl8Rk;c&*hUTcePh3J9R2uL8t
zSOe#%e15v6<6&Z8Uum0`p-1;c)6=msFOr33s{B(-Llrw~*q6%_$d!^gxLTIKMH`g2
zOI#fSZOzd54K|<7VgT&aIr653FlZk$fX`pXXn^53c)cM@UeWS~co0!F3F+}V7<=D8
z+B^Jd@9<@Oxc7fw>>VBVUmWfSd_~j2c^<|0Po~k@!?<DOGuCNUL@%;L+#k*_COlT&
zJtdb{cw3MoEN$-()xxt^uR!E|eND?GpJHNXw6giw1@i+6EAZg!zml8<E<M`bg1UZ|
z-=~hXu>=IGk;z~2+Yz``#p1tW)l2KX(5o$W!VO&EPJo;M7EtQOwY2je%P){CNYyMx
zdG<f@w6g@P^vNsCY#phZIZQ0vJ#i=565~ZOnSiLJeNbG}gP3SWloZoeI5@{}EXeRw
zHj??Qg#}y4-iI(T@g9}%i@Pp%^O}6^3ao0SR^tUjHwy%2-j)O<79C;h#zNdhF3l~+
zb#Y&%H8(rp7kqrZFss$2S@7+Q@2_`fObt-W!F);?v6kN?t{87_ir*;aBD6KYibf^C
zk5#j2XRn-<_exE=iPD4zk6ht#?J~fo;W@^=Up~#LGd;SNK6H+XX1=_1_2kP-)Xps4
z_);{i3}qcm8#ugn5RNN0j@Te{zDm@+qH)=vg3xgM>lV0|ZQoenBGisORvHl1ne94`
z?(77)^o7#gO+WFr^dM6Yf*tFX!f!LY!Uk0S>TF3j`r^EfJQqSX!nls3r!Ni;$dEqF
z@S)XXg)m=8rs+k___BZ?KE@P>2zQJIct=I7*zUgp-pAq>O|3P|C$E=`2Z3a6Zlas2
zHxOSU3%4(Ud#y~je78wc&f@o)+li{Xt=tp0`Z9N%CH?F=x7feuTM?Thy-!6&&&vel
zu1_FH#y#}u1%w2U4I-v#Kxya)4!uEl2}urG);v+M!RP{CjKNbAvNBNq0vTnHiCu6u
zg_iSEla6Ua)$c$b@wE#mPV$K(Ex6aA1RNin_&J9aTOvxiY=RO6Vlaq28`dKkSWtAf
zD!=(08Kar^#Ce~WpWAv9j?Zy?trNlmV=T>*b2oEtP~Z3(r?c{fZ1%xp$4|EYN(C>y
ze42<eo@*y%XU5Rpj(k8~{^c7~Qbm7oI6uG<m^Osi$m`9@?Wf(E+r|M?`(2+iSjI<y
z6flJZ(_NkRP$*KJkG%WYbZV|{H?(Cc&qR$7SoXoLIVcPHQZI0V8f*#Q1TA-n8cj;Y
z$ujeY(?M8hTFOxAGV*&dG7H#+Y8>6ek<}^-wtxM0hC}PpG(6Ak>y1++IB#cg#?itf
zL;K9!Pn%{wC-o?{YU#bEL#>l|X%#(!@i@p-MC|WafMuTqWpq~7Lh_Evl#q>w*}%%E
z1FxDfXzu`UCeu!eUqMWvk3?qy_l2#*<h`iOsHN9a@nP4taPwOO2h92ujIMM9cRe3Z
zC<0Q+@zdnw1Wu50v8LkRWn=I=>e^;?SD>0qf$3FP{Dh#u!0f}6-+pL5R#lLQHg*Kk
zr{W~xS9^wYXry9*o<2K<kdx79m9zbMlec1)TrusqKt+)cAfyKv3Vth<Fk>SHdUH{n
z@y542PP&v71VU?Bse^55ZROe|D|9WLq&f&VFp_C1Z#wDlPo1Bpt2&9IJZrpWbty(*
zS~!EWdL^2S;BgP5v9V<<Mz)rmjG+aG-4Ar4&_{qLI50M)A4bomN06?wg|Wi&0+*1L
z;hbZo&Xjb}557cewbVr8r{dhJy=$q~<yUULYsGdT-;0c5+fl@(D7J3NDHY<WwP+0v
zsy)tpW|y<#JfQbe-~uWY9v)E96l4Y?#R`+Z<e<c0jvVOOmdkQvNC9j1Mjl?A6k=}p
zl8Sz%=2y(zIOiw)?tHDY@H(zBRypE~SPFl&zC=a}-@z~KPS@@laZ&Ca{$UkR$?~9p
zIL+$IwY8VAI$89!Sl`!?`b@4j&d1uG8$(W1<Q-|mI=Id-f<-IVI+><#vwU9g{x=r1
z7uHqUH0_c#!V@EOEbb~Mr*3R|>aB8!Ft~{}=IK)ya%++oNXhI0K`7!<@tuvxN!(g(
z5Fx9H>WSA<VfJ$&7X+jKE&`Ficil)%I`3+uaj#rtP6&cYI9YqpXz>8-WCVr^Sg04-
zKrlVr)RyBG6~%vFZoH1Z;$PQ|XJXi^c6_bn)8IX^W`W?jwF}jqUbA%I44XyNNyY(n
zef<s|XR}z~Q0t%0b{PYcQ>44HF}`VQM(~<)DwUk}3_vGXVR{$U(vp%3OyCahF{pa$
zqO)u7P^kixt2alMw@r%Z%HX0h+x`grxMi9f-F?0StO?4&3$L3$du5oVUS2Vql0a%G
zb6T^{rp4@r?^!@PK$aD-?WX9ACIMTmExS&BSmqhS7@QNzKQ=jHU}zKnp!`PN2G-n3
z-54v~LX5GL;St;hjltA<#`#`fY{mj8iGH}TD^ZQMu7PO$rR%BlA+Tqftydw`*}-``
zjEP4l)voj(m=?|-9=sLVMgK!;>w=E%_<#Jz$uvzIYrdZ>7^O-?`NTVidjYBk&%Q4c
zWp=VW)hGMq@iQN?nUj|$Z~J8Yeuh~M@nk3s=$tX0&_a-+aU3iJ&}UGzWqd=;uD~(6
zn}Cc(^Ko&WojL|t$*Z@6kj++U4$*sQxum_WeDkTQ=(7WPB&!CLUcNR`yKzZNnsKHH
zeSLoQfa6+DH~{$A+~KKe76iezXQG44C^nT#4g>4!lDe}iJ_7!Gc7pxlXdro_h$973
zN{zq?66{Wwt#s<#2dwUt=0S!l=cgqktg0ZE6&;Zs3jI7uA?g>@_s^E1&z7RkmZEF6
z6ovaCO-S%0GRz0$d*nad4IhF`ck<@;h@gsM*(sK_N)$EV7P8B(ns7blh~?ub7Byy6
zXM1p&K8ydh*~qkH&~>7w++*ADUl-uetJudJy@r%uu=muWm10j@(foxN$iZOZpw~lV
z(klYoAe%*yYUh1*sr#IOEJ>oIEE-<ER>8V#0!F>&g2{GRg-F^=vKz$*;No2FDNSA2
z5Tt_<6pEl|xW9Y2f9$cVB%^dXvrFzA>>c`w4geHiXey295`VBtiW%_~yiBHJv90W)
zKkpnq-GBPMr?|M6vO#K>7PtQX?w+SG7|QLU`%k}n<|&AW(JuL9@9~T8JHaRoT82h~
zx8#}rI!zPSNh;P*D#di#NUIO!u`rB128(dyNp2r4UJNA5*}=xcWQy=%MJ2qu+`e8x
zl}&1;81sChxlDd~D*dIZf~!pr6(<DV!K9(*WDQ5-!;DQLTL_i3Xx2qRZjPRu0hZhr
zsic3IeyjoakTe+veRay71Z3ZRMB1TGH}p6QfKos_&)s^D0=_vRozbIldK`up(Kv;I
z+f-rQZhX@j>dg|nsLRq#WVxC8#d|ZJ*xhw5MvTVa+34NvttT5b?j%}F@m*B`yR~Tr
zxN0P7b>6HG*Acaf7S48v1^57bOpH|kSe+UWl!b*qRpszRphd818Xi=+d%`4Ynv#sz
zD0I-<M5%)+9N)BUB-^3*GYm(U;DJ?p!ddzAq#$UlwqoQ#CweLoFcnl<fw1E1D)WHv
zNY{8}5eAM9odEcC*zL#!C-bS+W&=Uz@N$w#XjOEoo6O#a_`7`uM`|s*1`{@su@Hpb
zz{M)SQ4nF}Jq}>Om=w7-I2=PCsa>m^RK;t%@-AaDa~>~bO}aU+t*$nShvVh$ZMjw#
z2{qs)-q6P8oiFyUTcEc>?M;)xc~m{OV9Q;}@HG)I=KM*Dg%FgEVgD15#WXz?d<npz
zrJIGqg)_ESy`_|T@Ny-4UABIg=Ne4Zc$J@KBf-Tu1f!q>$-PrKaViY8%1e>xgk_7`
zySv0@yk3G%G>>l`%g`ldn7zum^c8IAuGsw6@j;^C1p(hFh-9BLGQ<Sr6HeQpELW~G
z{|pkDQbbKAWJchvxp_+|7kwx*PQg7-`Q&Q^RSU=3e?L-)m~FVtBeaxiOp}1IQ{Sp~
zokq;JBresOpMKEyW!Xwpe}n$3NKmfW;Jw;4!)u1w51da;s^EY5$^UroFY&pj2Nm;R
zzq!>&^2Vf9gvv%EaU}3KgvF1p4KV6}3Hh)wqsO}uJ_z2Fn+X-fOX(F%#_pAi6r=%p
zOi$8)e8W=15qaOyAEj8CQyq0sb<AXcj%19KmVhi7N<tG>%0f0qsMBd09JeC{is*C%
zj?lnTyObQUYGy5KeY8^K(-|D&=sS6q<<!A9f;cwGiAxZ_4gCxp%Qlon=v4F<LdR)s
zkw43G!b-Y;WZLj1T+|>DQDarC=KF@?UsujqJ@!y!O^3=PR|dX``%sFSk2_Vd1#OS=
zul)^VTb^vG3-{s^v6vOS_8u(36kT~;E|fR9DkT37h~TuGL1Voc*nuU%rEJ!vjxQ>7
zLsdKK7^o~`@(=fX4y!0TsdmH_B09)C50rp4$z#*CkLY6fI(nnER}y%I@Lu1^OY$2;
zbe)wG`Bwl{K&rn$C0-9c!fQJB>&a|X%+%^e$mnz=4Wod}x@G{#uBnh_!jO{gs7?rz
zH|7%<C!iVV_adD&%*<X@e!?_kwTqn0lEB9=^XZ$2;rYZp^8APAVoL7xZuizXTJ{u#
zQ|7dih|+h+rF=>+{fU#ujS$l<V_VN3ens+Unh{1baU+;E$`V6KhG7QrZ%jV#zIw)T
zhNz01E;10r8vjefc6B0c%r*7~z8eqov;brwm>kZcV26g$1xNZ}*_$B+W3pZ%oS&Ze
zay(26MC%iC6poRv5{gZ5zp$5b#9{5eBV`n-j(!j0G0+CEvJ<b!9?I`FO1BgW+p2ZQ
z&|SI-Tq5f=uWp=~xJ26~^!laVE#;i$?u%?yWy1J+3ol<@Dm5K}wC{nZA*<Y1Up4hK
zEH#H+?o_EerP43y=!H5~-67R^bMJ*G({Vh8hJzJ-6-+rua}1k~98ZN<rkRUd6~AyT
z8f$CfOhBXKvy@|y#TFP6Y!CQ)h;JdovOJ`wTyLy^knAV9xbFPDjpBBUC|9-{V+3&{
zXMN0T-;THc(e8cuZRb_H{c8AC=T#@#is*w^zifjKM&pTCL4s-FUv!XBxH5W!Q(19j
zw*zHq+RU<>5WBEmmzSIOq_u(E(;78l9g4jLNkup1*$oMLHTB`__xq#d;$)cM6K9Z+
zF^5KVcsGZA(w85$JGg`5Z7-2ZDKgMPxc7lJ7Rt^XUNE|E7h5grKG*d0oxf>fO$k^U
zo7xwY<Q9VRZG^xDSp_jOs)j59oGH!&;HRx65_BFTkqn~V5o^FrA;u0?tdwIaUS(jD
znFNJ6Gc|nUA}ghpY+bd$wgypXUZg%86MPF#MgRkuVF>gWeTYK&f}+=obow?OlK)*c
zBMXFnN;d#iFiB!L2L%TxgU^7W+M~@y<)M*%RT3aVt`>PIkkRtI+={-yZmyzurZGor
zBG9>Op(gBDNrGEte=9~*dG=(lt6kz$U|x(fC8MYBuCK?nv4h8EhF5#}q>Dkz8M50*
zw5lPX%t>fDqNyLF*%DkU&B)VqRcj^womOL;u@b=q9_3^<u3IZ?cLxsuRKj^PSDArj
zp>ouf&|b(JQI)Cl^fIdO4sg17%!CwX>d+P`3`ttk5>wEhrnvXpF`u%y8<pL4xQb&1
z(r^)2fkXU=BlA<Q{e?Rd+OT7lLjw*P9YI(U94U11>JC7m(9I|$sYhsHP17NraSZ2x
zI_Td@DZW>SLOmZB^jhM7P{Y}SS`VT}zz8v}vI~Kg*nXWo#RD>0)om#1fRBpeU@udN
z;KI(HMpxmV)rV&GxFzrYYk<`@^3hcrFqLDT!q^s5hQhPh_x%CEP2=p<&|&o0FT}rJ
z=vx4h>#Xxb*>u9G_Ts>-8512p!?xn(#GcBd8Am-n5xpq>f;XJ^T-JFoag9cz39)*f
zph$8U12P4r1S?=-ao(yK7Z3`-I+mV;AydjrtP#YyR}8Jn1{t7Pha81)YW~@=t}gRp
zC1VVuy)ZnRy6ri2w+V<~qqN5E?G|@?y<SIO=q3TLcw#2TFb{(5q;F%@B@osynX6Y4
znIzh}a0xiVl$(I9st$i~n&)3cmx9z6C&}~+hNCe;C7gsEQqj)Ic{a|+h-xG1(%(h)
zF79+a5~h+|U<i`97>Vi$VBtYOfWjg>wg~N5b;AdevY1JIoU7j0TkZxk;q|t*jIgXu
z$PKkFUrmXIiFf<Yc{WY^IT%`zi$kVI6WTPHV*fET9GEZs?eTc<29X<&KCp(mAFzT*
zS-F3GxUteGeP}6R#`X<UC{{7Z74J<3%zg}U>EAxQ@t4m(AL9pRe-$&TV!lufY66?=
zn%dY{U%z+nPV^VCi@tXL6+gFcuixIFU%8<8_wJ_n{`1er|GEFISmzsSUq)}Ui!HPl
zr0*u;^v#l!Xa?EP^2vic5qg_nX2aRJ_~SGm4N2sBaFI;kK&YKgMoy<$ZX!-q49`g%
zQCdWI@OHV&UztgIA&adqudkad_&C21cf?OU_}^~+4ixZrkFsGp7^kz|AipSO7ycm;
z?H;6~Q3`;v_XT$;9=%OR^9!9{*eLxtozAAv#~%~aHlq6{7xdesi$t`XTzDI)O<`<g
z9p3ono3A13@HZ%T>>!cilVu$?kNC$(I($RB)!+|2O+|^q%cE}&(@_da-bU|s?>6Qp
zR@u5A>sWpTv9wDNOZfdpC;Bc;#GRHFTl~?g7{0h;fV_%tDxx+9JsOFr<ySI(8o-zO
zsscDz0I4UCuN!FzkprStiY^$UW?-`#oAmR+U_PZf&&4G>dyiXNf$+U`<e!3y?hHZ6
z#oWXuZl5tjZ8SBZ4%Lk`e*Petqag!`;P28?FmY##bDYa~<%{ecC9{v5f`ywTI%2J^
zkgZ4nRFErm2#k$<g(1W!FlM5Y=h<jDP36(w>_q!RvCw*<eoWqDmoJm|<a!Uu(Z%1f
zlADzfo6lz`+G5Syg3|aL{0AY-mtf5@X$S=l<7^h$qKXPs$#$GiNj<VY8X@wt^%3QQ
z{ZjfbL^Aaiw{pkq9W7aX*ZM+F&Z(t-A0r#5bAYA%(#V6rf9-N7`K6bCJ>Y(dUyq?P
zN6BgF@15d^CFd^<wV8Wxw?ld4#gZnFWS&3P8Rb3Vr!6CZAc}SPQT-U)c7DCV&*@6Q
z70N=pqd!*>$-cuGTZ)?y2(=lNlE|}o{w4hve^Cuxyyp}$E5M(O!>t>~6i3e2Xs(mS
zL~eze04HxSff2^IvG;Z2XxOW<Y&dox$|aF@HY>;`USMpuke1WYd*%O&=h~Txt*vA@
ze0D+>+_r9k`zKwbU<!}PT}XTiFg<FhSY-7f&OQ%HbZZ6{J%?qiq{a-1O+KE9kBoUx
z2I(tb+duU_U)l{XZN4P8B9zdtdJj`d!@7$Y?_xU3&K40jRXP@IO^bJ=r6T8wo;{|-
zWc}xd`%jO>wp`uZ_I-VPxDR2@P~eWYz?1zw`0}sxrOBw_&Xb=K7v^xim442rq!b%a
zDmfo#|D2~{ODRVZS!AV;9KD>z{)i%7MIRueu#!9!da%R46#j>u`K&?FE~222oo$g?
z#xW)#;VPAv?SuhJu|zLQwU_ONgf#~m#qu@1&D+k{`YLc>TeJ_@Z>qW9T#OIOaAJs3
z$-MAUaEq~b34CnXk|y&L!C4GnN-a^e^%z$so9qS#zu&HK3CoIp1`kA&O;3Ivw0Q!t
zZC^wY38zFlkX%i^uL$Y@+oa!#Jk5#Alb|J3J<7pRL?`*|+}OXs|6NO)|5*o`y>%<P
z3BM_%ejzFEX<Z-`m}ezbHLO=L4x~iUNTC^e3JMEC&hAh-LsXG&6i2<_vq#KM0ahl>
zcmX64d$DhOQ3&<A8Gas<P2+j86NsHV&E7>5!QCM$X#|X3TuK+9uS|3TA{AW4ib?rJ
z1~;_sL<3|pxjn7z>wnedvD+KDey6M7#4#4b+u8~oMw7c3n3QnIjM|-$PcbtG)aned
zMNlm{XAX!K8Z!`ch=@<n&)<v-=+vPG0Yz6NRrj<`QPY5oj7FuqK1{P)3uGk6O@edL
z2|<A+Cj<os!kU@$TS^K&oeM<l<oEepY_a;GU@#0OqR3_uXsc7oKtLZVS-s<9%`Ac_
z4s8neCd4Ck{Q<y^U<6Dl<#dsbPPeuUq30#l@un-Q>Vebi`j#o~GuVE3%gXR{ai@|1
z775v39Q@OaQ~f4mwK7fSPH1Z{kk0-vlp#>|QVM+1T~$sAOMUtgiI1H_O}RjnMvYz&
z7(`K*bjuri<3mS*|8|KFc-S<Ui?Z>&GM2CaJJckVr05E8c|O66vR~uN_1FHciQ_?I
zc0~ICaO$bpIHo5cx%hn>$v+?^-xo#T@f|hJQ&F)ixuB_!2cGr=pq;*+ORZ!1zVG#4
z2wDs#<nIrg3+Yv{?HLF7;$D3$pdfvWH2}oQnsr#L^UOuI8cbH4jp^!=rz?V847MMd
zc1C>a)Fqtr;8P$kupuPP<cFoCi4;FL1)$@ZP?dFPhi%LSsR~RE#R%#2d;vR#6X=OT
zxE6d5U7WyB>M^CtFiyh<R9qBJzBh>3nSiV17_l=PMIEis;5UWdDd+jfCdVe%o#*?W
zcy#qfPuh@_IKiCkgTmB4r4Jr*VmsGQ(&IT1!-Y(q_A)ldfO)4f;5-rVo(O|>xJr<8
zWqFd!lF&V2nF~TYsNe{EImNtdD1sGXHT75M>`SJ>QuG`4&mD(W5@}wKjr=?^Zc0C?
zRS$O;`c#uN*D$1%$E%`q<<fH_5Y`XjVNw|}_HI$(99rE`?Y_zSddW{i#(*ehqzu~@
z`hyh2d4F-JSLFDk;k_F4N3)X%P=iud57trPCh>gyW-OLG4wqH&C8})6Uz7Z((ARz4
zAF<<<sgBdZX)%K~+-lpwIy!hm*P+kqec5<5U$Q_tHzURjv_)F9lCo@>>;pO%ZUt)#
zITjzw;1Fsr+>|kZ`YpwjJ9X(7d>c%UMoS5GWORs=O9S498W7NdPA&lqA?$c3vBK~H
z_|=t5O8JeO&hZ~;hU-stqr+|4zO3{eG_J7UwK=VzZ&3MAoYR6Q%3g{lXUcQ7nxCr0
zPgk>5_bmMqi|(GSMNgG`v?>nO!iQ^tW3}k<T40K=ZI+iiV$F_P)sf@FqwSP@*HxP;
z*<2ZLm1sEmVI!?x71<q?c_=(1o^>z-LT=PgyFCL^{?_tDAn8ib#XdwRpsEHtSic+e
z`Ul6r0lQZp14}{II);Uzylo?%DMTB>FiFmlk&nsanoo${q0I9EVcVB}2tgWa$l4L~
z%`nZ~uJFOt5uhBlq~Xa|Hx|K%HOX(+OfH^vd^B$_tCy%|l?ZJGu-3HwBbpDcv2i!@
zH_*NrUE_Tj#4Xh)bJWZDaPR-V*gHDzzc}2FgTWr$*IE9<>|#`%NLZFU7H81W%iW$z
za#vCttMCNtC8Cvc(E~vtitm#H;t85>9<(-E5qOjof}4w(e9&5NJ%lKs)~j)A+k>3M
zUD3FcUP+Hy>pg(hrVsDW0B!)97(Zy;Zbc_&;;&q^{hz0&--sX4qI<%6GH@wPX6<+t
zB9*cZ1T97PPq2TA333d!`0D=J$-}M4Lkc>>!N7y_WLkJGR3x2^UFv){FmWI4SS&B%
z<v2B&BXdnp#n%0`+3=zG&-9@+)gNvwI*AGXw4!8`or&)TDFn>69*PcWTN~~)=!tGs
zuCixLvOSxk(c}PsS`j&0w>H<Yx&KrR#9pHH1c8dQ>|6`6gM5%!#H^tk$rcS&1`j1{
z@HZ4UTEDrSna6$bhSuKKe?5kWu?Mi6FRiy4n!tNy$zB)*p<VG8+N3MN2dv5=pamJR
z;|1t-dJ07Y9n~|d%HiyaU#mh^6)ZfI>riJ<P>tc^z}rAsmM+!a!I!4m>e2<HRG)$~
z+i}lOPM}aP?$lES+`=+V_$~T2iUD~thPMxl1+S-ujxRWk<eM_g=lG82qaP+#75NJt
zd!X>d!*mFwZwAQ!C1zX9PsBIat8TR3jW+IeDq>(6Yi5*=d1w!z0uhHJck5hSR@r1b
z-mdI54ZIb%;7DLy_~SZ&MD*!z!#TI&w<!`0&UPnw=xaHG_(jStZw)mk(tp7gQ7UDC
z)Rsd>sTz^~s|g(+(`<58d01k5<;_<co$w^^1pEr2#UCn*+!~)0lkH|#*&2#FCZm-C
z9Q3(HY$MsOlvDZ|#4-HjM-0)9<0}YSicar=B{D@yWb#N#9w~{Yt0Wjnxu`4@1@=oM
z<sq*y6xu&>N%Ux3nOMdLw2eT|8{a<s92)m;8UOiR_U`!)&+o$TKXWM1l_No`<3FQl
zvlRciDgON&|M}_SKPd&?n`{D570d`%5(xALuhf-vpim_*=pS~z6TgA;61Y<c?qRu5
zI@N8T$2vlv`Ooim{-<F391pKC{JZA-Z`@t~`fE4-`}W<hKcD|k8UL+=x8)8X01t)h
zuzHdd1TT!=qL&mxv?2V+niZ;f&GFuUn#gMN@caP+tM5>zF$k^Z1>PSIM)RQzOGcCp
ziUnP}v9=Zj8j-bsKF@>z&5JISk5e$`P^4H^L?<cuU4vs#k7fuGevmV^hFiv_TuArt
z4xc?e-h29_zk9HAbVQ(-)>af>>>K^q=VwsxjanfRyZOb17)^hkVOzQfWNoN!)<mY4
zuKcpCqpJOnNh3ms;9qd3f7)<Fy?u>nM7bqYFd|a^HJFx+kjc4@+zcLU9&@YxW`FW?
zdg6TY{p?L6SngX!-eE8uRsnF+_W|tfio`U&UF<h&CjM+vrk0p2k)_7h0aFvbVRgWo
z$gM3gBKgNId;5ra@VsFqL4bV*`%;Tcn+5$dEu^fI_vpWfxw#loOD~T?##dgDOpXw*
z(svVzK?Nts9G!<HhAQ#^!P<b&sVt~E0aG6=3{UnC_jZq;9sXDUXz%&X;g0x~<FCza
z2TYWGd6gKpCO(J56pC_TekZn^7^%r-E4FyUty@|dZYvNgD9yS}wr3e8ol+Y&sM}Rz
z4n8z4yFbg(eZi&>4Z_6$?1QCpEjD@xW*Y~rOE%=3gRJ1Ind3zSd4B{Vm7+Tui-n)Q
zt${ThmsmxmwsD~n=(&&*25&ekS&qSFGGPMC0)TCBk&b8Jfqp6|u?sWg<Z)?<viTJA
zd8_lw;2GXfLrgl=b)*A7#%9CY{uWT&ZeCl9DE|2|H)4shu_o9EW%Mnf$hE+`KXEwP
zmTIsS$gHPQ-@1G^+)Px=g+y0Dzd>5vPtJf5J!Y5|LPQzD&XL}5CH`jM7?-}g7RJag
zR$}6a`~BXm(ReshUHUj|k~$?DsXvjSJs8tgr_djF!?%60&Au_xyU?P?qA7!r&1~OT
zfIIlQSw2=a>0qR<yzM6mMw*T&1_y#BPl|jr2RKhw?4ZO|vMW0G5Rmh2YPfjRWrBss
zr&3&o$<U}8*n4&&Kyyt_Cji}i3i=9>08C18r9urSRzj35c})*Sd6D8b+Y7bp%Lx!z
z3syJBr&$<_l)i?b7W~DW!7^P86yx|aBSH+qz5wJv&?`XyV*L|9vhrynv`Q2~gwiY2
zE4XYO_WAg|jK1q)QYR=)taO+H^3V{nJz-!G=tYniklW#WPnYQlxf_p0I(7{3xeLjH
z5g!e1kOFc&sZ@-hx?VtXQl?i}c?k<bQjr9;Eg_-F!&qu=H!23xY%(kS)0_;40P~8j
z*(5KykBQD91rtF&?!yG)WW=xO3116Q<+VA;&oJ_BU_@R8&L)6Dn@I!2V1@P`%C4A9
zCLr|>rlZrqamCH5!^hyIKT*1?GZ&&EiD+jK7K6iMQ@Q&N=dg4WA)2l7v{O_h&Aorf
zjFZC4W5fa)RGh`D8^Lrwex5`6ORRiEbph0$eybkCldKRT`1|O5E;ioksZjjKLqOI-
zYYgK#!;T-OFgLJTlq+7PY#5OBNCz`|gE@6B3c2?QrZy5MGaJa}hRH0UZ9E2D5ea*N
z8=@5~3SqMFFM&hM85B^QC``d|p4zdhc{HTK26mwwiToE4=q}N2H!}iK0b^OBlQmi&
z8XQJZVz;}xDae20g9`|+QzBG>VKTy%5#vclc*=%~ON&9Di3@IQAzMo#J6cRY5tFT!
z1?313ng@O&l#{~BgNn;L%^?U=Qo?D+Ajetq1}#NJ$}A3Hx03<-8WS3}Qfjb!+=Qeg
z4XFsu)2msUCDz7Dq`D%8aRKM99FW_K-lXq|%hS%m{hy^`*Me1`r~|ivUU7OENdx3;
zID+M*(Xu;Wuqm*%<O62A^lcm5>AQ&Qaw+bDT9A))Ht2O|Fz3nJRE5;0Q2|IE7-5`^
z)l>v}#=FwsQ2YrGvKJ+1aCND68i0RPbwga8PjU>+CQegF4s(ZFU1B4;5Fz|25_xJd
z?Au6_)9?^O(I<G^+HyB`Rp+~MB_HSnHF^fshxQ5o@c9AlU+n#NU&?%+3jcd^WBuOx
z?Gpa?ox7jke}A9%-+e9he~ic6qgi$qJx<=d5%>H3qBybNx4dwn%|O0?gv93K=>H_+
z0!Ux{PmuDT<~`XujM3&_zrJ(l9zQ7mb#>#f(Z<Hsox5A>cR$U8@_NsHOnxE3QY^*c
zY?{v}sPu6|y>}O*XtTFYBA6(JVxNf}A!yof&(Dt5z8Cj%!M1Y`1o4ynay-hDAx#au
z4HKvdhtBRlJv!bwI6%0b$NNur4*x6eMys25);rs>_dCN2A!EaJsnJ(dLVBsh;NuRD
zgFvpqg%<T))E~Z7I`U8!L$MNc_1@=0@-OlfEjPaL46RP4^$y+F+fqJBuSLK9`l|s~
zu9PARlTPg&vCRiFu~)j3P?kWsqwn%u+|lbw%+szFmY@e8uT0*Y2`U=HR@3B^i@?tj
z){sm>XL&QS=aYJ}I2X7=3(*$Us%a1N!5nli<}kU|WGd;3YBpVqQB89Y)KyFEWR$=l
z;v!=1(La3l?AS;TE)It{ZEsRh;>q68@ss_-M!n!hu{m-{*W-kE*k~m5(~(6g8_ztW
z!NQnATM^LKKsAs?eVSd^t0^ntCO%BhfG@shcM0`)Ln@_X62xY#YUS3Z{7tz%rI<OV
zr~jOJuGLH#RtU-WhqB&KRx_sP0IiazWG+R#F0$qokx=31e1j!pIkL6+<ZLQPt<A^$
ziE9fIrxDCCTZVRLM)<S3x2}P#TGLdfO5_hf^IwGywYpJjmea2)Q65v+Fe;GEwq=qK
zRaQk+{>H7`>-CJkJFXqCVm8sV58NuDSu$cVBuD%3;lmA+yD4Z>aaO!LN^?u2XwPq4
z<W09S&s<M4{-&K7?q9YO#h0al`e3&lt=R5i8{T_dQ?f*HHSEZq*c9)>V7Zt)#}e5E
zp9nA<qaBM2?j$eL*baI&pBA2x(A2i!Ps@qT_-kl~e+`nXc&#u|m+(vY0N%vtuhQ81
z@~9hyaA=Y_xG-zRX428;gi88YoMj<Nl5xKXqH?bA%SI9LLzEZVAQ=upwtXh|bvvd;
zPOuS`!;)XEwga$&wB7r3=9t$2S-=M<89T8M*wz`$qcCJe>~mM#YiWV@B8HU3s87Yp
zg|yJCd~=XegXQsKl^C2S<8eCjm4IgkbljNEQ*`wm8*fA~Eux$AiTG?<%zRH2(edGn
zJuqPvb39{+GEIqS*u50Q03lG#r)lXpN=$$MiS$kI3J(?x&pashX6q8h#C%ef>i4Fs
zRSxq~)M8UyjKgo=GKi9UR0DWmI$S)>)tW(aZF$3xwY${`HYr-1<)i!(vzl<Ln0Ov~
z91}p09ELj%512aGw%_L2Fv56jaY~072Vux(Wa!i+FNzF=Vb02nyTci1NiRE2iZ^S-
zAw7;yp$doOLbX7R7vt<*nvWK!@pCp7azfF#lCk^N-fk>WXLIp7-^;wMOSNd!cH6d|
z*fYqef{9~XuD$w@ch~;-G&hc1EbGMj_?2Gc6<NOvYxq=1ifb#1q2)8pECc64NR=~R
zps0N@V2=={86EZ>qPcrg`21@*<Q~6&8LQ^|Nhth2gvM<17xdY95c%nr{Q{Ync|F=f
zS6SU9W=<Ksc|(cnZim_;)?9UA-e@o!xf#U2RsI;-U&EFc%*&W3lpxw_9B5z@c&<Xy
zLXw#%bTXgGlw$Xx^uuVDoH@p<&}A&v*)ScUOB`&v%>QsE1vJjkjIS}Ply}U%ED@(X
za8;Va$4w4C05f{dxtR3Hg(f5{@*GNRcJ|_=Uc-AN`emYel#Ag^mGw>o(Q{Iryx6Wn
zos#?|2s~wpjU~C*6&^kNjN5~ezl>!!V?Tf@AN0KN`;F!Wr__3O)JH31yHj~oEL;V*
zeY~69Pk&wifcNyx*xP||dPWK69ykt5nx{xB>VrsOKsar5qYby)AxsM0U^qa)Y_il=
z?ew%kVC=xuu0Fhg>|;kVjZ#|??qKi(_oagU!RzI1p*BOb>O>~yi`sg#QuicTF%g$3
z%CxN>wlDURZoSiMby}UE2d`sGKKk4K^XGd{>cPfLwZ;)Lc@&d3XW-XCfCluXxy|@s
z0wDMW`kK&7ytr=2b_K^;%VG-6pB84C6R?Fng$N`c7t=w!<@r2)H!FW->b7XH?V}7R
z^C*-jY}-S5nEP7<Gr9K*a4h$A1jgSNx{+UXw#E+rpiop?Q=I8YN&me{AU|KAM$flq
zEO+@3>?lPB_Xi#Vm_<W>UVF-Wu=CZLcqa%%yN@+L3v`eCLKg2ye3Ff?(0DMXKv=-s
z=hOl)_~`%9Ou+B2Dbpx2kQK7Q`9;kld7JiOR6Hm-K<CoqizTq~rMpi}Q}01&<M~Mi
zZ$a@bh&SvH8Qm0jOb^vVt7lAV)hpOG=#||{urrIc$ssjH2LkQGboe{qP2sc{aZi7}
zusr!RJ5yApq!p%0PNpV*-$f_S`2=~puhxZfRl`vfkmkxy-SesLGiX3<JqcZ->*C6V
zBob#Tgo$B-Z@v;gU)_XorkiW<PwOVM|JBV_V{~7~uMFvWy15*=Ag{h=a#tE{V9HH<
zFl3n?^{xGBs)uU7+F@R14gky6D{+H`HUf`LzJsR7Cq-W!1psE%N80L=!;;JO8=tGV
zCk{#MoZiZ|JhQ{&olMca?zuQ|B`V#hc2?>b#z&hZFX3yMF!Qonu*)kSaUEf+B7;Gp
zza9VY+N<8HUVH7gSFe8Q{Pqv{W9@$hf3d<SU%gUsl$z!OM%JUf-4}=Z$NxoHqqmIf
zou7`-0xvXmgS_;)F8Ha(co&|gr>Xd8kVd^;tLv%+-|g%l>^<?K*}6(V88un$P*Q)>
z>1sY6z4r!zwQpJ>H*%RM<s<+UW>e!+uiAT4W;A*8B%A(_rB(%xz7?L~Q_PA4Q+V+P
z_KKp@T7Y5JO{51O&{hDyDz)xE5Mmv~9-Pe}m(c*c@&%dkS#*w(5}5ms6-1c)NG^r;
zzQ-N2%qmvc9#|NsEsvqH0UIMOoVE1ERT99LtXMca3R-kg?@vg)wcvHvWCcA20W~c2
zATkDIANa)wr*`G#G=pr;ir5yquTY|~i{k7Pj<d972NQGtbr*d`h>~6FVtBWhUsNP1
zSfLVvk&9oDt|5lhqt1s6L~M<~E_1R=y>UOqmi^uK=?Z277^4F`4hh3L`7?81+ktc}
zs`>-@I2p{=p<9aM#)s$%`$PAx;as4pv5)rZ2l6j*+5#}f_FIgP;SpAGu&+ou4xrKE
z>?RVBnO;55C#&dQ5_c+qcU_TW?H@0b)nC?Ezv;jJN=PMZ8OR+#IIoyT6{hkw8MRxl
zsH>vZEPuV-s(|4APzMX_+RxS9Qsk$z1|4#E&br_^GOwbV9`p2Waj&a7?FaI$e+a9u
zZ{!eimNHGIt7J2(T}-)HSn(o(3%E}iB;&f-Lc^2y8Pu@KR#>M>t487NSwXxDYc^am
z+(1yC4Ah)NxMoqB>?VV}&nQT9*T53jY&SIO(sg#{L*?F3NawS>b{#&}vC~`m&v5X_
zti1|$?)sBA^SozR4g^j4sN4~MP|j&g${%PAZ&XY{vu$tO=!|CnGKN2VSs|S|vz%(o
z^5)3zb<*)L2c@gkE3#kG{IqTKuG4GLLuWRdqZ>lep{G8_^bnGwJrtYBVWwHasN2<(
z(2W)qqApE<3&U#Fx;zQ>{wCsT&<k8!5V(?VG!PQmA4EBVu{}CPWetX9&Sky4Tsu~v
zi%NX{hZwAcCb^t=${TJi0TR;F`aA{bEr6LA-VJ4jB_Tg(PB5JbxhPJz`FT@)LLcBw
zv4vT?$lq)=I+>L`-E`EDtXv%VL0ZGh#YB;dl5)VQyu->?wMsozzwtt_QMGbiu^B2a
ztn6$o)TUM3qeX+8D|`}8l3~PaV!m_Q3$w%<N7G}l><l!#vYqRi(=kR{QKNBpmJ^z4
zWTHRISQbjm;$ctBkHlE1OOteZkrCcc+3@`AsQ>f+(<je<J__cowY(ER5@qj#uq6W`
z*d9ddUw{2|bSwJbb~c`M^1*BfSo0pAgSpTQ-^8KxIAt^4xu73?^{&Q3SGgrr7w_G>
zceO4C?oNBs;ISWEcxrfc$)mG{V{IviPR8XocwyKAbMp~aw%<B|K&SI*&WRz{2vzY6
zFeZlt3mv@jKh0UW(O`!M7Hi7SYUZ3)zc_lXVj?n(NNS86YcmQ(HB2PzE*RQK)TZ7^
z6$9{JI^{V67pP9B0mP}8_M=(Om^BE7i~blCKB`=C0b0ih!hs0eq<9a380AME&*}2B
zq?J)VSj6Y5_We0XPkByN_**yP3Be^a-4FCa@*0|7Hj^4)D9uXBhid80>U~4Uhhp@z
z6?8lB6L|1*4uc}L72xN7ch6^kTfp~xGwghhWQ{<L{@ab;%AaliJG!iIwr@eedN<-d
zc56kbr=xyj2X@@<a9C8e-_Z}<^zs#hx*p$N8pT*8UBu%}>kbHpeA3-RX2-Pl4@IG^
zEzzByz@P<xK|mdMk$2(o`w8TzZ|-Oj+isPycAhJBFW`0CYU+Q9Er=!Y4(l{QM~yab
zq|gl64Apdi0ccv>L!ux?@y;i-W4e)_CT~~A(Zw<T3#!4n3_;S8n+Ej*kXQ+=0N_*u
zr2Nx`hDtRcM!nlNun*dm<1$WO^$;;zQ)rCvrMG+JkZ8KpcC`<ODS5iCiVn$tOXs5B
z(|K@7hrD2l_a+W{e@wr&E4X%fJ+l__?FxAbE$H6$30%AuGnv*Z<rVH;LA_vwnVSw<
zQru40wjwsv_x5`Kaa_o5A}T3$7Yab{#<>vsiZ{h)|FO^hV*&pl*wmlQg$(wjb{G4%
z+M0hNm$7BG#G+nfwhI`#e1Uojk@(Z(GHk4bGM4Bj<IP!X0ZfPDY0>UbN^T+4t;QW`
zv54XCKKu=Yf<|9K0#cddVgtQClx|g*rqnp_hi$}V{eoq<<DH|w$^BDhKSe?y>l5O6
zTk>-at<HA}A&n2C<aCzWfQ#XmdZs<j#A=JV?yAeMtM$`^q?k#CYWNeu>$R)0$gfNh
zBAAJbiqqK<0sTv*Lhg@7W=m`9Bk8(bU-Fy4`FfL0bnyDJ4^fVKBf8W0@okzGOTB-Y
zXBdg#XaMq>4BEww1qd$cT(Gc%!SCf{u;`;>V1DqycS(PP-_7UXn#Nw~fAA?>4+NPX
z0cO9Lvqc_mLf{WTFM|68^?1PoP-c(`pRVG<(DZ&=$cy1d*x3-LK<%j-F9moyl_RIr
zF8NsPNHE`Glr<z$LGejw7-HV0^Kq|=HM0@avVY0(H@Lq8&t0GWH2$1^8lQbN{w;hp
zf)BM#_(6?|SH25AwkL?Re($|Y2lJWV`2E=n#D4Lmi|(@{$e+a##9FU^dtZ>qIP;7j
z-tK%7uaB|c?W56gs&M<D;ed9X4{$yhVYgEg*b)TYvp@r{=9baSB_rsL0d4%jyf8}B
zRd&SK84e+zE^G#cY%TM559U*RlymXHOVGQJ=osxC(Au#s*be39#*FS(cE>TWBojD%
zl~4GVJnFKWlw~bC7hCr>XRGR1^$1r{)MM;h(E^Ic(r3h^ut5|$PQx1iSdbY=I2!t-
zU>$xK4d*x-=_67{7Vm*Au+I=5HpBtScjb0&(>pxU4YnewBqR+7bs=^xw63b@w^nhw
z317L6h`HIfgjPCzBb&Dvi9zO$97E5aDG>{P2SAFPiBoUGqDyuwDv8<X__^53P>B9B
zlD+Z9B|1}MgqROc(4r(_)CB64Jp`>ch*1tZ+;A!p7}1=H4yZJU)SnZBmtsmisMmF<
z6)E5dN7<}E>_jYrUx?97hrp5%K@!Ib!?p88lrZ)w390p<txv9cProDXCC)UC^Cbvl
zrcv{VZS*j!4IQomy${5k(DX(MB9`fpYm>)uO8jgJLhc&ah~7rw+h$=TifKNC`~h#6
zbX&}MIB%0_hFM22(E<;|&K*}a_~JKrdXS@p5&-&J!YyH;dg?AKFRyZDRhywAC+pHS
z_JV6eHfX-*p~xaGL}HhL4G90<;**k<`w*9|tX>qW?U`_Tye{7L@QQy1ueFm@b|~yG
ziA)+qFl1ciTV9CjEWrzjJqJvGp!jnAwg2vx%7f@X8v>0hWsC0wMU-f5SP_JNpU?%U
zx5V%vTcv2A-HKXr-MknzOxMZzfT4Z7pytxoT*QIP(aAU9D+ChL2riy}HtwU{s{+cM
zpTE65C%jdcTEN>+7AtkR`AoUs2f?`kE}PX(PN<aQ^awHQm9tRF%OGX2<RqWZP)ov=
zfRu9`waT7~cqw$*0BqjpkPoW>hX`?j%mq(*Z~4^a)1n%m+drfDLO6AojGV^I&4{x1
z)INj?2o(x?A-fT|l5Q{$a%I3FhYx&ZC@l>bPfkmSdz91xFCEsmhzR9;7{~HmdLbLW
zSPyB1PiE*d3YUKmxH`N%z#UTg#v==9oJi(Bo#tcH>n}Pm&QK1*+1}FJY<q!#We>uq
zUMS+pTMZ^d-foM{gC74i4j&nC^<{B|DPjEeYu&pxk6?S|mc4Q9ecJ_<CdRv$)5*6M
z8ltn4wT#|i1s5J)&Guif+5U^~f%VW4Xk?n^`MIzj%cStFCtN9&lXT2x4Ss&C9?9t>
zjPmW9HS#{>i7Err`F?zd3@U>^W1Bjl9;qc;jFY(2X@=5peQTlDgHl*bnzS!pQcow#
z!=zk|8yMF^32so^owbla6XquDxQHG`>+XQ{?aVhgT*vrp(C;+hPF!QhHJHvuS2nTW
z%XC%qO<w0%FYz1(zb`4bAx^|>nx;PCMkQ1LX-EoLs0C|zZXro1Lr<x)JjC8Z)4)r6
zF`rEGDd&|E>Q#Okjq~xUvJkP6XStLn*D8x~?vjsipSeoSO7^;*^9AnS8mAKJimJGo
zx;4SE{3L+~on{xXI1BM^J|7LycM+(fI&0E{Yry`jk_%z`RKa}ysNh}UV^PhiO7CZE
znp7P{w;1{zIu#NbD&-$5ZQIsDLV{il&=P%DRI}w$P6ckI?ItTsQ!~Agvx9F`OsQ>7
zPp5T#Qe&mYvjQ0xq_?UyXF@WLzKtGP1BTDG@ExPluMtR!S@zPb1(w2so3HDovUh^7
zg7+&MQFZ=VX&KViE~%sTAa^h-W@0<G;+oTgGpiy()C7nnZ^c)X@pSLwE4yPXc=^^c
z9yXtAHnV}-9L0V^wQVwc#xbE0cdmW3OM2qeTm>H%RLxDxi1>FdJ=u7!R*{>xJD}s7
zLTcW*sE|pkygO+?tUx(g93cFoPM55>hc;d>cm3#9uDF0UYA>K`zkGr!C0v&|BrG@9
zq8nlEs>`fEP3k@RR0|1y=B1+i7-(o+UWq`5A30Y+Q^%5vw|YW-HsEV9kl211YCH>C
z1RQ|`Jz`w8z#F1+7q|uytoKPaMq?9xjUP~@)&BbIH_MqfN;~oTSU(^7M!de^T3(e2
zheRr+@?WFm1TV_hxm?4%c4dU@1nI)jv}2iHs%P}_9G}Q>Mx&b#9)J=*CNKjr!XZ*3
z+RY3tD2g!!$|UsLZ;|;yFK$96tXD3!;EEQQU(CVO6U7ydHZiyY1x3r^h*4tb82}F&
z(y-aw-B!6W4{OXpH?DD5bn0<;Hb3;$w>{8W?%XeW_M4yo`Yqw%0~97)%?e0NH;>Hq
z@eIpdYpd#xQLwo}u2o@JJB3ezs|?>U#bP#3y(~TQG`jOEst5B?Rt)M1QS-bwZHJEo
zu8K;hhBa<eDovXVe0cLgB>!k)oK|JQt#6G|XPY0rdKEXkIenvCnM|SwO;4bWn!ufq
z3%>cfQ*(yg^%8B@uaGqb56aWI{qaoJ^%iUU8H&@&gWHp|q{6F5^^0}0S9*i}G{`U<
zbQ5qM@5AM;?fD*>kmlQ(nfL=dvtQ9jS10p&YX=N_o#v53wW3z|I<mEIH4;PVTEs#q
zqyTVjR^-sPtBL*e!)L4NAHb@*tZkry8dKRRL`ezt$&nWucd3a)wX~sPd42hlNnuq2
zV#C|cZA+YQEjTQEg#~Xb6aFWgx_6ZOt#dPl;tyy~>0l0k6e?Y%1a7sp<+M@L-(h|^
z9_7i<<F)^Uzrr9`%sh<>+Uz_PyK#uJQ#u}GY0(AdG)_TWNT%;yzkLfZF}ld!2`K`7
zeg%(UPhWIb7Gy^GARz~BFdI%Q5EL;;fx<fKp%O97fZVJj3og;DAw8p^u>2&MMVHxV
z1P>XLd@>)QJ2x7Yxo4tyZhHz#ZcW>m9KSCT94yKMsJ?GGb98@@57US8FUHUiJ2i&a
zXPFeFkIYV}j4(g+%^Elzug&r`oVYdo!gLIeF^>oo<;{zB@?;8r&YroIdrEX@&FWEk
zq5{(bI|X%6%$}Pl`~*dUj3bOsDR%B)j*u712m2Eh7rR${o3JPPY4TR|Sga84D!J{`
zsoy<YotPE52{b+?AZSWFl3OxrM->ZPq_^1D!;B@8FXiGhm}(jQp+6OW&w_5cU}l+S
zgEwNY7sXZt5F}YL%6>^Bh|E&OB*$=uEk)LOW)5tn4BRLfk2R17ieh<=9Kc6#Z87R`
zi)ZN!9npU*&I*esJ2Pq3P#qsKlBQKv%){APIwi|U8?k1hpQVSLjb~|e8()cxP0|V)
zVOkaYCmM{B0&sly`Y(?54*Ngv96sHD`hA&o!%Ws;-Quz35&r#RR8oIR1#Ur<*FfUB
z&MqdN8wbH0IL1tuUcJ*H1Eb&#9_(VIRCeX?KDu)6pQM8SirEBgTF{*!$l_uG`fs$_
z<fjw`eVjuqPkt$8P{m)+Rf0Mh-Y2Cr<O4<{1oxl`Y5n}6YYp+B(Wqe`y)S0z1>CdZ
zpGiAj9mbvN1g==Kd1lr4D>XSX2uxfcXc**G+^z}=x8pOP!>)+LLej*nF7~5Optz01
z*desYg--V3Fs(iurYG~WuBXd1ufV^u!Si`>j`RBi;46tUiL>5EaL@kX-tmjWrzRVi
zATBUsC&9(OGk*V_jGpJMi`9SHIoN-)bG#>`80|A>wVzMy=Boi$Ctg569ep!FhV-IH
zr<i}szb&+7z%4GF{enJwVuOs*w}fyk%Ds&7FNxI-eT<`TqxEPj+GuR9T*PO=*r%#5
z-Dp0*2!*!QCBg-xU5lTyKoB?g#jc9(t_o?=p;{4zrNa$qr4qxl5QlM2C8OXKGB>-2
zc~63@Tg%c%DfuBv!PmJd<avtnlmAHvGY~78zg>V0qDZvRss!)%5st}<NizjCzw}ag
zFHAgCC3J7v{gcJcD4;p3>p2-GqxZk0PYh+DO-;GyakAJ+Tmap<WUws_UvibgUdTV@
z>b;O*^EHdN=x|jVXG#gz@{~i{K7F1h+!FyZ0C(G?XmWFf^0X(<9gY#TF7{%Q4zklM
z9rpZcCdGdL7Fr+}Hld^#L8N8_T}PXPm|?)4UDYzQ;v!`I#U=NL9W!f{UkYI|KN}+j
z{zk>gs-R~;U>2WjaS5Rfi^fm0cgBk;L>l<wQCB0xeNx9^i~shQwUBN_+4*EhIuir%
zpUh`M(}Aa0se9nUXae)e*;LG}YE1sEe4H(G2dDuTOk{RXFz2X%*x;EAU4vp{p?OXU
zU5vcT%##C>#wZg9Z4I4_L|djcLQ@j08>F_>NZ|ke8Za5t^q*Wy*I-=Xf6m1!41IOg
z2H>NCJAk$!axAsU5F1`FH2u8dKk4$c$Q`RyF>Q(p9eG_))+w2{mdLcgq7H3%)vq#4
z`EUfXBC2(_WGN?BmkUIksR2q<U9_?e9yl|*!_IVYE@XdidFvXtQ!RMQvwUx%n;Ysu
zrIzD1<{7d<-t{-NrbE6>I?9|O;`)^UpS1estWqx#-#3W50Ky)H30`aU$HC1oOQx(g
z@LKhclc_Gh?F*_%rmGLpQx&!u54KXjDgnC9#~9Bq`1^c}`lf8K8D_aCjE<Ma&Up&^
z!4z|v<r=vP+`l-Xq;UG)t3yaY7M2x*5X2Jp2J?FN#HYP+I*U6?Wd?9|uJ|6ll5hvt
z*ja_qb6p7xjJ437%lg*!ErH!l{W@_d$_J@zUsGlq)9~e~ttfiiGsOwyI3R`Ly$2vT
z$$XYyhzT2DnAAAGyixKbvR1R%LN&us2+XGMh39H>cZIVTntEmaP;K%l4P_2?iHMHV
zWbN@IF8|p@M~I;AE!OTb6<m}M)=nWZHHo<D>M$z?=yWX<6SU3q7Xi$2@uj%JjgzYT
zX7DhlV}Xat(&&=m(4rt(YL;ul*m4d}X^Mol@JYFztsXSyl}=#5K&P;MQEeRN0M#=_
zhd`nKv`~a^A)1~qe?<xMwd{jsI}KC}vg3;`mI26>^*oF-EoNY>)7Rt!=k|%d)%Wa{
zeArZ*PJZQMhYB;uxOz>a4@h?h;78-xx!xp7nq;MzVHT_d=}gBMIW7+EIbew+YI82S
zoD2qlI;8ci8`bCObTlu{VL(47ld{B0VPifXlad=0)Ux{B<)sm_z(#K)uAdz!T`hd2
zHM3#ne-BbabA<J(Q!+t#4)19`9}mMZrG}vusDp78)$>jTlrrt8tT>vVu*UZ6w9VBj
zEu*q8)&75#;jIlEmMKggnyR=e3e|T)zLV-Q1A8aaQ6_GSx0Gz4pl5i5;FGliAyHUJ
z>@x43<GN_brui~8E(3Z|f2ZW-pdZWy@{sZt^ElawqOicEggvBOWpy5G+Hmj9q~@z)
zBAi1dj7D^j&po4W2;5MjzFtLL&tE0!rlAHbE2(9E8B4AazkZ1m+swh8oXP5GHHbyP
z%l_Af?(ccQI<%NA@rT6cjMw4@O(6+{fk$CLzKIfv^)8ZcN(L%zQco;0*u}4+jfQlZ
zt;y!=mofC44<ua3uRD!nC&2xBLE;GXFQ=+eLrphLvyHR)y5anNXb|giqhWu51vT5Z
zAFdXZ?D81jX-7wSTa|Ax!_7i~YNo`;0vqwa&rIku6Z*`A{s2s9p~&6I=^M-J5%l^9
zNpLiU<U4W;$g$%FyGzIkZfswmS1RttW?R!=0I%P}QdvD6jI?@+zVx=SkYBheL6ttf
z#7Zxm4MkRjMbH<8c3XuY{A6^Qye}dQa~MKjh;;G$-2kGyG|BL$rydfy(|?3x(r}N-
z=%SFii+kmwfK$<uMvpaV^Vm`fo5T_?B2@XdUX4S^@kTl1Dg$f4Me>eP_4O}=^4}t;
zc$o*F|0aE3$bN+m-RT9;X??NsD^vYYMC~t%POx=jPeUIT-qbf2)Wc+cZRsa%N<v+3
za;b=RnYWu&FYsVmLkA|-^eQ4@U@?2*5KP1gnw_>`5_LB3iXK&gT3sdKQSfbSB^({R
zNM9Cn7K02S?EJcgbJe=C6WE7fGH7nskA}Q`qtcA3Sv*_-?ze$KOE67oz(r>PwBqvp
z1?L#<P_KQ3l8#ztQsW--8q0!)KW;!iE-*t0+O3T@SKtW2OKs8S9OYzt=>$sGHBgU9
zvciBK1*aqY;#}h52(mu{+=urX1gqlt+52KPFH+;3nSb5>x8FYHxv{JKAvaubl2+bs
zG_a_u$zi)K+;n;heAe-|o8}9N$}Q_DIY6nE3HQNMUx<fdPruy|f`j;HQ~VR3d6%N@
zDBbi>-6X0TlIr5grlqeL_*nvH)#hw5&tlvRDnj4P#1z3Kdm~Q+0-QUfy1ek_LoG0V
zCB=3*&r6h#h7hZe3Y9f3q*MoP)8S~}vdgRSYD;mMhC*iTO1(3xat+a&^THXzt}XE*
zdh!0wsSsl&mq=H2JT5<yw|ZqN<|R`fu0V)%I-F0~i~s79ko%mx3pi}F#XurqocgA*
z9~L<jiFH;J>BKmTiga`e@0*v&7!w*K=*~z*`^?L}GqZ}?@wd`B(1Py8{43bw8Q{l_
zQ<b(xG*p};QqIXd8&O2+ZZt4o#iiJXN!I!_`UlavA@Hq0UT5Pz^}J~h)6--=n)SI<
z?6`8(u?6IK^2wav$GssV_R-c6MNpB|n$-#BPghhHlSjt6<@bx5ARF`V%9S{l<YS@S
zHFAxcT}=AuJ6-K1X~vZ)2UZ9xyIB=hMwEpb^<@8WZ}<4w;eYjy_MYz??ucIzsg6af
z9weLR4?>q)Ss|c>KJqQI_a3+1*4h1869tc(vTLarnx```9qvU41O)rp?5#sg@52Y>
zdvK+RrvoB})Vf~zC@DXQu)Cad0|nhA<UTCBM_6u^c<4)Vj$tLLl&e-W?subuxH9RW
zlL-ZhX47K~^hdvQbQiGvJsA(cH>32m`0^krG(3S^<$Afzc?Y*9&Xnd#ZloPAoQzsZ
z%gzE>W&`evl*yZxut_#z?FQlB)~ID{h;7^P=e#xiILwPcJwQNLyZXFq$M(iaFN1At
zV#l@NrEycfd4q@~oVs>{=upw6P6(mj-K<UJr{-yrO3Np@V~a7cXf50=kVk|d_b>rY
z0}GCMugILrknLq`VhEJzE@Wd0i-^;-XfC!dDiXRTDj63J8Dz?HxM+F=%>OJlDtF3B
z1dYte`Aje;{K#`4anC;}C+DPuTcV*x`G>`wcF3$!3Wx}D0r^^$mBQ<tr5qa5Vd*q?
zwih<i>9kxEOza4$3;Cio(&QFSuDG&<_b^)bS?b0)%88z(4=GkRg1e*7ojk&JS=BN`
zNn+jA0$NGTZ!$;5+pAO=LN4lk(lQ@YS_z|k@M^!Qq#|$1v*lB^HI}%HDRiob#ahnj
zL1DeEZd7-lRal8F@QRWTp+cNEr)+rA$KS9mtq7G~S{*zTc!#Uw#+e`uCCbbNSr>m_
zZLIcKq(ucb#6Ux!S%E2HGD-$1XU>E;v~j=@^|RseU&ruxb174|xw}7xb+SazGHCg2
zS=CY-9OwuBm;}RNz;YGvt_NknAYG#q&bc0XU-DeJ;*NwhAkzk-dlTHTRKzon%kBJ4
zkxyr;BMSQq8W;22hi`>aQ^Y>8gtY}#8+8SADiW%KkkNo0)W}3-5HdpI4uOz`?N-$n
zP389e%!mF(_>edR<MdJoiDxq6Khf9WDVP<r!U#EcMA7Q0UgrE)&IN8PW0G&`9T;5d
zYv5{E9Z#(dI!L(WTorJu3XNLHN>VUs7+ri5dQ=&Ed7UEU4&`o^+phd@iz(JQh>Qiz
zW)kJ{Jw~4)zzUObS}_W?$4T*~zbp8rxKKgHQ}FrlwmhHZtJ!!knhycQ?i5YpGf|-+
z1>CFjm=w3R#Bx2)!7Plc2VWI!uNG6TI-QS8RjqB%#F%Wvp|3ui<>VA-1Z~-XIu;n3
zM<wgHs3I03hz~x}cs%RB-T1Bi*`^<wp<W@prA?(J<P^k^=;vc0hvO=*JqArRMdlrQ
zk*7D{xzwZknu>Cl9!A7SEjaFz{KRtL<hC@zpHrA&yR>x;|1`@80?0kEFt({pl2SIf
zrKA)ru$z$5Xo)HwJsfHOF*Hx?O4Vb6T$fj4oYH7A&GG#Uwg#n#HSyE^z~D5Oi23!d
z%>Pb6?$)W#L=kdBE=8CVX1L%Svp(M~_<J!wJq7ge^c|(5k9#omld;d*t11xeUy)O)
z5$EIKXcPx+oHFxUpMZdj4%ON>4d%S363E4xK&%{Th<2|6j?w*zpW~A|pj!iyZH7^`
z@5RB1Kvv4e8Nmw0%?VB*X&77*3L9oB#hSR;bqRJlxF*H;;>IR#t^<a>YLR)!5*%(A
z_#=M3T?TDX(eEBSlB)*JyY%a*RF4NR-Di0KSprAfb((Zp0_FKb1%hZ{&I*{OZ^cd$
z=P%|j;#Ra(MrW}P{JwVSi;+l7^jjrt44_GY9O|W%nkmCKiXqK}K6o(~d_kyZ=Ro~D
znTTN)uo{;s`fD=?5!sWV2-$HAl%=w<$esEojx6P@uRIjWAT8gw<%d<_w9?9G09!z$
zzhF|=RjZcXNFambhmYlImRsG*^V{Uzt1cL#ltj+%zyhxnoTtEG>0P-umvDyCQv%5U
zsoLdjJ0nm7YiUKl%Q@L5#A49TUbg9*gs?p!Wk72-DEOx%pm9Gt>i@j|^vScIkHY@-
zlyh$V-o1O#t>}N-*?88;2eV;1@WL6)FN72ucd9Y@%cCG*eKiPZw6gccCZNoKRJ2R|
zUBsbUuRF*xXDNb2VB&?q23XqX+Pz_tS)$zUOO@#vN?X<+(&be?pE2F-X2FxOr<j#T
z0E;2hFBgQ-CX+1I^l(ebk6(ML{30%rzL+<vr>a;V2kU`+;;AP;cIx>ak(K0ZzP10o
z@mssD?Yzy2dF1plP34P9QtXi=pDAe#fO^ftUl|cq=}@=Md`Ol{<4hX5;d~qhnp7=n
zyOV?8cMR(FMLIjrhwQmoM9TZec&|BmPl*C1lTkK6R?wBn5yl$tk?R8}zH9L9dDT=a
zA%YiFa+mTLtU?|G2_xAP7hGNx*-19aW*PPq?E-F^0qe(toZLc9!*LnQrj*zrr*|t>
zqyog6<4LkZtOY0O5F-f4EeNK7)}?Y~;w}QC!^E;?Dh9?~@lrM8#O!fO#|6q#h|*W#
z*ZlR~lDPJbU>P%wbEVw@0_b7j72yBMkxgsB$&5Bl&Ql9cbba`cG(ly3-bBu$G9mOl
z>3hIWw6eHYo$=v3*89a#WU2>0M#X}aK(b6^MnnZvTcHumUCG1L9j`Gx7<LxRlCQ(#
zrh@!|S@6SkdA}~{Ln*`i4A9W>hM-08!jWmixjJqhv^m$D46S@3b8=vR42=zPoF7rh
zZfSo6Bq)?HWVi6Lt@Pzr>yAZ3!Ll7ja>JaWgf7N+Ssb29*XuMLKF-Do9D9$)fwWBj
z&m5c+$Ku+|k^<3+ljsDic_Vq9J3jn$(rgC=U0q$b&gIh(;3o5!>lMoR`_0(nB3m;2
z8s#11uMI~(!RSJCH`bP1qjD($gUs1-qrBPt`^vwE9A8yCwZe<1-sB1^$d7cNS06IW
zxm?H>`U-_!Ur%0!)a&N8RNzWQuu210iv|1-tHV$#JrCWmK^x1e;bb)K+DckZRrjI7
zG+q_qaRoz{lD!s+$moRf(V!cK!kfRbq=UyY84{Kc?<#S?;A>rVK858SjIVf&UOA*}
z(NMCF;wQXB$XG-7i)KsbV?2v_b1t{|A7|xS>R@|b+dt7dx?Q+Z%=$v!VMb7kl2%l#
zihl`ol?O8YTlH|Sa$2uTLaSKFe>(@c8&xkQ3!LDq#fW?yc#%e@x#E@OdcZ~&JK2kc
z+d3A_WnvBeN6w7R@HvZ*^9TWXrXKgWs~%BL$|G@ngyJSM9^sxY)NgHViZ!$0;B!CN
zMs>0lH&4&LpgJmYWgH#O$%2}CGqTvpW5+VN>#4_q=jF!Q=4+XOsWu&pB1FS+#?ZAQ
zn*cd69nUz!QaLA+m?>$G{w|+t1?QGdei_Qmq^9Y~W002}&F;x#p$`cGKrA6d8U_H@
ze5lQ3^1+x*Pg$S0+nl(qPI>CO`oQ;U?275S$))UK?Ue+4QhZq{Z>}VC8K#q>O@Y-b
zC&nj%;jC|yuW4qQhJ}hzI0=jMDdgv*5DdZivQx1K$1~5k@y1=ME2|sWmz6}QJK_+X
z7!g)catfz><wSfsNW^6WrQA*iI#ZsQCY|BFoP_(5=)RmZ>5CwDlAD>35$W7p$q3%E
z_8G7z_^Ws}mOCLlm!Y+(qk95DYT;?|kX2i$CL^nqF!<TZ-sAX1czX-(JWghVi-{})
zFMX>U9Z$!C#dT?Oda8PFb>H&ME2opSzh1c%H<El*^o)lJ;B)2RVwlfolR1GXntp`Q
zL+JBwzga6`)C^Z!54i=-v(<-G?TP4FTL^R61?7$J2&P0qfF<u;ds069<@fvn&b_+P
z`=+<PhDJf-P6MOhwY0IZzJBlCo#-!O%wIeIil5tG-??{>e&vGV->>g%M1T4G^YMS~
ze=An`1`1wZmZTb64uO{iu!hZN@Xq_5vP<8HsOAsPHKP9=e2TuyUp)fp>I~pMA_N1y
zL2?z{jBIqk&yxA<JfGr5_#R;XAEya`T-+a|BOzBm;^2~pL^GefpJr$0GqG8|`R41@
z&Gq$fqGKVj?jVr@3kkt49T(Wh`D`}XT3gG((uZ!#y?lDM#s!MClLB6}@ekPb(bM!Y
zdVKUGI-t*xnvS)Mc7HnBidOcATaj~IqRqeFyZ7~a1l?I(|Lf}dX0&l<YvbP5`n~@a
zqUP!RmuQ8%Hh#lAfxBh~(5&(Ftf{#X6E9OMeun|eZ-qL6Nyg}#LxOgSHhOn@>&eCq
zkP_vpLf#&6&%#THZA1SOL`!iEk3nD+6+CYQKe6?k9|)Kt$*=%_1I*XZ6L6p0=RY1s
zv*b)aZ-W?{WI`6E%%gI<V9P>D$;K(aV?5v4{oBs>d*AIJ?6D2==`;D^PkV<)`_G;V
zEd~&zm*|dMMTY1q=97uIEyeUmfD|!>>$rb6dK+jB26|`_)@9{R??UT?`E<%DB<n}A
z{}gAxJe*BEoE^ZeAq5&2%^i?DJAivL%_dY1p^pAl&l~UVtq3ows~(_T;9HGO5OTN@
zSG@6SDb(X_!e?t2wIfSWgYQ=Qq&96EpBSMH2C3teQm-4yR)t8!$?Neg;_MfCGw4~Z
zbK+UF$9bAJbHLLlVu{c2P0#Q?aEEk~=VDUE9(vQ{@{k0*2Ns@<rr@a1kvTu$B52H$
zF7qwDIEslWeZ>w+k2sO#Gnt<jEO+@7UUw^It>lqodjB~3bO~wv){1)Bl+h_TWR(h2
zeh^Z#sX94;>s??g;vDtj#=G$Ms+|>cA<I^iV_1>=^wdc1jJ{E1gowyDz+xtllSc@!
zgdmG)b7wx6G>+kyerM8gMn0}W+zGga`DavZmUd`{%<ZHz7`e(jU?AbH6-zP-ky86w
zlnG7K?lgr?CuK9vbC{uN|LvD(n~Bb{x9M22`(9~JX5$$GaTR6~ZJzBgZBM9|`pQ3n
zw{YR6-zB)c+p<Zo-69*yhgdH4>-q=fLb(B0U*H{3QfCssACk1vBz_+a^7AtV24hrf
zG^(|?_)MjH11=zLw3!j=uM3*#PLUHoh+4s^ll2Uca2ynPEKv25jw(l0-XPxz22x}Y
zN(GE0o2||ezwXRkWGlFDt(3<cZ<^<rKs)4H8ka4J@#5R|qwH62Ok!w<p8m=9=5=mL
zoi)x{aHE0i*prp3kGPlF44hCYj<v&H#11o84-@0uydwmApQKZ9ZC(IQ3wjo#ff@pR
zi(-C3e*PyZ)lo_6IfDaoC+Y%RDPpPL=W{~l)NPb^BWI}>|G0b69pR73Sp4Q?o$9Mi
zMMPXwm<2~}$qvRSfTlB@59nEg+7Y87dwnmosdcUp(M#W!me^X;>C5<CArVV_xqK<<
zsq|%4$E94;6CY_^ZGN<rlm8)%K)N5D8r2bQvM$MHZCh$_-9xdkGcW#QDN5GmLB_!=
zw^0L#>}9;<Ox6*rbIA46rVxm*n_}hqG+rC?8L#P@)T~EoEtX*`$vFD^j|Y6$>0``@
zyU}ERB2>AMyiU<N@(GKQJ!<LmR3Y@bw-or{>E}oKs|~rM<>Q;riqQ%70;6mp7CJ(V
zSHTcmtr|<TIffz-9gsovz-cPf{XtsMSVF1hIXpt>D2VHjpE6^mFVzz(%<W}TZj4jV
zgXKo7LYFZXmb|vh+|d>(9UjT50>&9*;IcVe70mMQ7bA8y#&z%VIvR+WJo<pf1gA;p
zY-jz8WHvZ&$7|Af^YR}LUw_5N_(7}va((ri*I&Kr(Z8M6TFh?)Di$}Da){p<Q3)b;
z>6aU?wLC(|xSR5yjkpqHkDfpcSA^KyT~d^25pJ;CXdwJMZk6m*U9v@q&UK?r_z&#Z
zO*U1jQoXpI=ZkyKV0Dg$QR?B+*OF-FDmRm?-sp0goPsnaYvGX8Mzl9zy+7pSw9-F!
za@ru{f}`ACk={*FNc%Il>1aVG1Abc8RB?!fSkRNaNaGGXYI*mZe*BWEG-4T_64130
z=NPNBXdCC)^7juo%NR+KYe=F`)Fpk^!1acEt9@|L;L1LdOy*^LK~9qK>&_LjAfpUl
zKJU-@eZ;-v;10#xg$_Ud+Jm#rE<ygVicOiZSmrGbPM6Qi%cC3B?9v4m+qW7`*0s@+
zhL+QIdTq3zAL_<VDw2X3n4F4sPDkJksIblB0LH{ABuBSOwmazK0JcYY-TGVh9eM3Y
z-{|`LM{B`bFR*1x0+6{yZ+NaFaLkyG^-GBVp{4e=6Qtr!y*3|$NAyL%;E0Z9g!AKN
zw57)_UB%J-J&WeFVMgw>OEw(Ok#733<q7uYy{<evW5{2igP?Wv46Z`u3L2|8&Z`$M
z_Go@pB7>_VeZIh(U*Ml_n9n!NN55eL`oHq|O^l~B+(Dul^`zE|qMsqL6b0gwmY9PB
zqa>5QO9yk*Pr%t(hCzYd&>~u(zGC>*gWh5T77Tm-7ev;sd3!6Jy42N@hWs|q0uNKk
za0u_M8c@FUsPz58v&TCJM=#?(KVJg=U?0YWqlsU?d<`56{<wmHCE}+_F<r;W6h?E*
zue=S-Ej%|1m|4Kcvb1$&dD{c7V6;O#ybpr~)C970lnpPc0!)+nB-`;BCfJkIG3<Ds
zenG8P_LVAwhFAwH-2ky{-`j>Qk{Bbbi^b)lYsbm7A`EwyO!?u!AkCY0JK&KDZ_4-4
zPt)~XOa$9oENal~3vV-g`2b45n|A55_OhL+h&glP>vgCpcf@PsF;Z3IB*DEy*@)?b
z=zg?$_bz<wxg;F?F(LrqV~+&cQ_U_q6-dCP>$^3;3}Rr;0lyg9h_6~m=~b&$amR{(
zs|_WThbMwO923N)bM{4Lw{}&x#HH%vAx0+~!W726Xn#y@UeaHs7ZUib!MSVAnXKhP
zqw~AF2JVKsmg%qS-3stk1_lB7$u!ANvol^0<6^Ky7<q(b5~b20@Oonc1WSf+Rj)l}
zI4b%;sR5fZ!5N0OjYj#UxM6y*4iMi4fjQZUxT?v0Ub?cCcQFj`0d=IjGZCw%Uh;Fh
z=1sk}Tx))X*=T14)nkSv#qT@U({kN25V`3163j^-9<yBCi<GLSv-E+?qSEwX&T*fq
z4}=uVtp^(7DqzGRNP8(Bk-E;URE2Z~4;I9_Kqf|nQ=jH1qx1s(ih!TYWc)n!Z7xMZ
zEw5dL@wvjr)|MsG@k&$y>GoL+z@ZdN0d(x{92`6rN_;5<)FNF%AHIn@4=xqD0=YD%
z#A8CDKu39*l^GoYi#~|JQ3W7&Td&5gZfIb>RmURUrIw^)jxmQnYgeKPdPdboiZzEe
zMZ%Ji3WesD4>MQuUNkYOt}n>kn+}Eta;v-zU4ga5i?{}B+A`k7WQRSEwyJk!o#H$l
zO(2Dq&=h#4;Fy_WHHFby-ki9pTzz6P&EAThcw9WK{iD&vwnLp6aI8+_UimQ5v9;ge
zLPcN$ZyaTlA?P?F`xr3H1vKDF@wD97tTSNy%uI<*B8k$8<ea*KfC~Z~q-rjC>Wc^C
zx}<5A&>pU$cDg64q<PC3u6*K;R0dY9l}pL7@{yll!LIY6pZuToGqeBU9lV{)_*w(&
zP-}@F<IUaAC)A@kzQNP7VbB5ETa{8<>LNG}h@o&8w3{Tkw5UGy)?`s?6%FoG^IX4j
zIw`y6Im(yH&TA@Q`a{&hN=lduN@lBLx;EoMpIZG_9|LGRc=#J%IdnxqaS!7t9-V?#
zV9r7evXWgv|Jm$;rS)QrAqHY$QRh(9Tb)IG8HF4VW5MOUJO?Otf-Wj@fGk3X08riF
z)C|bqhIz3`0ogKWA19++aA|QWu&h>22BRFz?WYqf=`Dfn;{1y?`cgggrd_VS55vwO
z#?C97_kGvlGRzJ&Amy4ftz~{D6f5{a@;XY%1Tdzi7vw&foPZ0x&Lw2Ds9Ys=!~88A
zUmePGnvF9R$+IjUrfliJh&}kN*T-|O$_C5UJPzB!t^*ubGA-EQRLqjMzBJ5fOCZ>t
z$N6{_=CvZcgPc0Y?}_KZj8&QSB-lKZD+}P_t3E60+Vp}&%fhzJ!DK}trmk7Ku~!;r
zJhOT+(<JOrR-+8*(V-4%I-4J_i<|X*tZCKeyH9iP*~;gb=rxM5W*k;R0}m=tD**dg
ze-q-yFmFNnAaDa(%RwdKwz4lP+P-*E*;kVX>U-jSRP!-?pM_DVFQVOI4zY={-PJn*
zQv&5{3EFxjJYR#&Vx7;>&ecr{MVeB_=uggmS*8=p?qAyhFPixT?SiF6+72eXJB9ll
zmZ2Nn_2ET@mPyY#(h(!R|7~dAuW{}xhks4eTl>CRe<*|OVK*5oJFw&hrzjKP1AEIO
ze&|+yZ^(vEf&VbQHt>g9{D+ONH|}n@_z$-?)<5Gv{I2*9WL-K-$A~W{#LFoKNPi^6
zhof0`7Clbhyb&kzeo>s*;paxd<NP8iqMv&3zuo*@bbpY)dz1~+fhgP?<QEVB>{t?0
z2_*4X(G3M8aVOfiyS1^twfTvFB-VR2hy><mkcb~%s0i|n;3sU)_YPD>sSv$y@K*{8
zVR#{gH^4(c0gfW>FcKM3FePuK&L?+gBqV?np$YUpgCSf87=qjdWgrAJ@dCzGWH`oD
zAtM}GiQa860sd;+iT9ouX>0jGm0i_jXg`OGcM-gFGho<dz$q204&JMy%yC}TMoJsm
znVa@z4d6amkDK-H2@APhQ2GfIc-<1w9N={Ww92A!isI-kLU=97c|4M?qxwI6cKGAY
zfl22A;9HQ+>9xS7dptC4C~<c5dr_oQO!VGq<`}5UQ+7*etsx{Y_DlmS=hG|r|2Z(`
z+_?};a~RT;g;j-}$xjK{SlgQ%i=xqyD|=1a`3GaJ)Wk{BHei~7r82j}W<_JL8asr`
z%cgOeh6gM~MJhJ^(3*hQi;cd_q2oidS$$?UYY)t#@1ou#vKh>gXr7bJCI`jc51R|0
zmaCtbCSbST!?Rfna=y$7^6aA;Q&4#Vm+?bh{#1orZDenFo4#|ixIrAFi+!lKdQH`h
z_(olD7u^ngJ#2a`9h5E0y*{c9DJIPtlAHBY1k{29y(#C&>k!za?nb;&cqkv7fwecI
z*`*zqVW5(Ap=>Z!aE#ADicBuLdX8S*CN+s|W`4F=j@$4}9?o^;421FoUegS0e%cxE
z*^_7!IKiwXw;n2`!aVFtf}(vOX^lHonz5+8c16zOvgZbT<(edtT47}AAzq6(5|%%B
zmxq_Q3Xq1DpGgGPpM?Z8QUe*eUBrzqlwnZ`oT!OLjj*c^<P`&9mf9+T(AaC*#2=}5
z1g5=kijWv|dzUS7G|Mz4e>JsuH{)h~xu(-qDWP0#i(IRWvT~M^?x^;~6G}|*Jy{sV
zz}-_eJNretQH#o}4`=!D*)N;Yy^;oJ*aGT>X(m{mcZ<r@=eY0d{D)v0qXg@+g>nu_
z@UE5q;wm4zG%h%)d4;xgymN?p4&SxWYV)6}?D3MEJ%V9AF6}AzMYzR-Slj*SXbrM@
zw*2qFgSUl-%|h4gX*wAtgR~v5z5GYA`U@a-tYzSh+>ec*Ln%r4-pB+^fNp&dwGQ_V
z_I8f;`bIOY?YfP7oSZS}6B@OKgcOSo$}O;yMNB^=SCnKwc0BM!F?;5`4Ont1xw4AM
zLljy$q?7m2xsXOmxv~AP@@frw#oKXU{>3*<=fBr<{sm2%e_0yyj=}`AR*eR)VI{bw
zPp}e4KRu<D;3k7BQF6~$xh7Ah$yl&i3?-xBM|?7&j2UKH68>Ew1-dMeXLUJ-sQBUa
z@IgoK=As`(_ilEZeP*_QCT82JIO6}$WVUiS;?`#l+MI*dPcOH$?DQ_d7H^bXCCvT)
zFX%GyFZJX4f5>OLPv-xzxp`+}^N#EPacA@PXaA4i$Nxh=)PDB!_$YoJ<`IiF|N8aa
zyLXkJ$L2<~xv{nRwfNuf<L9BWgrN8q@bw5gd6>!Lq$`J&660|1`~9Qi!~f#9w}WT9
ze-oFe{8@!G7**xJ1M}Ijs<C>zuKfPNo=N{sP5IqtPrp0Z-<2(_-mNSD!_L#Edk3<e
z)q9=BzAG7}LxEdYCqq+GVlqoW((QddXMet2A@YD*E;41`7(ADp6$hTUA%KC?Vw%w<
zzC0ggCmOB@9x-vOV>F{DDk;V#Mrli58^eBCh_5vYN_8{ns7vwaRx>yjYC#2ZTqF}v
zj){CD>QD`8Ej9*VS!(!;4oFt?jOnR~Fofq8T7uvy8Ph(seVVFUf{M~(s5Eslmk%T^
zftH4I4C&#<Ec!yn$5Y~Op^xzagh-*9_z{$ZI=Y$6KUpGq0o5OHZp**_{qNC>r!S87
zo@n~J$>7`y`!u&N@FIYVnorX$9SsG33p%1v;dTS89U~iLL;S1P>qVWeE{cB#<C=}G
z3k?Xm(H~&vJn_rA+j6^B^c6!@X6I|Od=2#~=$h(vw|TF4i-&t<5y3|$imBSAjryGq
zrZrvYfT3}TtCJdxu8GtzA5>E+C7ksUu`<J6A@!15)#lX-{5qdj1CX^PtapbzPi2B<
zoqnhdd;;$(WKbPnpt~_~<qsHYahf71*jQm`V0+B5AUN3x3FcJK;ORIw-lha^$$%e5
z(KC1;CkaGQ6PG5i&}ku5|Lj6~(mFInAMzr@VPUq~Y?dXX>=%QfUwu%!2Y;|ZRmNTV
z(nZN#)Lwyu*yk<Lr%MG(>_0s^-Z?nvKiNM7n-P?fcfCv}RRyiI0;kfg;X1mCl@Rl~
zwFM1YFcoC)Dbm?Kb?ga*G`c-4S1`E>+OCXV`wA<*L4|dPw?iqh*hXu-rF(KdRdw1k
zy`>=aAqYj{i@n|BXF_m4+IzlpxFdco^~$DOYO7S<mK{pvd!prD+>@o^@`6ZV3MU~{
zUkVxJ`chn~uFs{))s;X}SshBn{<S$zil3+1EZxCV()PmQSz(N&Y4(QHYKSE7<ipS9
zIc96X(tsxl|AGrr&mZfTkA_UQL`gMjKNi^M!SWx_Z9&s+)NIi4l07yrVZs=cprW*4
zPSyF)8h8~L^*jzLRc;Xk|0L(CW4v>L&(%3ZWslKgGC38pl8^|i+J3|%)dO8Fw$B+u
z+16~&XnB7HnF_-Z8@c`9Rx)@EhZfZ4^t)9`>W9<mPz$&*Io!>{?-KF@!FPr7M{A55
zeS<LrHqwHZ0dA)AG3uM%c;%b&>oTmKs#e~S4S1{x--sdgB_7)GyQlhCh{<_-*m{r9
z&7@KfTr<8p!NKTS2?}}mTIu!sLY*T@At&)G%wEtj%aL9@(!zF-1tNN9+al5BBzT6f
z7!!tzRm^ayt7MxYfOw016@fBDE5*0z`X0FW27K8!cPgyMpuXL#Hgb=hQI?1S60qMQ
z6_3)X5S823vM)$sesPfi@H@N^?17~VO>po)umb^B12TIaDp`9m^6U)(lk<F<&+<V&
zD%uNCc$^gJi^GF<e7JXX%-MW=_CLX@XKV3QNN;>R(zll;y|z|M{LWIuD+B*O)^2OC
z(F4aW$V9d)(czQfkk6#et(tq9Ug4gpV7-<a=+V6zuwG4~lJ)9h|0=B4n!ANruQ?y)
zjvS0?wz5-E9|pbb3sUg2UI@a4Y_;#BgX{z#_ZOqO1jltKRB~KB*hXxzn)JpslGeV_
z?6JkWmOsy@eK1i$gPs&8i!jA&-v<r0V3;ZTkM|->QB(K`OtB;@2YI3>>0ybc?YV{{
z8U!jBqEYH!gCE-SwjevSX2aNu=M(WwQMrxXs`4BdE52BLlN&zC2lI<`JR{-rI881V
zqO~v&bO}_jKx2Fj*i;SSjgLk6_A-R)x!-j!I`22}@uHkBaE_ZZK7+tV;CnSX{k5=_
zrCCbwHX#V+h1iI!gv*Kkur&72dRpZdIj2@d-}(Gf{4{D+bDAQZ5A#*YJ<;u-tZV!v
z9OQuBo0OWUwUL_jr|HQ&8x1K1`lMasLmxEx)fyDNmc$0;KK2w4BI!iT%Sko@u@s$^
zi*rPIKS^c2r-;3vPUrCMZiC(;P^8W%rF=dJn3=FYFVpEDDQxtXo6nB=Kkq+%^6clM
zl9k?md_hD;+a_s#<t)GoctfKP2e>Qw>XctJ2;t9t^T7k}ebpcg>zfZAL~SFn%Mcr*
z<~u=ipOp;bAH6SM?yUaz>)w~IfT6s4^$VuN2*!R8Yv2bE=ygwJ-Qz#S3e0kxahZIj
z-mY){g)oNZKq^x+1kBpowJ%Kk<kbmS-75~yhl)--NhePpw*yZK<#N8)FwT3gk|Jr(
zhEiXpwO-Nno?mUYH_HV8FD*j;XC<O#=V+v-pfM!y#CP^@{fv#bs&VkXWvjAiIgYlX
zxCeht2XQrL)GsUgF0pb)8b`>(f}(JWB41V{f9uHY^`pKg2E3x4e!A&K!6&JjTh+Hk
z6r85%FtfEq@n*ApT%B7p6bsg1D;gX*Aw(Wvywh}$!<IOCPmEmpa|lw=@FXa>c#dn|
z`|c(4QaVP%iuLvG2C?l#kA^4J649gi7`#NUyGIRrwV0swQMSc3Yz_EH2j{uBhrWar
zK?3oMG4CvNxW#b63I$i}q*;68O4+>YIqZkpESk12na+^ei=rQsH$q@3=IFSDo|ojs
zB!tGZ9MXFR(cUZbn%I6vAy=Tj>kGtg2-1nPZTN!pPs2B+I3A)zyHlS}6oyNqMP}f*
z?p~(Rn^Z6eN1P*mP?`vS<Uh&tQFMIxV(<U6_pR-1+sMM_v!7@G1EV^nluEMf+~qor
zYdeXbO`IItX}ia9b!dsQc_N7_N%_*o``h1{0YCyIz>6%W?Y`D_V~GR?z+f;K4CaEp
zPav{NP3zU>+XH&#VfH$aLFgoof6r2C4CcZzoUz;>I=~%=-O%S-VA0jTD1(M69DP9l
z;yi@W=jrS!%CX=%DVFj_P9zrIDGo5xH@!?HixY;M|2!dC7pG6i328H+obU?TwUv__
zQ;7+hX+Oz`h9ad%h&D~O-K6`uAs;e6%Lx_nbSw$c*?**9U)#0ZC^`b;s=SrBr`|K1
zJ@RQlj!wcotg~H3`8^{t;el6|+Z{UTjPRTx78c#)dLf~~Nx<3$nZ5W(SV9e=r?Wc)
zkU5n_dfL;4H7KymStv28Be^AdBu<ROH=V1DDv?4<s6uNf!|^e7cr8}Wq^B`oGSO#`
z%ss^FZR(N%Ep&G$Etx|pS}>u^zzGJz>^tA!UhJnzPMg1qXkgrhtE<cy(TUMg7K<{{
z!$y(xa0_N&r8P9!{ZK2*loVpb+ifL}YVwfHKIxJ*fGS%bE)Z#@5tdGXtaKq6>EBKu
zle@k+VXTI8AQ6TBBwn+NqWUPLk%Q&i>SYa3RBE@YeO=D2xK^@`{Z-Fs$$Bd7h)^ha
z{^bui$_N&J#*x5ZS6f3j5Fsn~tY%nHWhKa3S@x^j0ZiIG2X|@v?@v}GhIqSlx5C@G
z8TnP8savK`F{~StX$jW<ng@51v*8XChkZ)%$%OM$@7zt&3dGL)<>m7xCAg#uOv>qq
z?v<g)(Zb>Cp@>E$DL=i(@RG_Nr7d5=ZBxXj!aG1FFvbz;{u)ZYe5tnd-Isi0%STA@
z5=l(WBdC&>ZDks`IYq`{F~Ur6htfyIBI-#KNIx-PQE(3gGVy8gx?vuP+)Ik-b^+Zz
zSVBQWJ(;E(hA@CJy?W#6$RD_M8~Dml$`Dfqa{iS^mNLq4S3tBBJ&(sBTr$yT+?PW7
zQD$8~(S}(yB7&wWJ&)B#EcTPkQmlX=1u3jw3?<QJRC-A{@nWES!yfJ{2&xb-8s?>?
zZk12%s7F+-;FAz)5igW*uNExMQ=qmXTUO_`Ar-9FhGM{&(}Y~ES_|ANE(bO%v3?_m
zT8WG3)}*RNSq$?+2jjq*gd@t`Jz?~TrUm%DAI+RN9+GY-i{W*ejZX<$U|wjfw>c{f
zMIro=v&WnYL)O2}QoGG1c1uf37@aR{0c0u3v=CAz6Q(KAl2$(Xk<kPrj>er}UqP_X
z7o4^0Yw<dFy%24pJ1xm++Rfe-Wc17oSQ$F2F5kzoOxkJjMlZ%-|4inRXg;fEREv*a
z7+j*<DePX+ErMZMSa>v(&c~aGylSi`TtR~NUv@xtWN_#!tHdd4QJ77}o}7ip(p>vj
zvT&qBDGS=RfqBP?u9M#<cJ)rmN$0sqFapd_WH!ru5o|$@!>NH%$Yxj}6=)<y44M4s
zT6&XQ66Dhy4WyX5WCiozkFHFo+5a!8Ng;%Js3~nguA?4}gAR}N;s(8aU+1Hv@ym&;
ztYDRtMpq-fgwmXkpy|!gh_4;xnsJ%k??~|n<H5(-gOZq<p~Q_}Sb`;m<_u<{1XYc-
zLK@XY5@|oh04XD7!u)Jr(AM%nWmGuoVtArtKET*Xl&xD)$!G?P(OkXB%&nL!EABR;
zi-b8uvlB%@m>*7xya}k>k&S=6lh8iSHPU6J5kKi_l?;*L=;lQz0Z#oe^w3b3t_uCh
z5CpSG68k9A$G{s7T{K8dE)yf)1XloISq+#Bi^PiFi0qpYAslyjbnt>Ga9ukO73Rsx
z8F&`&0WRfZ#=H|2ue{6)?WbW3-R@}|7YdD_@mZLY(^Z_M&s>nsMS#ROru5%*{OG91
z$53YcqQR4-8k+1MQ)D|i6~)}+OheA^j@W(;mD?I&yG`UfuY;{<FbBp`uH%lH>ZJMW
z%6CnaOk$5Qv)@3xIovCwY|uGG(Xu{LiRQS_GhSa!x2Y972IRv$qQ?nnorWwoey8@D
zWL{_LzbEE&7?>|Vw32)#<FJ=H3uc7MO7eA%x=4{?6~9ARH5ZC!Pk}U>(})5$4jRo+
zEy-*Y0}%z*rUip%24<W#WGc%Dws{xGvb5{ui@FtDFnMbkIxCIYpaNnw_Q{IdOjoi+
z!qzMiQMD$SD~o58WRB;2*JPOx&SC7|W%L;%-=%SQsvl;51e_ApFEp!)a2}ul3wvO1
z?3{Z2-fuHMa>HIQn_x&|xnyW6(@|vo5Xb@bC`b=P8R{Gr5XdsgV5~aor_hls0%0yR
z!!h;?hNi?B9^+KcCKAzNW7#ze<?tBFM)JaXI`@Qo6AJkd&onk?npMg*lA704_e!i)
z==*vVYmK*l|Fe=^z@Vh{U=mJUmXN?=8U=qsYG6#N(%bo^$-W%CLDemN{kYdoMZy-J
z0~aKC2FaP=#S4n_V>qDbGEtaq|1h@dj5w-f@+UGT3>`qtfE3A&wi~2NrbUC*LLZgd
zl){@m^ZWf799`<r!Wo{F;FT5(4TGtW$;J@d7Qtv6^Eum*^BY%s2=wYWAu6)r|8-pb
zGjgPFVCGzJGVm`#>$%a&DCHcKa$}%&?`?=V<N*uHy72Kx3<KX~CPhG&NMKh}q7_0`
zofFE6GPEjvG-+b>ms3J}B$}&YKxQXima*9tH<pSc0i#bct{|WnI(5#VPX#&diw3!j
z`-8}YVPDvpNEaVme>!q0w0wZ6K&OEZJsF4W7%NsHns!0$B^^38;!=`^EuQtVR{bKX
zw^jy>d{{e~lDY0{%D4kNN4;6ut2D`1qHgx0V@;{`#_cq$DiSN&{l$!?R^S32f5eee
zkq)dMtXkJ1BXRk;1<z`YoN?D-2WSi#Yf{D~)TtTQCm=<Zn;qY3$OFTu2qNravLDKc
z6P`JNJFwTW#0iZ2^LkFjonMlQ?qz>83%zp}>K0b~xR+F9-p08t^0W|LKCf}b&lCS*
zLNzrNuhXetfpG}Zv7CrqYfgQ@Ym<d4K_wUPf0`0?iiM=4(%brNP@B^ytuPxT<JajG
zTx*u2KT`^}YNn;hz9`(n)6Py%Q`SRc8NtTpc1173cvciMAzmOI{u;)`&!@uDqO@tK
zIM8X#V@h1?8SnYG-N+5b-h?jpNg_&YPPol5kD-*xNTt7#-_lu0vJxc9;RQd;c@rUW
zs~i{ivC#;lHhHHLC83uj1iH>7|583>x>ClJaydSFq=SZ(u+MB{P7)5CBT8Gxl#_jQ
zKy%Du<^`H(4^sqF(7aQH#>O5A-kiixkl|!DaGfD0<w?@jErj}biFd5o9D|X3Vq@LT
z(i(f7^~_|)+Z0`~3nQZ!A#LMW^T-Y<lwoKeAK9!0jc&M5)012V8G+L6&{!`}OZPZO
z_L(0>sQKQAhin$Gb6vwT<daR*lQqiCBz_VT&JsYSN)LS4;%1?N65cvt)OzO+yrBmo
z^_#=P50ssn?Cdb;P~_5`sT)QH3i*=cGPMq2sJNSx^ag~|OzfF5J{TrfGbw6cLRYit
zfCWEfd7P}}5p;VjdYxy#!s5^7#h$H9NQy;MUZC1ikg70VDY1FO;P}Kabt6ZoWjepQ
zLB5%u+?T8eRK{wLAm%zU@iL_i7-jQ4Ji7}3@^e!VzlzqiS-3|1e>%)nHK^rd{b{c-
z2t9nQsF#J=NsFyxl-;?R+E|;ZJ+ZP2olbUCW!J3jPp$zdR5lua#^Pp$7BePodcs~%
zPYMV)(}4xKwWw5<4Z11c?&R4=s%xuUpJm$_DX?%cAJMG+TXF2v-G)@dC|*a|4PAhf
z?8Ql?uF2O<#R${hEf~~@w{kmIYU5hq-5qMqEtv=-e=~jUMJrAg7cv?vgmPr}<TA{v
zL4LAc5C+Bsgd_v?N==qY_1B6BZ0=h{<-{>^Nvy()fsmP%quDxIuwZas$%06vM<>CL
zG`q52NJ?tVWTq{QAY%{|2fTx-poog}i5)RP(I6*MO*i8^U=RUWxAPr3<`5Mtt>w~U
zW7#b=?NX6lYvwJev<<%AHL8?kTgA}7_$<Guwn`lFi$wow&O+7B6N~qdnA0Dp&^e;A
ziYLzqLy6!`X0^N<v1zTL7kz&=!FbPZ7&Yc@_hm4af*KU~w`8x*vF+;Hr)oWJlsA(1
zsoBVL7}Q=*#iJER6wTF?c|`LF`qeGuxumY@OiB)qRW*%Hqp3@4rx&3QHmKq@CCA{B
zIyNtq2_oNpy3(0|`#YEN{QiP^{TscJ&5_hMrR)N9#^wCF0Yu`@?p5+5;btjzq>C;Q
zgW6#A3tT+)h4S12IPMJr35isVrhxe#0>(5=W&MlOT{#kE3hfgUw*z&sd0hHt{tNnk
z9vv6@AE-oelknBrGrjH{IjxEo=EcHxuxXel2x@2L+GzLJ8#_}TcIaE`5c&&Bc(My@
zX>lxELDU1@GOBl)R?<&~+#(R>+PW<)bFvh8G`lg9UzbTZK^TTrTj)KtSmVGPD@3s`
z>iq92SO-?P`K)3($eS&)9b`;6AJ<e*i)?a7ku%t!Ssd?v`*J+8g#Xf7yR)Qm9bk7k
z{s>OnN7xhN#Zb1SQ5cs&mw;&omZ7wQ-L~-FSO_DLPc{0{2vbAAH}{;`5u(AF*fW}B
z+wgxg^m<~KwS}9q;Zj+-sVg6yC-<DBULw!s;3%^Qz2|Axmih0;7}BnkRTzU&;=Ubr
zkX`K=yAM?~N?#Q7?r{f0N2kjx3NuNmBr69=oZ~K}X=SsiDdF0u*&J4KPm)?ZE7dX@
zQc9Vq22;IlClvdmb4|zYHu(yNvlBFl#TQMh^@v46<I&GGCTLoxG~GoT^=Ctgfu17(
z<D`*XrVW-;y5$TwCGr6VJ)rOh%9uMeY?Bj!NQgC<W{eEP{aAY9<xVs-5g<|nHUv;I
zx~He<s&aGMSW4#RRI;tunm(+O>=%@3jZJ^$cG6TM4QJv+p&vwb1>(9Xt_!}+;XWCm
z{LhU-SW?$jB5Z1sR4>Z{i;`aCdJ9cIpPD$bmdnMBr8Q*(qZ<)#LfigdkUfh2G6t1p
zMY?o%21caCK;E{QrIPe6nloP}+9}d`YC^ZG1XcuK9=g-fR#oNf-<jm*rMShBoD$nY
zZ-Sf?-a@Ml%hP0Klu>1sDb<v_n}Y!cz)LPYg)$J1RmCb@O|&ghf^d<<0K@ZG9p1nk
zpuY@Hv^XC7lWrGZ;`Z?XFfxWioj>5Z-L%&i_x8erUFe+4!8pr>ZXXOd;$*D=T`=pm
zJ5`~Ovd*5@NT7r&Cu<Q<;-FSw8KAq4Pao7uUci^s)JVz$)`2(%%JE#8Qmfqc%eJ9X
z4}0gUU$W2Ebfh*fVXf7T^u+Jf@wK>6SNmr3s22If*5<a-M38xR?R15x$@5LC)R38F
z<^ds5F<8KO;2y}iAPq5Ypq5F!oiI$+TaYh*VjTuV|Lg>qx=1iiHwbdI<TDSQGEVDQ
z@W>vsjF9$mlSt>r!2l}XD#rs7h8pskN^WzKa)MXM<$&$Qh1M&uD_Q$_3m5$yr}JAa
zu|W%yrPKr^<a?`3_a+MTza0B5W~t@*DBtWq6mRyly~`TwRiUX?b+^p*4S(a^GJ4ed
zlhKt$23e@|{&A~qS=&AuKF!E4u3e2GGrM2IW{<uZZa|BT2rVtk`J;g#%bZ)a6pdh>
z;;Xu-dz;e1LWKkF6~~+<1hMJt`Lc^tpU1q2+LMwK_d*7o8WhctsVDqi4~xVo7m{3&
zaUw<s%eGnF4zaoz#0UHzEeR<LFHaaUY**RMuc_NP7rwr9?ZQ&iH@?W-LBFBLOAcQ%
z^J?A3`2WS;l6M`*+bK!j)lF``?MWn|b<E8-uURg!k>r?X@U)@`qTo*1$jz1&XG6-#
zo^et&F(FnQGrj}s5=V9wLbf=$HON`)&5F>pjHx+%NE28pfT>hICwl4hvpOn;)J^&8
zm#4UIe2bM^FVHlcEy?t*6DyR4<tV>@lWT6da;RMu(v7KPbY6WCXdDrXovA52xF-4c
z4Q|7sP-;yT-OFq2j5rXJN1Toj3vJ&G1S!?iBuFz@Suw<Yn{K$<jmhq3FFK={4CBF+
zFhb>HH`w=;w8Mvz`F=W*!5(d0yq~mp<sICY`4JuGRz0#?ZL9WaQY*SE<*JBoSBh*Q
zfHu~bipFvSll`14E*2^^$u_{F2TcQzK>}FIz%8vAZp%I$b$FzaaA_e#S(zX+cRMh&
zUb5RI`#=I^-CTqAf&=m`PhBfFifS=Dvm7CXg%4)qu@hVYR^EKDb}l1#LS|AJ{%CVL
z9eI6HA6fhE)DOLM8gD(wZ8i@$*bjjp`F%fYzM8FtVPrq<zpdN*I|qkw_Qf0evnZN&
zS61ZVuLN!wt=Lt;tu7Ya!%E=deNBRT+wLxZx3zP7OGidh>7~;j&AoI`={uXC4dPqx
zByj$u6_bp5AuFajxJ36X4grjK_;Ww#ec0K0i;ZB{zs`!ubK3fQZ#FQpY70iHpsW`K
zMFn-lYT;R(ii#`iW!vx1#_l9y+smQrj0@|RS|#a9Ig3OZs)48rfUPbP*uyHoVhhOx
zrrD<Ire2zVb1{sa&q{71tT4?FS%hS5Gc)DNF>k4YjwBzzC%2Vk@r3Sd;J4yTc79-?
ze!%O;ZrDa<%D@%mH2WG#CrLS)Ixv@r=T_{Ml?t%oY9rhoyfLammtC!XUXA`ycv+ZL
z`iUTX#R2YM$z5M3-~agI4@*7pH*TmJnLBcve%j`b8u!)atAxU2VKY`{Rz%D;%+EK`
z7ax}jucn`oYN6E@KMSU5DCpM>rvMj<7xH*2W^dduQ4PYzrd+1R*-hnqp{24Jo99CG
zNbh_5)mDJs6L<kcFCkyn(l-|G6I|8v=$71mzvc#$y70hGFLsm3?lFeh+ZU>H#|oSa
zZn%&*icy6Abkz23pJYXp3z`2YT1&dlfS&yE5?$;q`GWA81eys3vX3bM#Y{RTgl)?r
z6)sZ4tPi8245_mTh@7yh2h5iqo-j+uTevikV(c@s3-~+nC#^!qxa<Xjeg{=l@d<JM
z<+jl>R|dDUiRPlOFoo<_!BNTRCv)Iu9-I{Ct^Qg_Sqvs5ex=xRH&T}8m7R3H3L1(`
z&=<kRvnKah%;cHme^q3d@?I_o5An{T!GY0%^s6F37vW<OqnAwf8;kW__)^knMDcOJ
zY%*$KVf7Q8IZ=E7onmaw0d|JV2(p=Y<N8nZmq_v0YJL$#=7OqEU)D5UM^U9|b?29x
z(Q3|6%MdPUA~DvfE@oc7`3f2MmsAc))mF||OI$S#WzC@4Xj&aNBuyN%<1rh%#AVHf
zE;6PDE_$Z9lm6BAkF6K8315;4s)wa2=2pAD5&KxnFwfFX8*@>+@Ot4yhHeLcDe}**
z#_CjGcJ@mXPC><aD1aHHrZ!M%4|xR~eK@02n0q;OCIb<BWjYI{KAZ*6U=lfW#14N2
z;pg=XR_%mz;z)&VCkwwE&ub~1<s1PijU-#pF~woVh-ftkY2*K+_^ai^uP%0tn-;mD
zKUG#bPx|JhHi$S7Ed8<@`G%uxqY;9k$daQ7ixu5gb^P5-adTye(58YobDe=3FnXl4
z5R`u0LBqS#uaXL)c#%r^Ak+jAb7q2|xCskO?C^C6KQCWK3SFgF!#yd7z~5<QFeZ>X
zJEd6G4Gi0Fb5c{0QcDDMOT|o0r*NX^r`8XtaHv){O|->+4Q5(dp2q(FHt&{gZM?9g
zMJ7Z+dYttlD=kaUb&ys);?neR6MwntXF{EmkZ9!3m5)o|;qIhZbW&txwO*5dvjb#`
zRCCu&>KJ*Gb7YDR^+!qVlF9e^XU2=0Z+Evh4|jUo?|<HV`+jqKcklIId0W>a`R{dZ
zorCh^3&mUUAi{p&6=)n*xjylQ5ly4IFHzcQXilG@Ti05Do0G?@@*N;sWEv8a(5ASf
z*dJNWSb_DfWn(5@T@;_WNG93fb4g}eX!+J(th=R#I=+VVS)E9@lV3t3=5AKH>PWi-
z>Mx031Bqrad9=E+cFd2fm_m3OxS@+-vQC+Hghx8H{Gov3SP6r&P6K~7WmglZY>D+N
zX)}jIv^qdj1iW*A!ZAZ^p*ykex<YR%K<ipR?|{!;(fn)dR(+XzS2muO<V{cYq)pM3
z$3|QDsB^53XOk`%cOu(fo}88Vz-0gy#CTtZiA$D&NZ`%NAH^q&V?54i9>bZ&7;%(N
zD1x#zgneY=S|{lu>4PbP&(s)rpF6aFyFASavVTk^uxN!We>qeT&Q2;3f?U3c7UZ%S
za!?wsL=g(uJEB+!QHcBjIoSvcwc-YY%tTs<eShYX%j7MTLvr&t=C`_rjnOXgd9o2|
zB%J&#j#$XJU*b#cmI<c|k#Z{)u<JcL@o2U~sFN~<F^a$8P4LWa)tyOV=$BCkYxh<6
z+(jpm_$orZfiTZe`OuKJC&Sz%=%ia9A!}14xu`5okEJnpbWgzx3=-NxOhn!O=UBa$
zk-`o!H&l}Ai1d-@p#l>L1cX0B>%<-TlhY6nRZbl7DkV_u4in0wcvoZ(Vlb5d!pc!&
zQztrWTFy!6k7g0I9k?S{QRlH~3yQ~j6BIr%jB>4k7v#0ZY+Bf&hz|wOoCwV=X)Lj5
z(~@<YdF{vaMHc9>U5;!XllIS0*7W9w-8kDt%UW%(vTE*Se>5Ag3qyGxNEDW4LT_8c
zou~r0KVy*3oxpQWMsAKAi{Wo!Er}7JOS#}TI1e;k2`w}Uc@vAGf#u<c50l-3GAMY{
zNOr~y9F0d~+|<ki3$06piJ(Il*4!X*53s`&jxzR^($ZLFgeV!Ei#sM~ih&<(=J>UY
z+2C_e^mt>!<R*leVGZ2(3l85AVJ^#Lcz88Ypiw1shd6Nry?wu8^p3dd3RX1+@W_ZW
zqMv{hy7Y5<0>O2A*|D28C$xKfTux)%ZsaR&<0+7F$tA`g_=1&FT?qjWq}!&Yd$9^)
zZ>Hy6UD1rT_w#9J%8n&xwTjMYuOTLbcOFD0rkP8I#fq6`NfQ34;E^p(sZMAgH*zC_
zvYuGFie<xrCI^a%(%&OHK;i;HSwnN(ZgTKNeuK}#dLy^9%waWT1`@~?VoqSJqTgL_
zV=U<X$@^1gECTFFQVnB69h<0GqEVno@vG{vR4PfgU5QdM9dBFPyZbv^hwu0Q)jQbv
zu(`hpUs02X73T{r8!xRR0wRU{R(Ueph$VFt@M6J(4JWgdY$i35!wloN=%VcUJh5@(
z%x96yTW%)o(RkU%*&-W0?v7(;+N0D!+SC2qa<oB~*6?392qdUzv7xyh&X-S3y$yo=
zeg(mLxzn$n!N$8Y7wTwjBR|HN2e9iPr$KqjAAx9tGUJ6mgRdtn5-Wx|z#8N!l&_1?
z%+`_0P>zpiSJ10yNTzr}LdB{r<rpag5Ut_z6ewj=NUOJSWm?uAQFz+PQIZXwGml<2
z6Nt!Pz(lPM+NqFnpQd7ZVrhrn0J+vZO|k;r`_*o1cvIW{?jHK+OX-5RaF<FwcsH@;
ziOsfVJYo(<v+yjdxp?IVeeyj7Dcu?1=}5@`(4Y7i5_%|tuC^byJNsJ?^@2Jzkep#t
zN(aq2xqWF)&Nb}2I|<PimQHHewTXKfQPL08$b_u7<jx0Yr~p%f$bC24=}o<#*l8|{
z61?+3u<qs5?MHCXk<NZ?OIYiL^cYUj;#3I4)I{;pi}2|QkjRA-3}X9Skw_6Z*M$em
zL=HsFr!mj%EYsmknqi`5jSefLP56LL9MU0}?ccy!#jQNOlOt!dW4U_6qB*>yJ^{T&
zW$hO8?94kNvRxprglef|Pe}uud+a<?OrF>es&t%Ri_ayiC4LlDqCldo3j11AffVkn
z0)1r~?MA^l+7V~;Qdm6__qi)8$46rPE63E<QHu}lON%;ue6&LS*ob>`tXDu3-LVtZ
zaE-k%jRPtnT|I?!DIKO3mF|qfh~2`Mb>sORUN$t*b>Q#;!;FNL0U!>=2bT<Bc??E1
znvUA2Fd4#iAPwozKOkVD;q`R0)4(SeC*&Z~iqTyC5P-Z3!`yrO46YkpzUmlYyvNrH
z()JjWj^feG!L`a(y}HspRPzknORGkpYPLR`aNKnfF_`;R>o9X&ga*70IyS3O)WXRP
zlktWpT@vS1rNYAFgDzaV3AXk^>$)KHJMIbogs#drh@*xsKpEBRj9?pjR7!$S0sz<$
z?3rUX2Z!3y<hFqUvTPG3fu><(s*+BNkVK+KOmL%8TK+0G)&_q{kmL;wJ;gL#0#Lyz
zvD|W@SOW>4#9@Zk7*>#J=@8MMpl0-9g5naoqM#<EMm94H32n=+p<L@tXknFE8$~Bq
zc>&0nL9y^J#x}B;xCPFkLB*M`&0fIiH*m*3UR3}~1`%_BdqHibripT#L9Ud~E&H-*
zt(N9;l~yXWH}yk(llF>@8S8{@J4Y$0sV)-Xt=M_Wrb@&UaU&gE2YKs;radimdU&~T
z3P(yN6T_rbAfgy*#ieFe(qR?i#UT2R`~e(ZS11WjcFh^A2C^g>CkF}7ydm4bqR>#C
z@?9~50ana<0Th;}71R<eYj5gL^IJ1@xJ~o{i1)@a67oP9cgp;ZR%l?UQj_|5Sk(4k
zW`*X7B@3glsx!WT*}g8yOI;+G%kq<K#iSY7dKGCb7Cx2=50ILsw3Q6H>uS4?Q5MbC
zuPzj5x-tx$Q;Yy>=#J<LJA!69lGL7K51xf?P|z$Zl5UkfoufrmI25$View2a4CiX`
zx0xGU8JcABdq!5^Rhn^^{Am;x80X>f74KNskyQl2&MI4Z<_YmtbEY&N9YmcYJBE)2
zd*6P$q%+>=>F#rN0Gi?q5S{*xVsM1v@^fcMs?84j8nEl7c!;b=W+3pIOxO!{^iqUS
zi|Z;itd{kt{6ulB%93fbNOu{~(=w#7j9f|)9q$q?yJ;0oZc2ne5R}_^ZE=SsplLD6
z6;d7LAC(5~$QyeY1G3htQ5?t-63-wJ@)DIxfuNUY<K{U};RlV*baNmc08v1$zljE5
z);HJ$6yI{e^q<GZg{CA+sTipl6-KTJUaoIeI>}Pj)vB}`$V_zuk!5gs<H}C9T{F*S
za$YZ(wd*n#qty^Mm+2@&991oexZ2KT-<{(0cj0gx1hZ)rhk0tk6TG=36@dnIwM^Qi
znjYy^O^%UR%dQezG+6=BTA@Uk%(7L#uGrLi+>5`QVeRs{ltNZhLz7H4Sxv6SAt;_6
zQHHw_X7$bL@;;9($9vo{MYDfbVuk#?sVYBeI!>6~rP{d*W@%nUiT0XQmG$&)2#Vcz
zw@U*fM;Ha4CJ>cTm+=Bp_>7QB4H~GL&@%|_69b{@p0YfMK~)f#Bc?ajtGIjcj<b6o
zlc$GXdQvJjEs3nfIyu0XCR3(LXlHx1f@|Kg787j^t{I4G8@IR*tD@w~Lvyl4>kwUT
zN-E>75B$+jG@mDabY@nPI`MTd8s_4aox{U7)u}^`su)zHt?KI1SUwfj<Dz>gjP;`#
z2xM2Rn~|GEXb#~fQ&F9CQ&YrjQ_Kxyg}d2APZjIs6*!q~MBJ_y)7o5Aq^!LdcAoIe
zR-o%~qkpyv#q>@5K)*80D!43TtV~<w9G_xKz2w@~7-?7QwV7uJk$)i@;*HGm2?$lg
z0_*Qksbmxs*=zGY8^=&Ez#(_G3>2{lLJE^)&|9U#v!s#%XNxOAUZ!e>U`=t^)PWa|
z4NTPHCBzIEi0KAb#Uw9fg2<-MkPcFq4yeZ}9{yN>&%YU#<$na$=E~2wdMv0FZ%@lJ
zvUl0AY<oQyEqb+BTs>7VM`0tnXjXbLn5fh3riN9d?~1!qW8YrZazYl^$)zbZ!<)6T
zvrr1dnn6m3@h@Mj)JxOWz6`Zwchn51AFS+CbVf~G+Y_AjhN)Q@jM&07KoC_p6D=A(
zfGoL;WNlhzgaT+=!KqeLmfHx|K^o!zV4J-tWC*H11?)#N*R<nHwGxB!8hzVfHETs)
zcr+>Ep5j}s5|hVMa`dL-Og#K=6!h}qC7pDy|LgAaxA~y()>>^pZ+BM6zY3Fwp;g)<
z+gR;%o;-PE{TEQj)6`%1Jbco5`jCC)1>yC>$MF8{bNip~e}KteBDwSdb1p&(ShCpf
zHy?z+9a@j*ME97#df5lQf9eNUc<)25uO!kkeGq&Q6g_ih(HY3<_<0?;r`C_IgS*T3
zeRnkSPhWBa$QKNzKfMaP)3XRj;ra8Yt+h_)xpjEvTAKtUq(URF54@fl;du@HDLn9J
zLEmlr!RZPw5U!krgBJgRByH`v7uJsl+tyq5jG&401bnuBI_O%<yMwMJ7J;?)?8&2N
z&n@gns{{RcZgn1aA3yJQp8bzCm<?yYTg$vplh2$X>eBaeysX4XVdmuYA&+<G-0{c{
z&0=r%-I42rXmI|h-Emfz@Dv~>3F9LR`zti$xg3v}=Pi}Wx=eB(NsTY%FYn%xDRjV#
zh!%Dy5loJE>Q0m_HJFH}2^%3^VPL~&SD2^~MozJVCoWojI;iwTItkp?0GjJZbdY&~
z+vJ6d!H51MNr%r@*CI}OQ<B(1kJ(Z*LB6%pvSqvZxf9@RFNOtNPagDq($a_Psfc-T
z?fSRNB6R99FPr$38vGep1<Rr!1#*+J<5dD|Iqrl0P#oui!v1iAJDFib-V5g{Oh}Oo
z+5EmUvX~<Ui`(l-NXrSOG@P;gmVnPOnVynsMR>-pDlpCjT}PlNUpVWN$E=#5iMa<v
zUVk=9eEtJAJ$mPPbkMLq?!RR|;2w^IQJqd3z}?)XAX3bhx{voPEqBuQY2C9B$eQqS
zt}_vGA4|rF976c`GkFceNrkaNebe$$$8zC?YT+F7dVY4Fg_N}uDJW(pdS%8JS<#VF
zX^3gv!nu6q1$a$43s48c#w>Zc57AqPBQ<$ikcDTNh(rxyE5iQ5slRU1dvxfs8zw(e
zMNA$K9#apow2hf`+i?r_x*CvC340rtGARjAuNQdE$ot)`$8tW1`B+D(o*&DQ4N;(V
z8<vrZP!*Ax_-WU<IojN@AMpihpyE5CuR!$K*;x#^?+(;UWcG}attPyDToxGQTjZ=%
zL3E5mH0rkE(_e}plgQC9)`5^(M90^cbcVv}rU570;Slyxt-2!(6=y!Bgiu$#DEkI>
z<kZ+uslmS<*%+97i}nCgZNxD)#Ol#Shs?W+*RFZOJ-%TRglnA{Hn*OyJ$;g=y&Gmy
zOsCUR7vNh)4SPji4q?2jf;5HwOJoqB*wF8PcIh4nWW9(v5}D)NvWVUq^+JX!(=@4E
z%}Pk5pq}KcDi6+R@g8z7Mhc+AxJfK5usAH3n%)XgumIuV!oie}A{xEMAc^{ncL>VL
zfKG`U1IBmawURqQMGHr@B-N77GUJ6I`?bO5^Jp!l<V>d|V5L^mr8wVJVRdAUkJf)D
z)dg+*5p7b063rX&B6CGUAmPk3@dh$^RAQE@owQh6&T8k(6mc$&jU$_vZ$)rI((tYD
z!iz|iXsV!#(}kkH9l4j$3T#%k)isoGrc*e#kffSlkU&jGjyKVjiE(Y{qP2lu6cUVl
zD}B0wl|4!LY;>B|;~eXJe(!;mkuTcc|A0fvYYIOnf$MxW1HCpF*c(kELQ<;7A==|T
zU*7~{TGLs0Mr`X19EL}D(Z*ay_xIo9Ve9bY{+`K3oyWCc4RZ&~7-fyzM*XSUW{#Uh
z$&eR?SG~L36bL1##4C&?W?@&pumI`8wOi;NgT0__;T`i%tv9MUuLv$8VGn?jfTaN>
zErYX2zf!orgkgQ~9TOAABw}S1_eTu#5r(s|YXMCy%|~|S=%gfSWXWw|j8w}+uhU`s
zjZ&wVpN2~m+2DmT9;U3o0uO&V2S9INYs8rB5s>w#Q8j#qc4RQB5~oJdqG7VBOcafB
zQ3UU8)mU+NC`2kW)VQF;_s&ED$70=uP3ywt$-21^c2Ai`jAmU&TXWIbBbyluexJa~
zPtRbIC9{X)Y^V@97PfLs(w?gpN=tckv@{<P6{d;cLil_{V~XgR!C?*t{~Sfky=t16
z>`u4mGtwOhC53c4LUp3L+u6B9SXIwckf>WxwUp4z_<?uoP3WAbs$25vGAC)4ZB0$a
zhWh@ULq}+5LS4!WNizctP2}U)fJNKn3RqItoVpVi6Fg$BUPE4A7{V#ph2ai~45StL
ztq}%frK@zk(#5o$g_-?qdEzrAu&j5<-H+I7pk023nUA~^l3q75p12|N<|C~%%Ungb
zPBL369k~TIO#ACXcA+8KioG1-os3eUY1tPib|%TkaH{VOBDi=0bY@2Qrk((~*#>=Z
z6-Ms3+Z}&KsN5;6HMN_T+(KF>Qx*kzXejEY>0E7^<l#l&MKFiMDW+Z(b8NEOBa1!$
z*?3{Gy<KB}C+XOjQ>xhdW#wD8UMfUtV_n7ius`xc>Z|@Nuc`<o43r*ZnE_@7r!bc#
z!+7MeXvd);k4o!9e<6`0jmG);<bq`sTW0Y?kLQ>X%PT^QgUmc;_r{&!(Cd5b_Ig|B
zKzY>g=q&JOr)RW{wejK>p@quPl`iCy6P@KvT4Q(YCt2&oUE&G)C{k_~-2cNdhHB(D
z@ygvJi#kpl=QQvyudFi%E5k0xnA0o(5OusI?y>h$;z|J{1Q{6hT}>8joQjF-4eUbt
zzEj=snOwqmPN>gC1u<$<CEPBFn_BEHAMfljniS@aAT(tnr_;QDQG%kW`ahnymG)=~
ziOtkI&Z&cO6?JJ`%^y5buxlfLBj^G~r?$a!7JH#-xUA2-v-}EXll>9;O&qj48RXsa
zB(#*u07Spj^hMU|?Cw8rlq^^mPtgoy0u;N;0J1kQsJ=rKcyg5wi7D?}6ty0TQ}wVZ
zfns*tL{s^Y&K!OLKSY?wia3P6Kaee1_)5zM7GHd@k@2aw=(6xPn7xRSU8BI5ncsZC
zZ1OX!0;e|&t?BG!<n;~7qcwL#nylcu>$-xAIT2JnaM^N#avkM79h*7e-372mAJ5Gg
zZMskQo20P<f>Li@mM@%8f*3<rQn1PmX54g>xLcarL2)g|T*KqYJ(P_&iBhe;jeX!L
zu2z%9*9z@M`NP&0^ErxduqOVbg+PdNl{#r<`)&wQQMwPrNU$TN`>>2nk^rvj2;Ml#
z53Ft~9O&}Y4>Z;BsZyOi&{W50wAtz`yoywvMN!FAr`dF%dfh+*crZ|(#lh5IvY`R~
z6^+A*5@gz=Ev!cf+7Q2Jyz#FY(}0S1dS3&bl%MRRb|Vwcfq_%0z5s?Kp=G>V<WUGC
zYka26vhpN@=y)gs;W83+rsQ&)b{NK92+50l&7p*BE7NU>x|Ao-?Pr~5opl{3nyD-(
z?)U+q0Ludx_lL|o9Wvw@*L0A%e`ukKcR5fqRL!fZWSx3gNY@4i#G|Go1~r~hjN0d1
zUC@n3j~>#j6x~az1gW`{r=1p^5nk^cGNy*Y>dI<+^;7U^QY*RzP6HsmV}hV4B3ZpQ
zRD1)S>oSJfCCsGiEqg<;0W)(*o!gPvjg-9dIi9j|xg%RqYMC62G~L)8#<f}p_>iX%
z&4rFJ4N^li29(nD71eEJyNKw8KJNJwxAo46`e)r#-w@cbwln$jp2daQO(4;l202O@
zYL>i*8ihoX9huUf+DE+C+C;PEE^X&4+^^xyhZT$~0e^cx?d%`yzTcCuFS)Zpb&+L4
zvm=Ptv7e|e>nJjy3qKebV2IZ`80xkbcZRqTua>oT7^6Y}<Mljw)FUG~w_c0ucH@e*
z#=3sVB5g1WY43N31@ZXN2~kJ|(B`Gfk_#sL5Jo1o6UNCl1bS%XHt1#a0SmXZ?d$G}
z)p5#AwPSz3c;{$nR#<ujOn}erB0C7O6&-6eL86Vt|AKZ@Ofzf79d6CoP4hUp>=rY#
zVsTYa50Y0nP0QN($&8b0lf*GjuF;gGgeKk0Pki<l4!uol^>KAwWHxk6GDbXM|F6`3
zS8Cp-)2}<|isoxgZX#EST~!gWG{RM}Sd~GiK%@?Zw}HN7^VFe?b)Zo~87!;l1ewVU
zDmMGlSbQyG+KVd^+a$T<;tZ7@use7Ym+UmXaeavC3s@toowY{|?M6+RG{(4T)$NsE
z>qozKkH2elKZW1b+YcI_!Uvx|{Z8Q;5itCrlCC~gRcy*6$6DYOF!k24=ve%4O&?Gp
z-LEgda#`o7vwCdRk2<aA$A3J$h9h#>o-v%EC^(54QlAW2U3u{h>tW{+GTqd!3n%l`
zlZ`l9Zc!`;&3%EvIx3Z>iuxqZ{cD|06FRqw|E%FZ5AmPJ_|MZu<!}-;a*^Uo7nY+$
z=S<YZQ#!Lkst0c0_0Ea#5%G;$r2q~~8Z=}4xK1Z8gK=ykhqkkkIb_CS#>X@{sPUUc
z@Wv92W`?Q}B^6cC3+vHs_YyhN$OmRPu*N>iVKT8E(~U`3)L&U?rS$tdYjr)x5=2$s
zY33$-)mzT2dwJwePAR>Q$=s6_;D=}9TM%|zt1>r5H>cEbM)1r2*=+Keb`?zc!kFc=
z)#q#3LmUBVQ=~DdqD?|8-=?UPu4fj=NYta0`6LyO){V>ulav;f>j>#6LziS}AZ3q6
z$t2?$Yn*?At8h}(c07BM+pvs1Sg#niIc=<60d9#)IX-6QR+nA`ys3Q0BCLAn=Kmk<
z|38~xvgL(_0Lb<KU+p|zd%ULl|ARcZ`t;8K|4;J&XB2QdApj2ju@hQ9wSQ`F`IpxB
zegE>MH*otCH){9&@r%E2#DHYkSZmLoK6><&2Mu`ET771%u67?i>8?KiT0sLIwjU}X
z1CqQ?XWTWQa;yMmjUWOA4BR0|*L8b)=WuiP?asE%GJ#BIAnBafYp7{swDfWBaOdFg
zU}F`fJ<**5RHU#yP9PIAp1=8EhZe<s4rd-l<D<fdKws#d<wa**{%F}kG`9jwe8IAh
z*V^q2`>L&jNVpN(&+|9%(BD{&S}%gxq+V+i%6lQ1YGI`a`Z*2Y7}kTsAsm)%*5n<z
zfBh&2f{5i92b?uYVGeo*T?Bgx2s{-Y6R98w$s_2j^b-j%>`@4D>FMRbJ(->Mm<h*v
z+TiE_W^BMr4v>-&mF}h6pG7#ZCNmKt6BWGIrv@<`<;1#(ZEVS?!eP`;;Rv8kX!TFM
zv;hP5hKH)|p(~bR!@$NvaSoL+c@wYa!$gu^C(K6Nv;A2FYqv+-!3{Q~Se!P}P7gJ&
zaQsqUgwD|IfdJ`lbmYeaFT_#D>D5CO8f)leHXOQWJG1eAI84=^j-0C=vrpMrmEXZ+
ziswp;=)I$T5d}bgT2OGbhjVLh?2dujKBubjm%qD{L64?AH9)@~xWiuH`_YExxqBIH
zw8^1JdPjZeO#=%4%R?`2WD7V`(|ceNeq0|dh_Y{a<;=^mbL#bbzs-D@`W|pSJbkMp
zV#M9%-cCJtf)l6~p}6&US>7Y#!x)?5C@C$5&55ujVsSNQQ$!~-i{gfD<FP+!y@2_w
zH(=SHP8>L0une4dE0QwLlInbsUa#n)m@xhT$2wZ~iKR|qI1|$6uw88cN7CN*&WHV-
zt<6K&+A_yNvH2;bnpVdcd`$*?aJav_b(jZ~moNd0vk=Qm`iL^{F(P8*O9W)Kt@=)H
z^X*&fTkGF-xxdyIOSIHzWUf&WYXXTHdl`*zfV0De1NA@~PlVWqS=pSCai&dX>oWf?
ziYT)rJG)`@({Cj+%5E2fHjLZ|qkCrIAxGX|6~#^6*|c|peyt`W(?jPoaB#8-g0ihJ
z=&!)yYSH$An8>xq#QZ2@CW@i0Abpo2y{CLGmO-d8zzL&)hjxfi-w80S1aMc}YRGni
z;%>z7)5eQ@7cn?WkVMo&sjG(!1Ne4b?sStnl`JsU4})WbM!|)I#wCj$B?b=MIw0*l
z4!~;JkK3Jg2d~<`w;MXUn?5Dl_WM0<4J~)hV4L1SH4|4mO}!~z<=TO*F-~9A6ui(C
zT+<iKTCL+f5WH9PE80u-zwOB4D{UZ**Z>f@KZrdc--Sufho;+&9HTu#L1nkLR9Iso
z$cD+2fjWHDITn=L$Wxe#!m`?wD`;sbX|G<8=0M2jCbo=2z=6W0)EFQL!qV!)b{dK`
zmngi+*bN&?F;TKexX5G+r+2vMUc#VVXWR=xcE(W50SxN`C!%RR>7*Sbn5PG6c{|$J
z84pN5Kd@lQr@N?VnrojX)`JHYxwLnatiMU!2N{DB3ZjFA4cHiau<f&3{J!RrMp0R=
zu04G8_{q~}&pS=lzCO@7AKDB3z{KSvSEaLAT|MRs^>tI0JIakjcS)8BWgKlg?_cQ<
zmJ^cT+KgRlvRsM)!L)@}hfOGkU95)&$FoqwKJkTMGD$)0WUy;<cz<M*s5T<ax(>e*
zVI0EzLg|fKTU3qwDLg0@R+{X{dFR9uRQomOs5xNXC8!tSliawrTxE{sRMOK31Z4d0
zkj89xZ#VHCfo)hMgii;hqbjX|RpW|`9^RyFtPFjB<-`eUtTM_dT~Q^SEZ&xD+6m9j
zSjXc*E^s10U^$3e15E;Xn~tzHcWkmnKje~elJ@w^&wlVZWLY67hbcR0kfsoS11rcC
zg#a}w#+o?@(Pm}WOE4fHv$*(cv5C6JcL%NTFTdCCJsDdEiDu!{>ai8&p7!WR-CjBR
z6dr%sAp3*_I1F#KX@MO6x_9v5?e1Z3?|pCQ-G{?}$zthemzhv7xWJ`g`yuPknyvMA
z_#qChA}XLlj$U;WAZj+FnVU4Qc6=mQop^xm_^WZF=?2y)pBxOOku)HO9$HzkUhV$!
zZU=C8?t$n}F_)Ov6tF_fxj`YAVE^osyn5;ru_PU2lCL<g5keAqL?LC~I&S8Iev?q#
z8rOA#p?6;APFA5H8Sz_8Ape=BpCmT8C_z!dh0B)a)>I_K<3*t78%0TtMOis1-UgCZ
z3`4hxvC!ngvPHIh;nh&C(bW?K!YpD$;Z<ES5(PI&WOD{$y>zw=8A`$Q5CaM8xs#I2
zg?jQxCQGheB8<Cwam>j}H&KE*V;meM1bb{mHCykzJfq{%31Fobk+J7Skrxx|3<lxI
z3D4Y63??O6#;Cz9U25Z#60-hNt(F%SK7T?<qXkF54`<UKJ+wbOLyI%!(waZH+!fvh
zQ5wX!Gj}v{f>RzSP2oc1tBJAQhTbL1yNGA~$L)u-LGct%6W2x0JZBiO5GIkbHM~FQ
z{k*%k{r=|zG`32gS|zJuI<!7C9a;NhywV3|+D`Wxdems!mfcpy3{P4^W=T$?Z9~<f
z!y{`00b(_Uz}uDzFZZ4w;OJ*8m`z~7A1AQC>E?;nns$3t+>TjnKtQJa6hycF#h`AE
zj9>_Z$4LRV6%-cA!bzht;~QPBwG1#>4>gwTz|*vzXr2rtuT2l4sK^?I=y&`z)3B}q
zIquIU6Wlt4rinSPVfXT!*YF;Jg;EeGr6`decSOVuobD^e{<({Rm0@@GXOkp!V*d;S
zAHe@7lu3`_Gil20pP|tz^x}WlQ*}hs+1=azuz7H>vu#sPE?jnRG6CTMgav<Sp+*Y_
z%47{GXmjX`P+O=O6W+y|K({lL;Zb@Vc<0_==8V`Fal{2K*6hOXjCn@WR>FOMBf3q`
z>h-vrG!uQr0s>j+#I-1jAG<V)(F{v31qHPVq$$PE-fVmV-!D+-PFlZN5MYp+fX_X_
z@PtEhp7ZR*nLl!+i&*Fo0zg0-KXcU;nrr@rD>R#}ruFmY{vQ5)MYqK~2_i+JnOJB3
zMNy9|F$sv&S=7!ii)vqsj277~o4_Do2W0fn9SzAkIyA)PolQ)vjUND-?2@oIVHn>4
zNn4v@OJ1=2PR_VuxdK`(t!~IX=UWP(>CS<Bo~487_D^*ws$eZe+_m2&H4199p{PZx
zh(#Q5B<Y;nXNF0ab^2mkKxv)pB9|~5LzH<56zm4~B>4&+F&8*$W@97P1U+ry7Gp>n
zts5=wNxUa^Ifcq9#vOw-%<}Tlsfa<A?uIopsn7&egtP0QE<bJ(ROmmtj~pEC_daZH
z_ulTjI!udRtPX;y9mxPzvi&%=3f=P(XttdjrP;Wtff&bhEf_6PqEpnQy`u0wsS271
zlQIZn9BH{wkyoQ!_Q?M5{@}2;zxgxwoYa>2_~GsQ&Fu;<;I%DH>PyiQ36KmVEfVBV
zh=wl1XU!xOTnywLbxHLdlWw-s*CqE1OB$Gz&Z{#8O<%2yCS4IqGR>q|WO6&HQNCm)
zn`<Q)feupoNUpp6%$J-}L;$;OR)49U$uq@a$^P--=k4nfXY@>6&I{0)!0E%8odIfE
zs$A66*3HdqiepwaPF8K@=+op=aQxj$trWnLIEPYZ6knH~LG7tsW-@1f5OD`g8D+F&
zw8A`Y1<hEVUs5=pJCL*&G9u6*O~C{&4#!+m2>K8W)_CSS;K*@DkI8e@%7hx^D>ciZ
zMBof#0l~t)d`S_PzDmr|%urwN9996h_5S@ocXx6D?)>rr=HboG<~E#q4Vj25Ngru{
znslw-W}X}6q@mTFdOA(3cJR;L5Ap6NXrc~#R){{8EfP&wBSHayc9L{-z`{)n?W;g`
zaGk({v-;GE@AvHzenomYFdkIoOqnfIaeiH)^!$vP1?w9t{OnE3bibzQd5sF;$;d7>
z0&(m@Tz<fFR~|!BMN|3co0etuVy{XkhOopyT0FpCEUp-jn9F0>waFr?$N35xvL$7k
zBpF6BDwYS{aM+8Fa3YqYXw|4wP+Mx-2u6;_h{kIQ)cL>y7#XU2Ib8%)03$=?MtTz9
zxu60V8S2;_Q>?E9?p#m-jJ=+s2Oj701{hFHmlyzCXRv~A02Lv$b)frkzM6SK6NC(G
zfHGwvhbq9HO}yW{0Ug((wk>a@7~z}(09yWNz_k!=I2%P_#)69aGn>92(SabWXEtSk
zwMC)c@G6LO3vs+xMAI}@Er_$Fe9o9n4xr5LP~D4~%0xBAMxHMY(y57`FVVNtoYE#V
z2ssop3*Vy<4UAO2SG#b6N&FUn;9D67KfCrhjM$01kPP5iG(QTH?J-%sh1@z;THISI
zv6=Ky7N&^VJV6S*S8SFuf;)d32V<^Cfv7oTAneTHmClGZd6sBjG8+L5$zjK87cqoh
zcs7gBhqDenHYN-Z)uoX@ljly*16BsYS)Gp#%>nT4z9+z=_J)jh*0qt^(>4V(T;zo!
zo}X<{Jfw!jPSxlu%3^hXvPt7A;~YwTf(^ZPaRRbLUS<RtCQE;Erkp~`)>S<F&zhn)
z<r`O=NYBdGySB^TW9iVCnSvZ-CPOO7j+APLgF+*fG`VO;De7J0igqUh9rfnbgCm=V
z`pCF=Y%O1}WkA(3!!h^Y3DWfb%l6KXA7A&jwt64;J|2+aZ}Mmxg!tap`|TYXCW8Cn
zMJ;77hAOKbn$tecE|}ORKsg}1+I_oYAM@lc6nccQf($x<RTV;5BeN@jpbyj`I=7ZD
zm~wn+n@Nv1Nqj-Y>WPTaWRMC?ICCNBx?s?VH~~9Ht5r7lU&FBrqmaQN051)-uho3)
z6|SP>zM4+z01c^+b#U#)x2v^3`?3nw;XZlSxRY})@F$qqlbK#RlPla{&pm&}4n~rg
z!AzJFZ6*NNnVjo|jEs`OpcCbWkRPYG?`A-KO+6`{8+)JKt9Uz$H4G^_B&nfLDWM5q
zM^SQgN*1YFI`Wir(L>wDP%>meKGtOL(&nmCa5+2828rL9a*8E(9!ZO6<l(V+++@(H
z*F$hT0CAu`Wbbfi@343HuMay+y3%fWYM7cW9`WJuYU*||P|b=bMS=+oQD6i`rW=)v
zcVd-T?Gr}yA>~)VqSqKQCE=#&O=fOcZH2(8v4cv~DV=?<#-=ryr)+}8OpG_3-RqJW
zM{jrbULU>@YF4_dNg@_ytL^Xn_s1O|&38M8Z{BaS%OO(C74HK4Y^8)m(imUVBzCGO
z;Z^nMr&_{RKGlec;;oZtrKU4a&@bqUi+PTPoL$6u*x{=<WqC_0q8Eoy5p$(o@<lUM
zxMJ|^sAj@zU0htW&>WyO!-i2t8stKf=qlCwbZ>8U+S4;-L=CEW%VMVNz-@D2Q`II)
zd)vmc-03vL{s|LR(^=WrC2}1x$}(%hUf0vwrlEhq2Et(nJbo}pm4esk5J{Sede*v4
z+gA~UOS=}55oMw&Vpq|qfMQ_EJxBSs1Q=6bRSB*xZ>Dg&(oVp^;r8wxk4B_@qYsnI
zaGP_l&*z8Sd@}AcQonn#kulU#l8MUg;Ja0WvX?0$#U)pKg|>p>4$-Wd$qj6(pll-@
z*ht8se033LOfI>V$BOA!{3cDgA|HkZi1td1n=|z<1|@B$GI}*EwZ(L6dbyOyTT!$<
zU}i5YP4(96-6k35Or_BIaZ&^_r<tmbJ_*)ig+5k)!)gM&Ixk_scD36g(%B_G{3$7#
zH(CTVMOkByOuU4}PLEXjz>@ubU2d)!x0a24#5g-8a2aS=W+GgQwotU>c_)k(#QNir
zi1Ea$=iGCN{-EsD;>EkXtxuEh;wQEB!uqDhs|Kvf?^3ON@V!_7<p?#Tb&j0=XORyh
z&L%=ubBrdt8slh2&P-t4fR92wWRmuAe+OT5KTX7dYQ>g9(3@@F4dqotCje%G=Y@E>
zp-6o{#8n2qIf9yw!e8-=*qkE!JFj<s$qjXu3*AU-7tX|dg`U)}N-rhAiV>AMS}=I9
zH56?UyrjX;?`Bw%nkVO{dh#3&X)CtjYz72$5P3k)X!D6dkHg|dltbYC5C&FjfA>Q&
zK6ptx4O%Uo2Ch4}stVIXm`C4zY90STkxai!0j~;gK=2j;=~6&)TEorOs~f``CL{gS
z=7SYq9@KYQ{88hF8@AJ@St<hrDB}LmqF5WiS1x>O>U)?(sMbPX_!@=$j5v2ewnGW1
z9x&^a2gq;G)fx!c6u%Wj1JeCk|9by%-=c+Pz1i8{QOe^j%3wC0){Whz07*h0;W`m>
zM0(a?p|B@u+lT~UEH_Aox0y>AS?UGBOj51XR(?(T^l5no$zQ-UEzyiwf1=FG%XcmE
zp2?~|UAb#xquIkc?lhUhdR`}T5}BLZo!5#c&yohsxYL$2bP-ysjFuai!x&9sTFk43
z^{Y~k(q08c;)-c+E80VtmfyII3{y9-HiaC|*?H5q1{or#tEmEq7!KmZZp@eCz12#Z
zZM7`kBbLalFsJ*FF7j|c8sZ7Zt~5W!Y>tL=JnJVN<7v?=>Vf59qjY5JoXIRDHI+E9
znqbc@QrUK?;lU=ueb>l>d4%ESP^1oLlpC!SQ|{oU9BcsngsUea)*UOpW5u`6iY3(<
z55~d_BG!v8!Ai|N^Dbj2ILpCYVIZl`Mou6yF=qT{xOclh8C@kgK@ktA9Z&<SD!Nx{
zVrZF^c+x@e2U*C}s_w9FsO(4-DI$?J=|F@;7fVe^$R5^<h8bRlp&>hC*4MmHx-#cW
zR$gTtC#3nw@Ihwz68C2#<~Co+n7Goq`#P4uMQhD$&8uBw*E(;ra_4?YWhka-y_}xI
zd`XZik#N5p^8O^J91e$eG$bJ5wicqP8e*txlvI|rNsaY328ZP2!*ow9J13f6v)G=L
z&TZgE=vpY*7(|ymg8>ZW2g^oJNQ*MZQ8(@Nr2@($0PVz!E1q%Y;XU+IMwVpZWwl{N
zFX>(NdQ{>qKv&F%bt)2#d4lft+F&xN=~WyICa+g1^W)@<cZ(fEl3hyOUxX%}oDi+`
zgK>LgYc>BGDSgY8&A}<Qha2t=A_QN_T|po~yECMXbCZcvOy{$ax)wfZutG8;tSz<R
zV==_+Y+LU?9)9?ExWvcEUT$t3e%yQ;zha|iub6}KQYM#HBK{gPZ=_ph)4Zh47@zxN
zr6Z!GObbiKbYl8NBl{QJ8tUiV#gZdR%HT(<lTAw3zOi<=4qd4CKTW=Y|7ub)wi^C6
z!iqPhRLdETqL!|G!y2+S`w_+fC~RE|PmLkQht*DQBrF>@v4Y(^8&gHzN?;ckdr7>Z
zr(<>$uXdt1ML(I2w{l^Xn7w7+DuL<ci@*d+RW&YOtZJ|DFtnksG^;O%$<{8Ea%;2`
zuj%rZB{zD|D%pt*F2zlrHu;mpZ7CHtTNW3=5!Mv>vDrg^HF>DnFYc+<V?+i54p}zy
z9A_~YttITm+EGY~*<rnQzw>bLJ)#wgQ(iOWP0Ql1FqIPOY;lam_gx8w{6%5t2FSoh
z_0gA7cz9vN!*}!HVVR$Z7{QI*;1n->)^LL42wa~-^g~!qos3{VjRM+<*`h;-(r>;I
zdq!70KI%|D)^EOHTZ8;&l{uZ-nb0T+OA6SUqNZ_J)TSD?aK*BIrcD%u<Wuh)!(^Zx
zE5<6cP}AZEPH<&0J75&5c_Wb&-=v+2&Xrh$NgENJuC?*@NI@y|lW_%%F<aF=A7OB9
zWKG2P;XW!g+p5PMYt-~{UgdO$DFg3}0#d|>5ScF;ERIcW36-N#(|`Q&#}WZsy1u>^
zn|UVwmELPA&3vo-JR-Ecui)`0+F7W-V*+$>-i`^(#rZlWFc;_Pn7~||pJM`ZabAuI
z%mw>6CV>Ac9*)B1OI;_@0*VXBG_QLv)35G*iWYT6GNh#|q|=nEFWIDPUkiISQ&nMa
zrsZchbJR@pJ??6$II?gD%ak#sUek+C>$|VC_R+d?IWK-}@>EGX^u(hvfHCUG%%+u!
z6|rJC+#1HV!>rv;wVJsF_AQe^7ARB{8O2tU*>g)isl+>Y7zGowX2eS%VguylAWjvJ
z^x_$oV<8yun3aTR$e3J-W>k6bQ}_TOz@K{iJ4^t~Tr1+E%-F2hm0HHc-f<uZ5;4bs
zD-<sqc3Exif)&hC_x|kA5`>TnT`7tYQ9wE5L#<Md&QmZ$2UxEn9SDw6LnH5@-(~aO
zs8#GS`E}3HW2{%T$DH4h;|$vG(ESocQ+DB8<zc{aPSm<s{mFO{j&Z!2k*fqkBc{V1
zersB6(&zzKL2I`Ili_eiz$FUK$ts=~|B3~b$$DlfF-A;5MzYmZd!u^$!4Hl458Y3b
zPZRXy`U2<AhHQ8wQhR4NjhNN)WlF^;u=Wpfo^g88%{pbM2D&+>(G1G!aen4j)*Dmo
z`h7mze8QQLSs#9$xa=~MBD*IlmU;tEio%S5_c1@?4V{H7$?!{#0<4ZmcV^7bIe(@G
z!cya4rH^!pW8fL-F?7CwazHTVw`X_lMt<-wo?jx4&fQI%{<NXFh3z#X1}uodxRW&W
z^knt8Q9gt=hiDSc)M$Mv1cM~})^}Jy3NFxuas*R4V7HC#ubR9xEYg<6atYLD6BJjO
zjNP!+d^193qLS%%=-Fg(DCu`RT$T16Ig1(Uk(0FH9R^A>w)b{tbI;DaOB)@4Y(Vn2
zh;)qVuZ+H<Y1M+-e7cUZu?B^umNvQgy`k$5Nwbk*T_RJ;sY_;4)3k>k(8@b9b!SGX
zryldz25NBx?X;Kj1-VwMe$?A+{m=1tjaF+#c8_i3Mb;zDSw^nST7rpR#|FD7y<cqN
zYN@(UYP*zcn`WHG-O0H#@&?HgV=;=uq7afA!31Vua}dV}76`)Ox0lLbChKimlq}xt
zex6}A%FUE~DW%l~LYZW7#1-bz1@?i<MVw<H)RraS<tzW7Q1;qPU;$nlPrSuJ1JXMg
zk2=uX+52gIDec+G6d1jO!_C8w2N^F+R_eb$?x2F>aDR92HTiUEOMTcpeA7GJ-`qQR
zOBo9FunxBNcRw8VP<y$z`EJKhD&ujgEtT;#%`Fu>n&!khP2G0y{bYzYsE^%A<>!pu
zNp%ZjcP5kE)B?y2;28@d>Rp)DI+Twb#T9+;-E>|M1_nE3N^T{POk#)R#!Es+ZiE7=
zLax!SmKR@_3bUM5*x*)QWSOU30(yTU7W%T3OLYdG>ieAEZ7zkB>-n3*!w)?XX4BB|
zI0|Q}zNaDTyPm^fR!i}YgxJgQ5V>?_|A1P?gdl~{Q#2b$c1n0))bgPbjIp7YXVe!O
zN@$p`xbk{#)zqE0{5B`-NlghSVvT2`$U}S76$)p7JJz~&f~NIOaJA7gf7UwBo<He4
z>8w3o#V@OC&(~I;;{Vp3K72}nq)fI<wN~o}a7~`G3UZLK;WyGI==hs>nMr>X*U~dN
z9_}xJt&90rT599rzJ;t+LT1ZRAR6xSV*ii0(|P>Z*kwHFkqt7#vo%0pRg{ouiF6g{
zRxK}-+uWn1qOt#l)+eLP(AUk>fPGJ2apqK$gV%^vwe5u<I#BGzt|cug%5n6mmVoRW
zf2ys=m*2{(Rd}WKcGkAY)-iI96_6{u3F?*#>ZUN+=8@l)ZhN(ARH3&OgodAJSZo#w
zvTp^>MHVYnW7Wu&V$Sictq)YAaww{m#Ein9Jrje9o9St}R8rUMw8dGK)Jz_)D#fn|
zjbxx$auJ*TGm?H$E<&7~Suh&7I9+w+rO8z*DYKdfU^N%O(XvP4MO?lNBhpN1@np`!
zEMznwOVBRt%;HuMle@MTy}tG6(%SxO7uR)OP@N<O9E*rc1I|@am(VMejEABT64Np^
zsq&6Bjz3d3z^Uaqhge%>?t`gl<{T*6x#4ZFYE(fn7d3aXBCJ+?|Ep!Q%wp-s_xu0c
z*|u6O>S5y7c`vbcO|CgI$GmLhj;w1Rn+jbIj1~o^GvoEr^?%)cZsCJ_M{BkHyxm#B
zuPZ;{zTreJ8s03bjnz))$&*Lcf5ALHP5p(><A<HckJ(pV5dJ<~durWH&R6(QXx=5d
z3Vgua6a@t=S?t-H4<hGfXgwlZ(8v7M%RUr4^#jaRjJYP3*sWjxvvW#jY6y;=IkV`@
zXL;&g2kxo$Bl;W%*7tpPH1bbhLJ!&#H+sQf`qQhxJ3Whl44yxK3L9GIIi=OxBp@Lb
z8hL#eHYo&n7DdzU$_lEELw^?Z-L@Z`uJ8ik%1JnA@gGRi)}DJ|{dll#y=Bh`8Xq1)
z+xqDMq@&$I*OC{4wf6MM!)FgI>`SY&)>?aHtv&2MeBOQd^na|uY&iSfTIT(leCB+M
z_Y3jT<^x>exLJu26MB<Ax9Fqunse@WBj*IZu{ZlJ@J1NtYWq>U<E$>>-6_n~H!r`#
z>L8Vbk%I>Umed1&j7Apxd+JijfjjgjAc3-J-F&;dy?MCP+ub`j+<f~M6<wGldfia$
z<DOD*jRi0hZmxKcJn^E|*ulvC*2w$JOo@H8O9%}h_ulWn+eF{nhsIX7-~YUaM{L&U
zqXjhjVRP%Bo39zXr_e5;uLamafy4{ko{xy8N-JCbc<c+CL(O|m6Mg_Qxb>Eo6N`tx
zq+s?VCuEbtXS{tm9$765gG)`^QETL$yCcgPoI3z}V4cS`|3g<5C*!U~8_i8u$`)a_
z%u-?VpmH@PjGQ|Grbwek0C(;sNMb!Ixb^<syZ3vXY=CAr-vJHn@4Q}5+f2Mf7*yp0
zgM%x$cfR^1`)o}ye4w^_ym255J!EeZS^gwWBB~Pg1H8awYhMEzUPO2wpj&;J#$M6=
zW7n$NE}k82Db4!Ob4LSu!0+Rjr4c>h_F;HQ=LC5BOHa|=wxJAzK*diS3Ne8JgwAP)
z$#k82*C%EknO>!v<WGeHRT|lQpuoTzxQu^{T_AM2Ermrm0J2F|9pZR`Xc&q0N&^nH
zmMrPSrzgHY%8t*E$ZgGF@Ip;<3fUvY)g(sTAL&z39b0Hv8owBJI#8%s@{p0NgR=%d
zs&S4yYQ)faECT3Ci`=$?n}t)i?+v}aj8P6T1^}Gd8R@a1M+S58p<ZxU+>oAK;OWkH
zn(~Ib!pI-_7jD4O&SROx4|Q;IywkPwbL6ys-)#L)r}eyd{2khlwUsB02bx(bW8uRO
zga!gK%{C=L7sEo6!IK#+0fuN4>7)m+RAwRNyu?$m0Ku&cD7P+@VgdRm=k5gOu!+v_
z_?j;=57Vu~gcE4wMqa<2znEnD0A^2Ba>(U%;LoP>ubg~NUwRR3yOA4=(N^Z-%taZ5
zLY)Ka4P1=GMyguJ;`SbqbK;G>=*ptazdCDCa8kUW4zMG2)*l0UyopG*OQo8E<AxJw
z8lL$P+5``<v-rgsP0t+sa^gnx7Y8(Q?S>IMuU(9sGV*|yfLUm<5T-}0?iS^TeCkF&
z#iI`Eh5^qtzVegrh;tG%%Y{u~>IS1LZsCKzzv4a55}dZO6rfM8M9CgEvAlJ1`H8g$
z%+C!<uO{6p`e|qXU>ASGLP8$y21R?&JR(%$bm&G>vHG{m)1kq-SQ5Bk7r}zYe&t9h
z$sX<u2CtZ~g4a$UC^ciFc|!+;Y;(k9n$SKzI!@%AMA#DGWN}Ni$G<_Je`can^*(c%
z>*l?d7cIwNcEv7Bf?&EY>&9Lt{fc|53XUA{s@#~~W7T$ybUT-TuCBU-MMKXqVu#i`
zPIdE0$k=2Xm-3CePHDlZIW&c$1`SDhM5kDBtv$&?anGR%tjMB`xs+g9<`VB5k1}_o
zS-H8?HqL|j^}%dBc7m%s0B+b1JaR0^Da8-RIVJXd+PzZwt1}ai0bB&zgP$=PC{xyI
zyJH(>H6Bou8nC7evQyl<>kVBdl8Sv=gFflq{VM}nEgIaRH!d36fsjH9%5A&Tu%O60
z?y{Ojm8K|HP?$=utfb1n9{DHE=+Fs27j<HbVwR&LSzg?bdv(5p^Lu9FuGA>8%jBMK
zwX0ZnVpEw-T451u?y{s)P?M=Tbcer%QSMxXtIZx|fV6WNxsw4*z1AE`NRk_->Pho$
ztpWUU?3bQ5j=Ij6B4T!F%n&3z^M*i7j%@MJwwrMe8wR^94h2xtu?uXQ^hu*M=0@iu
zcOvB$id?OI$MV?uKh%?M#K{NQF<4Y%I)N4gr>W1~Cj=O@bMe9+i1cpY^~K{qI@e|s
z+Dr%71E!5HXFMig+}mLDQRHnZNq#n;Y79p!6hDj_Tt;%SIw;Qyp@?cJ>MtGtnPz|*
z;3<FeVg}n3(+^Hhei#kCOUwNY<1caT0}R>^;!_mq|7-TmI?3oTomsFv6~<elN=zLS
zJ;99S$4j1r8~pVqnlwnc(|m%_hgnC|$t=-ePG4^}nWfCu@5#HbqJt}7rN#`H(oxbz
z^r8AeQORnFyr?<C1F9lCW(;QQqmyY*3pd{S<L#$#+rMYr_Vq!fB;?0Ri-IlCkh3|9
ze9l=?UVn*aAh)VZsd4hCR@sI#RC!(L_*P-lU(ZxRMG~A=nH{cvr`G04&r~O?#D_Vg
z9J3!YHto$c4*AYN%>SV^aQogE&|uXs+gI)18wS!<SFwbs%CgPMO57o0UBI2tsCZz_
zrl@3!VwDPf!V51VTS7f_ez-~_h|+!~sz<B4RGKxhs!UU<smJa<($j=Snm}@n&15WR
zQ9_ovHE5?}+@16_Q21Lfy`AN+PNFL@iEK%VU&IJGg`E_L3?hmeEDfuvqkhxwk{_gh
zzTt4v3Yq&oQGldE7nJ&aOuMU?CdRH3v?Dw1nn?GI0GWn7MS$!T>C82xiKzxKS`nE-
zII*}vdT$|v#E+Z0>LeDt@_iQA+4t8Bhlz3r$-K-2LVn9q>e?|#=5Z$Spl_Fn+ppbL
zEL&J9Y{7VFqfBh8iZW@~G~dJ_`_9yhKrG(hYLZb5U0k+kF0gy+MF!)VRFY;&F?g@c
zE2!o&5PLNjxrVxH$8g*#I7=3SC|N(XTdcMpv^(%AtTP`6&@#8xw#?n6L7??`DNqEi
z-9cgQ#5oyV3Fb%!Rv?(;O1EIi(z?zer&4=};kd+4N4lwKST8UjXZ4BL-&)0P(|7Fq
z+9S)2`t3#ce~zBr(MLJ_F5L+8H$$R*GCM_;L(GxutL=yFOT6C=T<a2uveU?*#4dqS
zdmg-%!kHdllAd16Xzvwry7>`lD>|AGlMuo#M|a&onHGi%LTpfuJDwyZmU0SrKoo;8
zZ7_iPp34s}tjIY<oWe72faWNDG~?phqxuj;2J3tc<)TK3jnRzl>x!FMDcSp0TF#Th
z=aR*5NDw!d$!{c=8-$u%X+5P#HchapxtnU37ougZu4&FEHZw2jkh7<(k=B)*o84IU
z&<jBF)o5MvHv`kO)!4~t97iw`+`=Cgv!IM#j%ynTZoRNi97z;u@@ujq41mYl{(H&S
zYhO>ku8B4|qT02;rWBQPc)NWudrcCv*Zxvs_S#nxvu}+|`YeFef3AF8%gEOPg_rFs
zE@fXaDVwj9+MRH%VvwT0#`x<H;!ratBa#w(O5!ykW(BbV!zS%hSi6&i?<C;`s)o6(
zbfwFQd~u*aB8->72=64>*%Hrqf{B`Nh}X`lVfO;ALlnVWyV2(9LKW|XPlNC3LH~>M
zg%<6XlP|bz8=nRgEPAPuth-h&zid8&b)-sX?W<x*d4G$T&I)790z|UQ<<G;M4B`4u
zzk{f3xN&#bygO|E-42^YLQu}Zq5%D>iPt5@Eg~BLz~GfQIVn2DTq~nhw(5ahDeFFt
zg~p7{Qrg7DU!V@$p)(sr=1YIgnJxupL3TNcL3}m>_&9k@j!7hM0>)vKD0p%p7`-@v
zDQbo2U5gkVV^}5b4;sn<Pi9=#%balguonEW_d9bEr3~3;euyqqzIEY+XO<T&84-Nr
z!81Gm>W0Y7oVc<TvU2U5wPaE@{`#i@`(NWztFHWA(Qf>P-G+^jym~@If<126Lj}IK
z9%)Kov~t=qnSTn}hT|1DeR(LptR81`UX(SnLbx_1kzn>z{8(bqeYla;<__5?^qLo#
zCbnH^gY+tf+`NOZRS`bzf3?P~fn8*i7V}1dEMYmYeM2OPKpK%haIWm~uEz^phs;Go
z8wgzAeO5ses!K3da^SZxZkEN;Du!-U#$rrnRl<+na%RAz9J)wCrJWmv1eu(i*#Vr7
z1N)3oE2Ia=Hb*0Y06kfic2>BTIvac%bmM<2u?3F5vg;E^t6QIh->Rg?+P?YvTxNOM
zM4}Ill`o$Lf2>`9>dJq<piyI9XGG2x3cH)(0iqodEFAeE4`eB7{oN3$LFwXGH8*_B
z3Kb%J4@$ojP(P$Rqc!qLu36Kw=_3+0PNg+V<gWy7>2_tm_I%sRqOcFSwPP!<va?Lf
znppIfV6KkEUFyAvIfDy<)~J}^$ATt0f?H(`iuboxo2(_R*7JI)bl1}q%79j}I~UkP
z`fSFwiOfN^s~vZ&$b$BpR%)`-9{r69*6X)M-@<D!?W_!qi5y+YLt)ks+iPwVpiZjm
zOuf?eY$$A}b7kc$opirSxh3Qg3h(A$m{|A(nJw!Xz9aHtE`XiXR~_I41QxPP7<$JH
zfhpuuj@@wp4tc(tQg`N?o6QfqH<}klQFBj@-2H0vAUyEl@1hp1@ZHwOv{>ZfQuYDA
z_10ov@>_3-`=nQICmsH7t=(bba~ubcbPRSxTb^8URb1rGF$q(5GH@q-Z!vvd<$bOe
zW+UrEpVJdMdSH5)Gk-LI(+758;$Kum>J8LEfBjx&Jm(kI(TW|B9PMv?-IW^cqFC3o
z)M~j4!Tg^e|M{19Z$CIe=mrZ60G%KIdG$%Bv&z55@t+^Tqr1uZQ{q3z6!0enfR@T0
zMD7&tcn<n!V{Z^ybwBV<DX<`PviA`Lpuhtj_B(*WEE0`*Lfw{+bXz`lw6ch-wP$P3
zpLTfg=qIhUXBa$swbSkV3BjY|nWpZ=w_~_TWBmTqq-y3=Go=+~^oA4qRp&D|XmP~}
znk!^+vJn4BZ}2n1)QI6~Kp9??sJkNRaxX^cU^^)z2i%=a)FM0(SvH!ki290Jyuil`
z1m{%WCcf3QM3qd?;k+nJG)5zqv4(DHF_I|eHp|8ort@SEOCDfdO@r|}IcIc!!*qEN
zvZm3F?$n*Qfs+VOnf9TAsd@1#ul4>c2;2$b(i*ta=qwWgnvGI=rHl}t1N_dqCgiJ&
zYl`Jl!g+~&JZEWVOq9vC5ZB(Y?A?R+t!K|3KW|~Wz>LJH3E-KH(TN0R5;TQIB2AFx
zA{ZkB<LR-|T|x<#1(c-ZNczrAaiP`C8EWG|B|S{0<__vMw3t;9!?GUD26D`J9wc6)
zy3A&6!ui^XBch<%h-km2TF_)e@X3TOhX~G)U#4P;e#CH<?uy*1*b0X6<0P?B`*`@O
z^{i&A_rPDim@CYpVTlU0xPnbB*tPN%s0F!#L4PLGHETqBD~PyAMPjYPe4Yy(JdEx!
zx!l8-QDigIq;v~$6PdmY7{7&1KkJD+Sg8!ehCVB6QPc6|OH4KnB-$gw4tgvtay<n~
zYDg*@x>3((iY$QBq^<e=heM3&y0v+*(|h&)E#_xvTAfsVs(A8$aN=YYsWnX**!IS-
zP<t#8d%y~#8Z(IAutzr0%|QIp!04aB@`s~sK-8ZC)yHR=%CwZ@k@8Lw#xrv>4o^7-
zDJ))(@tHb4zyyZuA)B(xX-3b<6R3;QoXz*}agUjlQ8l%eGzG)Jbu}dxz+Uic*RpYZ
zwncH5pr<x<7`44?T1J!Kvl0r41Dson&pQvm&!kW6)RZ4LsBFHfO|X57(HY*dkRU6;
z;jhva;?0hCf;LC?JzbRV@5@dEbxuHTqrWq}9smIdE6TDDAO5-T8PqH?Vb^(wn{h{)
zaXY3Myu_uy`)=LL_m7mK$EuXY%oCkayb&y^?h_brD*lN<dqv08awHnrQaNlQRVKQc
zs<3Q^^^~oG-9Ph216UFNbg$GXv1&2r^c0R3tdJ!Y6QvrdZHt>W33M`7lGM6}VI0Nn
z+sC@yF)2smA&&qmWUuGKI<k4oEa4shq2<r)>SzFSK#adS3(xB5{hB2{Foxj7d*T+)
zk}S*pda-C(IT@(0#6l2%kq`{R5w!V%H7WL7QQN3B#O$2XUX~rm&SY>K451_+D8G7>
zZ792TGb@%EABotQQ-7M7UResG{Xe<hRnT0p#HBv0D^^U-;Q#Q#4k=fh)~HjN@Kvdd
z7c*CoyUxx^63WqBR+91+KM=M`3|=5KT8ukwo4r1GN8~jnvfi>qHHc3HIi^A~D8{z1
zE)S!fX`*5MplR6Z>KTJ%nyVt|fm-Z=iZkMtshN<;O~oS?)}T=cjEuQ2pjVSCE9^TX
zX2Dj_Gj3{^?G<1Z2`A<ZDlx5>m>I*YW-Op(+X^~1mt1H>exgc2;B$>W<l9t_wbHpz
zZ^VUZUp-#0ZiN^yju_&J{Y10e<e2cRv`WorzUzg;vOrTJGxTg3)3zvKGTt5U#oMFS
zU@BGGu$Nw&j$a~&w1QO~i;Bp9)ENQM46X=&C$0;)Bi#zcPa`|DWS5f~NenTRW|~>l
zkT7CQUOn+GCbOXNRNMu2_8M?=cQk|((qqPvtgs)FNR;nZW+ad!6?TD_SaJQBRLZoq
zzBHHbag}aV@->p>Fdd2$cE$;>jAw`rsJY|KG($`q@tKfQ4k`J}tEjuBuyDPU+t++_
zG|i*GE-5ZEpt2mK$V#o2Nd$c(iJh@NK`T@*QuMU8wl@zq%L|~gGD8wU`#N1^;mHuw
zjrRwVTJ`Qu|L*>u-~TiFwUAwEojB3L+F0#$o<4nSy#HTa?X1Q3|5y<3{~tcSyZ`?h
zpO-sZZ{Az)U%mRr(m$5=civg8g?tz+$#lSaym;_i@x^ex--s`VAJN?xHceRq7vC&P
zr^qgs>DC-?DZ?4t1TcFhAMr!9dgIBVpf~*1xoL4I;(n8*UK~g=s<>_UCRCZ4c)Po`
zvv;t=vNd`khmqVU1FYx_#(T=Vj4%9PG-zFT1GjbIp1@mPf!|wSTwKK0*1TUU4||<<
zbQ!fp|8|Ggl|Qov9*bBMxP8~7)C_nZuNfHi3@=S*6Y5dqb3pzHx|E_Tgt>=JYs&4(
zU4()yN)UJp!m0oru`XQl85zU)shhl8-gxW|JlLa0SM6Jvd2VvhC2qAjaxY=bu-(6N
zgWs*X1HZ@cO?0!d@DA`^ymi9JnoXH2?&{jg+Vd5n`}*?kU|Cq42QHaG4)8P(QxTGz
zH*tcihFI=>GHGOVhnE0!?3BFKo#>3T-hku43a`S*9UF&*FxksP?&A}>E^D8806A9R
zTv%d%vFfu4Pg<VjMud(X>>OH$?>;2|ZM<X`AMDkKcZcl1jr&Te`)&_=`|=-4uio!l
z_wQd?yL(o>_EKD$(92rG+I|nGqaha9*r?r)q1~@puiqcOx4L`p4|(SEo$VM+TNFZq
zvY(z(UM6d2@24i}J`hb~j^rzA;1lxQOD}{axBJS17T$bd`9?X^-uCYP{Tj4gvv4>y
z-TRGHuhXD@+}$&R;qNwH!c6xDUXZPgU!at>Hh;H)MBD=iSexM`MhfCY!O}mLXcPH)
zbANAl?{$~)M={+^OP*yh_bOf!O5w};G;mIc{-FQBRnZv9=VU~5T>sgd4E&4G+B^KN
zLBqTM?@0&mTFD=?uF^n%<bA?5>0Y`P{~MD*?f(6LFMrrPeAB(GS$jMGZ2?B=jL@=3
zk;?vK$?c!{*2fSfdgOvTmu`PXAx*TX{>PH;snt3c=-u1-<?wLl;P4+yjfQykYIFDP
z=EuYL+dGFlTZf4CxR7B+r6Di`|I84ICia9r>?)u;n2~D49Z&rL*a4!2VHVz<GNMM@
z3!@*zDng_&|4KH4)^fN3CHohHU+cd%*868r{MY)jv%#zVTJQB<?Y`aV^?q%%?N6U<
zDC7-)MZGhu4Jz7%$6V-yx4$;z%JG+F2VW6{_2uEl5DmNFX^2n$?X(@cX<wWmaO|7(
zczt*gco6~^HW9}9kbDpEx76JbzW?y+3+sjT?|;K+Mt&dnMZ;vNMR4t}Os&ki8#<re
zY2c5ik@dZWUHQk-_Rd@RTLz4t2V|E!PD4%1>^o=&#E!t_sxOvw7E1KT1F|~=4vS2C
z;Du8^bVgVYs0J3Uwe!pF!J(z+OrK;Bb*hqEoKK)qZR`Dqe^n`8+!LuEnTF<ubpPLj
zX(wj@#@A(9Y0!Te*4eOj-X82AVrg}9Hulb4dHzhqMha*BzUvOi-(1Abz<eaMC;JvA
z>?7D2_CTvM=E7LcrG)qB(B2xj=nBC2qc>qWiDAD5FbZQ&nDQ%fpa@B<L)H+c$j7v^
zv29d&zO%poe!pCG8Hq+vYi3yS&M4KzX9ZnI7I{()o=G(kF(YR-fl1(9<g>f~aSxEF
z8!zpOx={)l4cC6(4{(bkd6iXQf-uGi^3XR5HyDz>+{w8Y_!GJ@J$C|+_8JPlGVq31
zyf!gz9u<MzMuO;_?7CD2&qu=Yke3O&{GEPQ_)vHDwzWfDn|G}8qUy`RQOWR)F}A-K
zUL=Z9QNjuHZ!z^^5oL#`t_gL7d=33AMkv<1GD2F(dNFOwY7JmFji$4xcQP9eUDV`m
ztm4zq8M-~_rn}LhLLi^?D0!3@pm+_BkpK3k0r@8Okd?~MooV{97=GCE1K_|LJFh=%
z9pH<=Jq6Lp4SG&++Q)y+H)`)ER7XB8Y#2FnYgmr$wp!NxRqOtmb^oDt|B-e7v3386
zb^ob#|Cx3FIUtJA#WhEJcRIBHK>hE)Jzty(xWNAlK5HreFL?6wPXBwS|Gm@y-syku
z^uKBSFZmcsT)KH~t+t<_gW=N_`WQa6IuE;@PIvXG#oY0%oy)1Ue5dlgQ~BPheD74g
zcPigImG7O(_fF+|r}Dj1`QE8~?^M2bDqpk8ckGTq677w=u@`OBTB|jU#y3YTyC}`C
zMyae<M&Idy?>;xz|Mo|Vw*Sr5|8_bLGx5LH9^UDH@ASWS`rkYK@16cP*Z#M&w$gca
zXa9Sr48Bta-zkIdl)-n(;5%jToig}N8GNS<zEcL@DTD8n!HZJ{PfD8rmsG;$YK{%6
z;5@}`e{`p~z56UE{zG{7UtdZ8Ypp(flD7ZttihwZ$@vPOZ|<$YDSstATUz?YV!6+U
zAe3TCc#w4Pw8#`jB7Qh3I#9V&yIfB5$r^?Nt6kRCkxx&SEUdjz%NAS0AVEtMriy_|
zbPX6D?4`|r!nYU{1BPM({NVL@14(UoHuRR@KNt$uvqrxEnTOqSEv6~v@-H!HJmG2w
zBr(>^pmz7R@NlLr%wBKqzuu^&w*ftHJt|0Plb`~As;J;y_+N2AU+(;`cusBCECoxv
zxCC1%o$jepjN{Y2bo&+#fp)^*tYuc&ydze*$-JHG)MYm86<NfrEyJMh)_h6-kA-ak
zMg0F!=V_Y%KYenS|L2bX-|_#y9{<<c#FX0<ZiV+7cbdCR;U@MUUsL{Hdy=vLSbO~B
zj{o2B|2zKwSCs!JH#-89<oOA&jul&X0{qvK|2e|H2LFEu;{TJ3|M%lN`@gU9$>jfR
z#&%svDl)tR+?-BFUZ3s^t$lauhaQ?`@I;_n{&<XqD4UQsfz>>8`tI!{5Iu;zQ|m|P
z^Jif2--qFeF?;BtKXyXvr}j_nE&tN`zVBbY^agGpinjay_{BWQLMvpKBz{#oW2h{U
zu04D5=-E@AFBH1;-0D2;K7QI=dv=q2p({&E{z(so;r_^VCKxB3V$Kg-*zYl+9c@ng
zANLOb^<gK;Y)6sxnK=(H$?jYdo(wp)@wdIi(?md_6tpIma3~em^^#Iz_x0ZU{hi*A
zn_K@p+~3^7qL}NB)8oqt>=IM!b@Z7Afc>>q%P5=D54^P7w)_}=zKpXGcoPpZhSk*)
z(4`b49(jBjP1H85p#$3|bXSgOF5$vp+SIgM4=*jz9PvD~`goBJyJHh?vJh7TG=1^q
zc33Wm>!p`*H|fg1Hw#8RvUP!;Vi_@ASnL#w#k*)SS1&O!TI7vgb~dYb2;VU4-Wb=e
z7xjiCjG@lqB~3;F&<e|G7AEZ_@6RHU2Mu2nYLxe5=hW->ew+Cq#PovM1p6QrT#n^G
zya0vy`eyn5uirkf*O$ULm6}N4W-C8&QkIqxvpr7EJ+XW?P*}nj{K3l_6b;<pW?rC4
zkd}S1@+zRjG6QpoEq^lfPV?Rq*V7h&x}iUES6;i3KaF^ir6ocHuh;Fu@I@~UF@=h~
z^>!DBybLse2?w!M2qRT%!SwU*A>|YWvJBuze$FktChlc~ap)tE;ekb7xK;>Vu)^7N
z>IV^}0!7Q?e&9@7lxr5)^P~3KlAKqhcd)bn)6V{pjp7(475VmCOT5EJ%7ZtDhaY%_
z-cOtR2XQSymt>b>)17fwED&ap=2|dfS{ZI^K1YiMFOM~X;rj`3AK-96dpw1RdkLhz
zN~FF-odbk%?DrV<yIo8Q0^{6-w}>*p7~Vi{z1{_3bn03DVBkepR*QPnYRR|CE9}4^
zY-$nB140!_$ym9EB6z()e5gP2Y{ZO&siRefJ@JF`LAF{kcfx!#Qc=!>_%K-B1D2GQ
zBOZsjJPrI)lKeSoa6Y@f#43bm-Y|;GFSA^Zp$09d^mmOFZCbT{cdI+-Zg*dw{SY4f
zHtU}MRO5VyWfSy5mP$~7jAwWj!qQA0v$=p@*r<4V)H%k*Jaj2H6<`60ok5od1kX=t
zufRMu>T`VDI*mTZxRYSP7GbBjHJtlg2Qyu<j=(mBUmB^*uJ{akMh(2qrszz!pysBy
zhH<W}FmovY21Q7^!4>sl!+P9aZFkuC1Q-qn38FBs=qk%A`eGwt@M?F~Y=&pzf-}nU
zNel~L!z=cjnQW)t07C#qrB>k^9)FjvCf-69Py7&junLozk7AK&jH6h_ElYFNPvyAM
zjf5(%rqY(AGD9(FTUu!8ffT{RDJ|gAd=_wN%{)x8l3~xH_<NQN6-&k)5T)@azy^Li
zf>k)FX9nNYjR5(*W<BzkF`baYlh1aNw<(QXOvc9c=wxbmRm>BTE-w(I0#p&457J(-
zt+sAh8PI$HR7ED7WMqeuEf8-UU)eG!j+fR8n3H#INK8tw*qPUQ!4wyimAb~aC*A;O
z_zs#7c>}ot+@0VpS~kt5kvnMDI7HY~er9`Z6F1#62R7u1Z^4nn!JRm8@hSSpbQ_s{
zOOh-B;RE6ML$Xku9TCm8-6-%}^1=z+5gf+OnTtk7#F9r|kF`jQWLqynlpyeZOgZaI
zjH2KTkrd^d!GyOgaW>+nx3&59Eeh&Qk??8e!JdKU#UtnH6(Dg$Rcj5tXXJ^hY4qE%
z*(!*S6BJSa1y~Oaz+8*VRw6U|Xv8d1<J4L}Rxyd#Crq*kao?E1<Y6i`$taAeIohN>
zL@yZ-ib95c_J$_GgEN^7^d$^rd<BnTr*B&}bHfr4agCsr8P=eZal&7GQ*ZG7FyWob
z?9}-48nKD-fNz^g&Uji7a9W5DG$^RWAiQv!oy*=jS13PYlPnXpxeQx-YWnhJW^x&`
zdhxt?8`W*41GaxlPqy{x;Y6!+4&r&-7(zc!&@%esj6B=iD_S}OA4sDadzxYDL8KMF
zJei<m%qyp)T4N1s^2ouGodzB(J0Qdm&qAd7=Epp)kVp-jrz7X;*x2s@w{hX#&@kl2
zqcaUAuip^v7FjSzaj>d)whrI#|3CKLb*+t~OBkKMpRS^;kVtYQamI;kY-3Pt=E1;#
zoWnTYnnr3tzn0WWcMD8n-^#v>eFNW(?RBWCuI{dGNf?Z0#ysyEgH*L@)oIl_uRnm%
zKHfRmfnV_)N&st3tVVAswTP4!4Q_?t=dU+r!B&I0RU|dkyh>wg>5&X{DcUNm8VK5#
zTQQ=m@9edZH3gBoohn;wS%}Q{wtAQ97KSD%t{d~tUpbH(XF{a<=W~O^)^ou0dkcW{
zd*N)5Xy2G0CbpgfD2TfA!*rECa}K~VcFqJ`)Mw-d=Po~~zrcyCn%I!sLh@>?5y>AM
zx$o*s^vJdiFK-XT(Ln0VipU;vwZ(*diEGqt3srEF`D7}N%fE`2QMhy_Z{JUG<EnBf
zj<L<;-gZa(o?ET#kD2QtsS?A_%8h<m@a?Sw-!uWH8Xo<I;>%b<-lqT76VG<yR?7(H
zK7qrhy8P$3Tu5P-fUJk!88MtN>=0OyYGu1pm#bwdjw(x#tA3;wSi7T%#`DRWvRrUD
zgY(UI2z0c%^xnNz6(4JJO+0Zn&F-)n%#O?<zU_TGFy9Uga!ispo#V)aX^G#a*GLvy
z&V_Yqhm}?z%n5CphNdRW8bo=p7r7pnc@XJ6kRk-GcS7(}pV!2XnK!~Z%wL~5Ok=)b
zeoYO-`a`VC4QnFRVCJ%9^+k4_Piio0&2r%Jk&_?$tmGB66`?ryIrjmHimb~?tptl^
zZ{?Fmh0CdLu`Y?|nB_3(hd2538|OdS**MjCUDaViVN*^4kW{6hW9}CpZ1u3mAHn<1
zh2?Qj$plC!Bu-ioAsNp$H?8^q;6?F7(ppgLo&0RAVi$6W>M?&c4af#vO|bZ^ya*gG
zbXg--**)3s?C<Uz2&vZrv5v$96c<gMjsz$52`r6z>d!QpELSp0u?p&gDi)PiMW-~O
z#3ar*9zQX1IW<N_h2i^SS7uoO7(<^;?;%-7l<}m|BT={!3Z>(ReykJ0?&=0H&4%S|
zwMLFdre7)L^?hTx<1+)Bap4Xp35ngjqR-8fqpcRQ!1A}9yUm>|#fyaXuXB}iC+*Ig
zlS8H41X`6b8x9;wq@lN26LHx|4&qOeW7J{|a$4y;>euEvAuFj9vJ_tUL4+1PvJVaY
z@wxhgDUd=Zp;Tw1)ef{Xrx1gx8<6C933FJCkXof^G$}HQ#T|;q$y*%&o>-m4yHJXm
zCuj!)DMl$o1`0ouD5jNxNsS!$B~fnR`(pbkbxp93JP41VIW%hZIB5stSXpGXaSt+v
zF!^<?r&H$^(^mOYKmwM-kUC2#1=-LYS6SYK5mqzc`EiwIO8kpBizEIheut7zZM+ah
zcam#qDf%`xniSLgAokx@Xjh@9G;t?CLQHMCPE((R>;Q2Bv_4s}{ZpP;Zqu^SQccfb
zwd9Vi)KL~lS&XwNB>Jq?^6<$j1>_lfuh%@7j?K%3(BqS7n3AxI#nO|d=H=-a^|)ij
zQi=ak;49_qvyrwkzqdRUw`HNoMHz?H{2Tf~W4<A!xIs(JKmYtAX<e;U8cfGMdWNJ4
zoJ}@-iD2pQ8C9v_<jpGajAR-qZQ_Q;rq_qO|6$Yzh^UoEUm#K+ww9OqQ?w3WRr2XG
zp^{j^!DNbhQtl1|Qj4T@EGhNzF{Lf%i9N8;hZNK@H#LC78=P2=2U$={0174xXYmy@
zOf*kml<AUu?3H^=3y_F+dTHc*05Syd;g>4E4I^h#Ei-v4r*^<RBuktx1sbB?(f5si
zB&<)N5Z{N1QQn6@KdMPcHfu`4#RrKNz1cvvdP64+GXxT6+1wW4B=E-3pc*4or=Iof
zd%5Sb@c~&beybl_j3E+ma{b=mS!fyV7jGqXeW&m7Tlq^vfAfUMgd2hM_7qkm#ebpY
zT>M#%LE_e`N94~kvOoA#k!U7AZO#jYNOlhnVG54IRewJ>#3!=rQ--KAV$pXho*<mK
zJ#XN-eKk(AY_i*#TLFK^cY>2qsjq8UPbN)Q^j%PI;C%E$b9axe{C!!jaoId*fg4SO
zvHr6xpWjwu)ynkW#%26!jgfDKJIPuAbfg-(m+nwhm3e-(W`pooEHb;|uc_z4<JEWV
zux$N%Y>vmp#DEpD873tIkOuyXd;)CUcaz;&0$2n<A5Mb5ede&UnlXHwzvRE5MFkJg
ze?c=Vki7(u1QLsYd8yYjjL`GXqZE3R3$F)9qzaN>jqK>QuA$M@4_wPS+IpR)dfArG
z)^CdQ725GlPEEQy%s2E!T{NCal_)*zbS;-zC0Zpz{)k^Q>#_S)W3D_&jciz&k{b`7
zd22K!N!**IuxE49JXMWNd(IMEGJHeym&rFOejflPz6v3~37Pi*!5HrWPwxB1Pa(fY
zD6t?3u+n_K=LAE_FFDhdD`X)OqD;9kf8_=(QEo21JUDu>b8z~$VsqE6yvrz@fz3b<
z3<HGe0%vRfpO_oAJwC@E1EbsD=+s`=@kIKR=wZ53_S(!&pGdrAGm|tp?M3K?UCe6;
z+$aIan4i_6#m|gh=lE%*u8Gr-5~HXA`;gkDw1Q!{@5(zn^!f1v5PyypBIN{wr+}zn
zkcwvYl{*!wZ`h}zl6-M1W#tF;>67{TC7r{OvmE=(xQ;^fkVEQ>0y!KB5^#giR3KJ$
za6`L$+Bw<Z?XYJI!x29S^>Gb#k!I_?_VG!3cc;_dqaMa88-3$O)c*k^%PvKvI!Pas
z`O&fMD~a8zNseDj{uJ^MFBmCqmNQy>=cVTCUB)2rL~P`oQuZ^#k)DUJi(|}HOe<JN
zhV6<tI2fewo=wm309|<J7s4H50_lt(t2PD}p8aEqyBD#0N1G)?_zlRZD6<$?H@=qs
zXR5((PJk36(d2mN<g~3C9K%sVl9GjlnQ?b@yF)+ndTye@E=Igabg0cPzMxq^)K23S
zx3uB5d-VDkJ!X<%M-yamY>>IN0-k7Y1OMi<EoE$O`vza?EL>`q07?yWA<CtSTgufc
z8Ll)yCtP&a-!?Y*EuUrS#j7}B(*-i-dS$-Zsv;F;tCRyAdzLC~3b$9Pt3)@$nwFJE
zB^dPnpht#2NND2e&Bk|0&aI^g8ZtuMA4ng?(h+6TZ$jecAiXRtQ=HU+k9?jExNYHQ
zk#mOG)uW4+*ucMg4Zz6jHT=N<7%%xDaK7$1YCzktfed0xjJ+X#!GB<AApFsWH;@9b
z;I3YJqpg*dR(L($zP0$!Z$DpM{)aCZ|0`Cv*0b@y-|BySi~s#!75^It)UG|+TK{=X
z#{aH0);0wY+?B1?+WKe4|Nifbs?Co^?hO&OWXz@!gk5=j-%o3)^z3Qri_(8tV&?Y8
zm_h&79<6L9>A%=oUw!nA{(p%ddkv+ZfmP3?v+&)^fT{Ki*8y?{w3W(?n=M|s!*fsk
z-~SgiYXSXx_OJi@{{`bP1k(590>3qz&!E-N;<bZ9wfJ`j=qNxK{Y!UmmUci?q)CLp
zB7+=p>GqqY(uqri!8@Bq>JdZt3k)pc+D-V0%x;7lz_89Wn1HHCqjrh1Ps>-YP9Y}~
zHyC*lI$2Hv{}OQQb4(JI*zqxRU;2skJ!y}IP9vZStRs0Sl2}n~9f?j4Bb`Rm5aW!g
zViLl1&M>e$ex}AGAt^~pmhFKq0LC1YlcyUPp|kkV@kVaY%s~VOG!{c40<-K-d#()^
ziG#%GMz~1LuY}b1ds9pR?x_7*hOO|4@{fQ|01`Y5<7JoivRq+K1Gc^MYX4N69{th*
zL9{L4_v4eJU-$Rgd*a0(qVuXv#T`!eU%u*yS4RhX?UPfnbGQee9(GRlU%crY!3X7?
zQ|MVP;TJoHe~9+)$0zO6Qvvet{_Ep|eE<f~Pj(JF`|Z;@rcye1vj;+NT>t>8FmSN{
zdcOnBI!ARJw3O{8j(!oZ+b6rP;Ln{G`v?1-KM0Xu_B)3-7FMv?5yv|xAS1sy*f|l$
zZ%&SnPTK;eRodG>-96aZf8E||Vu_o>Bhmh~eb^DFuXYX&QnNhz?XZ1<s3)fQq769i
zyf|o6sT`anhfUyY;@@^*;Q+mZx;Q;<@9yI-?cdulmz|S8>JsK@`#;`5BlxnkxAS`E
zB}}b4V?|&~cHf+|Un9z}45x2ioObp*Z#r%9^5|#}*SUlV1>iwCeJl=+PHC~;VEMDX
zoz4yo3?N{o;A{B(#hcT8TC@GbPW$BK&2eY{=&%Oc`x~svNojWny6(~99v#wDVS$cL
z{y?C(2DJ8d@!P95e13xKNh`I3OTgMTqge^Yg9Ypua}<Z|mk0YV+lRYt#O4U0{I-AE
zuEAFApJIc39`?5#81oHH8Mg?qD$%dTfvwX<iv3^2&fc&4h_-ADTYtJQj|nZ=?kmB|
z-7MYC`!5rdeew5yeQRSi^ZsvqlmEV${4W|@G7*2>mz;M{+Rpna$u^uyB;5}v@E`sZ
zRk&Er!;G6mrIthfkVDZ&tFAwxat|Y?cY$&vWglz`5rZ$q-OzD9as@v}^ggI=awLB|
zyhclMAH6S~0X!F67cg*3183w7J%^ulMg<=wiqOVDGcw`#U0IGojY(xG3_MG6Kzw2-
zoEu;E=*q{}{lf3lOYX%h!(vy1!KoUL@Z5nkj31x-4H9@uzqx=G1vF#sMfU^X3KKvD
zcq;7FUN92C0Yb06Uf_rRAW{{DN|s$4s0Gn6)+m{8HrKFDWgy1xm5aJ}OcsQN?5@T`
z-|6E@m9SbE)ohgIij;U3h-z~bdNs~^fjDBVG1vr*PeY3;Z1wQEq@_8)^a!8xD-Y{n
zq9X;>7)ode>haJxWb<!tf-5VBu9u8rS1Mkc1x~pjv~375!ThPU>k%HMvRwW$95+0z
z#O$C@Pjw_&mvIJ+DC`#{FH|MdJUpMfAmP6+mC4dx=0uY{{795frsHO_S!R|84H0D&
zC*2P&d68t{H%o6qY}BXkWhutE<eiL0P#(m%3^*}PCV+c69mDEO@LWap62ep)C8wu7
zQ%a>bWA6hU3OL59ZWw}~OW;z)&c4p45JyVNdZT=Ft{k|n0|#^Rl+-3c3s=_rgmM2K
zdS`KOb8&%n^UapK2m7Vdo#XwOjcYXc>jo@l3_~u5cj*GO9lF-YXzFtcGX~b0<|L1q
zyjS{2((Ov0N$qCf_URnL^k9+HrBqku7xvf=Fbv&S<+(rtAO<<+h+#n{?B0#d;BZr&
zE?M>z+1sH***zsXFkd*kLu8==5j1PTqyjH|j~k3ty8x>?i7FBwn7P6XjxfUoywBoW
zikDgHfK(qpIH$b}ol8omKyJe7OB9_-yqX3Gb5TVZH7iE@GR}{Vut)wSj=;jQX8~MF
zI1W`s8juXvaQY?zNzgI*Kp>@XhF8utdcVCF=kC}I;9-z0`N01*g=J$YiGy_-ve|Q#
zGeV{6g0n9s(=)h(R1X%XOL7PhZ$IJ^Xfpd1?KN$K)Q*KFdNgRGM42`4QiUOm59q#f
zCX;KtdbCEE+XL1ib-2ViI`6|!{!ksL#Os0eZr?vBl}OtsIW4iawz9sliJHEx#>&r)
zwKcJ_-dbO6t#AFOV3ArZeL4M)T#{x#>VHxGZ)@XGD*wNDw6VJJjsN>1`u_)w28-XU
zhmOxc{Zgzp*MGv(x!G7<ZLGrSTx+eZw^kmh!`c2Y5lhmGL=}D29HCO<_hUcQy7swR
zZLUa1o&890aAz(jztJy(bj%v6%k7~?6<scaR_wYW%8lh^UF~~$d9Sm_;~&fMVW{Qh
z_TlpK@2?NavY%b+wVA9Op70_vXE|5tZ)@%ElGNIKM&)k?F@NFjl4&3)totqZ<Fm_t
zGn~(;`dyNdD>o_nE%!+k>W+^IsWVTT35_Q5GR?97G;TFRv5C+dji;q24^ZI&lKA)H
z@XhNN?GsVnMa@K+zB*vVhT6<3x#xycV8w##x_KSs6ra^GERSCGAgsglgKJV}b`VB?
zRzs*eoz4N3Kb264zl5JEpT>`@yZcCin>A6Uf6JD*6?H@j-^{n)owWbs&Hjnu@e}{Z
zkpnw~@1%wc)+k;A^6#pCcT7!diLc~(<b10Rm;GB~4Rcx;3o5GdAGIHIT8S$1c^?CR
z=zc_`VIAR+rJ9p}s(n1{nDZ4u%K1+3v8c*zPYo$Q6;-+Dbu9X>&P^S-7WfNqO<2ET
zC!6qDU1~_fhj7*=@V91lr6=FBI?@&7ke(&6Q5&1H=op)rvzJl+cZ6NecM9j+ZJvba
z(l&XR`P}Rg-wpgi-;2rn^N%1#e1yAOGtTw@5%wQgY5KQ%;e;REzdjD5k8l>wqmSoq
zP2~QlQ=bdA_`2N)ByS@+c3->U$Fa}oRmOfLdA3s9j=3fhpQMgj>RZu%ecbuOT-|g7
zy4*akBC?VDqohp<LQQ)C2(rv}3Wvn3)Mdy{M}I>nrb<U8@XtR|{LM$@f%<U(Y(32R
zqcibp3(WIIi$hXxKTNHN`KG9wD=?4ONAfI7?jn4g{LZ)?@D-sI{}dxgL@oZo6s2^d
z!l3sN1=^2&zxNRnN_}K<T;q&YDJbX&Cj~6TAU(I#<d6_fhEC6Yn7G;W)$QOTJxXIR
zW9K96vp*Q<dtMnknO+<tkXkwW#T9cbz+63HAtKT>EIj6@zX=cQO|Z3|kokB7rGRn5
zS%aqDINI>+4OL(81%<6_011L^CQSfSqmPm)X`rky|NR^Q;aKo?0(YOKGo}9#`hO|^
z<FA{|JMik9<^Qpgk^i^QB=k)<|I+?{N`@y}%E%>kug}`_O%(?jfMAFQem5Zb4t4Ax
z`$|rZyrWRM?fY&xu0+)1!s~<JE<z8Tth}faD)BbFm`1236zZ`hPbhkSNrc~&p^k(d
z`7B7`l$6#W{839B4`7b`FdAMjqlN%jxohG{y&g-=*k|m5q|F~nVDQ>cU=|)Q&(s1%
zOU}<hA!KOOA=RNbnxaAwQ64o#`@D(xlYWmIRl}Nu*!QV(ODv79e{}+t?Rk^K!D#Gb
z9`w3e8C?_p=#ECMm8;xCQkuVhb4mgSnZ5>YfbkKeVy0ZEq;{0b=n&X}2i#Nkf9~{p
zF02fzP1J{++DmYpk_<BzTrORjtmq?-C5<o(s(XowOZ@agrd7>?xpV^7i@0&TqLHXr
zIh#C}uInT318f7x=kctRnL~AN;x4NK@?NA=tP)WA2eta>j2L+i@I|cbJ$!R;AO~J9
z$)HGBdVS2q583VD_23vH-p<&iUv^)L4@@$5hAM;*fB%-jy{l#8xHE0i={+ogUk^A~
z{k?mwbDdtITjUK#e2cx`C9<v9<H2(K>ih`b2<ZQ;_x~=Q|Kj(5b!B~XV<YqauWo*O
z|Nr~=|Fi9%UKC|_?NWFce|T4c0B%6<)~o3`JW%3EC_l)J2)NbI0i!u;jdNATUsITY
zy5d-4Z0pgAj4}ABv9cysH(IM(t(C3Mi7~)PPJGen2NNM1b_)LHMCvnFnyWe{;k)NQ
zk}Eug7m|brjAuw+C;a!#L}$P?5y5~r)6(YnWdE=un}{`go6gDp%a`pFZna@=v$x+?
zP=xr&-bUpd!iK9`aqTi)(7->#^kNb3O5X*x3eS2!Z+`9HciZH@2msgD7~Xf!8|lXX
z*<OPNRmIXMzMzsSE0d01&L}2z{h4GGeO;8-8h!V&48NSa<yuV@B9PIMSk3h4lrmJU
zbB3zl_78P%h{E*fv<n~a9sPD1R~1Wr|K@Q2cV1&NH+EvGN2lDNB7K`GwNwO&bvPTi
z#CR5blEb0P42*>VDrX=7pfm)uY&s(CCned`;m;f$DixZtq8Syuct>k3^9h&-`0<S1
zQfZ3-wv*wqww|yhQ}h|?`ecgiqKdGR;4IU9l<d{T6BJ538Q0uCiD3LLT+`lr?r2u4
zm{nCy-H#WPV3D4Tfp+tb-w`*&3LQ#C8%+Bid4|)ABV3Zmq)Svh`>-irlYPTq$uSye
z!A&yz-WUe;qSz&n{D>R`VRVwBAiIu<E&|Y!5?l!UFa64OMkpW%i5T~;i?eB@oPNsP
zvfz;48hSGgL%$xQ6!*ao5DYsg`ZRKES2r30RY!TV@f5#+)o-#8?^>`|jw*5%Dr;Yy
zvk4G7B=hS9+KeBfU6~>!U}EH_g`PpK_RbHH67()`&O7i3T(~uqw6A3;V0c0TtqtJn
zE$IKG<^3u^<^t2k=8+MZ(W`;%=Z+{R<{2$0MhrMX-|aWGftuubsguBwWuAaImkTTT
zaBY+O$*xs=mf@jBS{Gi2^cz*4^Kr$HtpLFv-mX9&s@KOyC!L+c&I4c%bRthaisU;N
z&&0$}CiRpjgYRdEzFS%VhFye@#r6;Ag2|Mkci|2DkH2h?q_{IyXDjJfaktEl<S<%-
zgqoW%F|KQ72V_n*&ED)Xx0~W`xR~Nfb1glvb>xvVo;t&2cf8#51DKus?mOcz-fvSY
zR?=aUn20cz&`Swj8FC;OE)ms8J6=*`?wH)K@v_J?Nul(_(H);lrH(lB{h|I)DwQyM
z!KD+)m>sEL!46AZhN`1H)A;Nu?@|&BsIC*|QX{8EycfBM0OAYbk$#7@uA>+yWho^$
zq!eykO*6(_LGVJ6<tp!FB5{J$dFG<3hE<WIp1~2XrDs$}-IB2x%D3pDu&}qeGh#*H
zjVGnh<XUyvBaDxP)bldY#YxEBVp@88m@!5?+P0{~ci)29&RFJ{0S-jhU0_}(7a{7f
z2tE?7<e?I5mLvg`Ey*AU26K=>c{l#9iFA^ytA>d~?u}LJr6S&vcEMmWVulQkl%qfx
z4J3G$QZfs~I%TC&Hn%}kmA6Apat!Iipnxb7x_LC}%Ey2@#QWJyZ-SvIH<Z<vzSmD|
zi&h{LzqOP+FPz*psX1PX8O3d!U*r${D>tZ8jX3<ON(`Ktnv?P>F;~X~HLcK<*<;eY
zpk$ruyg=LW$f=BCiE+#sJjhG^ERjjh*6eBnFZ1Ra3-H4axB^(Wp*NZsUx0*3p%_`s
zwQ+v7fp?C(l(ThIn9bGdagGr%AXqDcB{K)vkGiE4Q&ID`D0Tfn<3F}0pH{|#lx%hS
z>P-hE*Fz8wU+$lF+9&P3%DY-#>S<jXIU&YTs@F2Z!_#1(7?v$HrD!tq;9)I%l1*=I
zslZWOQO>*_cqLE~G1fOje_NX?kF}(R1~H7MZ+R>A(W)lcc=9#y2hC;^MYKIE3NrRt
z9#8?;S9JviMLV>ZssJRUitzs{5LE=}RU+@q8+y@o9lck>>6z4qrpaTdT%ct@1POdz
zh8;R}S>_-&S!qM%`-l#a(jU?}L%B}MVJHGwhRYD(8<N2;%bn?x$}_3gpvvUSxZp|Z
zC39F7QOw%od5=NX*jFq4kFYC$Gb`V(S^1ki`L^xJIX756cc=2T`vn$0dx_tuJEr%A
zP7HU&kUOP*l6MfPb>iYG#pC>^p3mJ94#<a956#L!7(q)31bvyut|_&i9Uc`!A$af`
zrNkfxb|N|7$QY=UL#xwA)VhR(cwLUCk4^fx!Y06>k;SW}{*c!VBPq#Vs3LMF@G_0@
z&X}FaA!zI;-F>jV!im&+FQ(_>yRD6l&C;!LOP|jr-Hbajvg^;#y1$KYtGO4o8TUbz
zc&KIgnvM%p?Mf<s9IlAWTSE`7Yf3*U@k^gR^q{3EC0F*xBL{1gX^(OURUzxUyj|QC
zhZ`pZvAQAvxK1g7E#uvezGn!l$2tkTxcn&Sifp-kQIDD`XR*C4A!Q^*ONCWA;FuI;
z=eUBHIavYS#iE8W#H=81<(^21rtD2PF|Bep7s}3G=~5oJu62o_UDA}7rR%81ruw2*
zn1VO&l>lfsQk90y1CcuUI+3=K5xb~6A)B*hg)fQjm)eyXHz!j)CVPcWU7)s@e?e+p
zIOI6ufNN7%5{E6a605J(3cH*I!5d%t@39{U5R^(lD*q`gTN6+=X~@I`5`alw(<tKy
z9A>EkD9&79Ts>qQ@kvv!igL?PYBFOOir*gV%V`}!!N?zo=z5OgmPrH>h$T~5Du0f+
zKw8EqS{G>}em&JQt7=X3+1qay^iaA?A%nov7WbT4NU|u^uPN}qp;mZF>QAlcMMhvO
z6Gd4b!yl*D1=b{C>aC}9Dnn;88FMX-@hqg`0!cF5)F4Gl+n9nyHaHeFr6M_|PujeQ
z)=d3<3V=b)Vp^_ae2GtzQKhP7Jys#=YM*jw$+|J+)T|X|VR6|y2|^MrH2;+XLpII6
z`$4Rz4N+G>B`K5r;+Ct1T3oG23hh{=W4V27Kwfl%=+LLmCmw2biqaF3^0bOhk*mvL
z)HnuxtrGQ^FO3cqVX}K;jR0HAGB-KzTbf_qm-5QweGTi7_mw)=dEe_Ro}OmXYPYGM
z;p97<c{P>{qf%XyhJvSAvazJPKusvW)U2hXmpc1KFF}tHvsOau6iKa;wr)Mn^iv4s
z_meFi7gwaq;4p{B%M5Jh^Lnwq{krHp4wPOlDhO=b@>XFpKCZ=W=+G87kw>?<5gcGk
z13WUVtZr1T{5I2x$JQ1`&BV-xrZlpJn5p}76Fh*kV$oKzMTWaf{2F8`Fp}tndKq13
zGgsL???iL;%*=gz=fKhPIjfdESxB89WQA)v{ovLXP<fXuv8~zlEW`sBcpe;5O7<E0
zPkz{QB}PLl=}FT!34A0-qQy<}!Klh)P}1#2v%Br2{gd<rQj^UOhRSh~wVr2gB5)E(
zaFm*jVN$6nW?lt(pJ`r?pYM1gSSlAgkw=Ys)BQ2(^e}@LYF1>XQU$@a%mD^+2Lqh&
z6dutb>qsdHtWR0D{J|j3Uiy$xia8ssq)R|SI+0vb>h;n7RteluU5t9lGmEmNkU=Hs
z&_PF(^Py`j9<mcAw`49W`i2maX~^=WXAxiWJg}C1cY+ymnei#77Ol)nP{>21BwX`s
zD)F}Ruws8gyHZnP6)0Jyi5ssC5Gnh)6rgJ}-n@ALB@ihnu@!oMyZ#^#&MY;Lae@l3
zEwl@%=(IlRd@xgonzuZ0TAMlB&S!<UU8VF*92-2eSFXMa_RTf%PwuBVOc$EnbcMQ<
z3x3ZX&b3a|IONK6hK`E$K7-hotLT=+UD9htdLE_ZiG@9ae&xtvrC&0;yJ8x|%w<V<
zgCrT$b@XSm+Tl{mpp5f)JkuTteHWe4`zbfAR9$K7W{90rvGg8DAXcQ~5oiNzmNLfP
zSY6f_m3p$5?YXBl${YVJ4*u?~Eb5K9`Y#H=zq7oX#^kg1>`%!ToY)!{O?MMP$#nR%
zhMB3Zpzf*X!xK@A_)RA~!}^_2it+Rw&oYb8cU>4-$R$~Oy(yX1LPh-J@~4XGn8xNj
z>XSoulID+iPt7|-G$+=%$+@O)A%iHUS?UxhPqG<8?_5`~f3wSH9wg(1GeDrU2xshp
zK4Zprwal4<EjE{rR4!wG+%QhCKy%IGbgwHUQp5K;Sr_K*3a&|W;LBQ_TCo`SBKtsS
zE6Q%-NrfyEgd?vqySfNgdX_IB#LJrJr&1&u<nPL?D(;rMC!X;e(6ZD*?_@6pGS%Vq
zOqLYrOLr6YlPh!V$^L6hVBZ$6+ZHwZ1KQZ+p(s8QJ%2=Z+Q*8C=`Hr6(n4EeA2HWF
zP`DMc#~m(PntYb>Zw)PL>GM%jpzKKH8@%H&W=d?1xC$I#!lXi;ag|mq45jNSMWyO*
zq`r0I7)>J!Aq(=AFwO^TQppQtC2%kzRE1<9!Dp=)+svfA9><rE-~^kb`A_wJ)D3lM
zJSMkCX|z}?FZGwO3X%Ik`<BZOQSdPgpK_1_TSZUlx{z#6M{eNt%qOVok-ryk1aM>G
zK%!j3BBsHm&@!B2=qB<gOAl6hn`$%6C!cFIiGLQipIH0Gc7z+-QSi{rwwvhllZ%x)
zN1=*aZs;h7w6(<$_cK2?v%6&B<jg8*c**S@8)TBxvYB3TfoPM={#b_9#d?=;-epB=
z!}%EXEi=5eF)1QOU8Uo)$XNxSnR9m8|KMN%8AqPvj~a(>*-TV%N*W|}3%HSYC<;xg
zqD)$la09brMB&ID8GtFGjL=d6goBul<)A}i;ZpeCn_z)Yq?GU^)(r~JD3IF&t(n2I
z=HJCwzErd>UMLmn*AGZGU(B>4mqip1&e*!rYNahBGYu<Azd7Tb)0A9VRr1qunQjn8
z%|`PzOB!#ATI!=dyJ<Ewps2Mv9g+dHIAC@3e#7CrMrJ&3dtz-Ff2tQYYha3BJ3;Dw
zZfAH^q)a(_{@M0ey>}nJ%JfM^4VZm8*OTlRx`8w)@t<8?1Q?@)Y#nTq&@LqfE-q=a
zT!A=FEoNx+#8a_iHiPd0D|g(_?NPI-Pq5$H6)f~F$`8xp<HyY5!3~Cou8Q@}B5Ggb
z8H`OWDe6S%n;ZzzMJFGKTuueY#_6kjW(jehhw(o2Ir{9}yL87~8(xNGz>6Iw9m{#7
zoH!ML#W9(Q__wTPs&LD*2F-#w^NE|&ESsV=b6REP#9s1><j>4>ys|k=+6=WbXST4h
zH$BHiZN0hYWd2|!x0fHBlwPB}Yae&6<-pIjoMlL-e#wx+Jeo9)E}bD|*!Z=5a!QrV
zo`_A$aUX(=IdoaS16|-?0EY;y7g9=$#Qkn{ZFS>O@&<6I3S+YTi}wMB*~H&vjrLF$
zKecH%oLrRE1D07W2OmH83a76L(un_&+h32Lm05<FB(#_^Edn>|Na)PamZC!JDo+$Y
zrK|`6S4;%iEWy=*I6c6cN-C_FIdY6AA^W?Q0`yFJN_^H2Ey}>|7!`6em|Y1Y*(l9z
z8B@7^ZY#wc-If!KW4N$bxJAAF?1>}&aV$GO`ylgB86D5UBh5Tmv0D*`j7-A|i+9mX
zx1uGsH(Pvata(}<n_B2WHzxB7I`vTR7_-G4dKhoh^IhRnPXITT^naD(kKUbp&!6NL
z+?ngoY)tOn_h;Uz{x5g_v0tnt9m&$DSUdlzWF<}hB<(GKTQumi91B0&snBpdAk>Vd
zLDOMo<?!h7>MFsGyNQNaoe%6c-^Fjfi{Hps5&6oaNy-^2!zN|fab%^G(_bP94#k2_
zl<Pw3JGnjVnIL{sW-tX*g>bu0=nb!he+k{azO0Dei>7J0oa0I{Z<^-k1D9MEb;_Vf
zVBoiu5hf`jJHy^ZcBoM1n@g)-YsDs)nf<IjO*`z$X~gc$uLw?ignemV_oiY;nnj-1
z_dd-We~$0{XR+zG!m59|3Df@BYtL(DkGZgNGuGv^AIl;rx5-G^ojHrh7f>&tP~>pw
zgy|$+Xa`S5r59aL-6+1EnTuD-bJ)Bae(%dOT>ouP-~2}k%j@bS-P!YWbV@O76L;K4
zvnkr*;<C!vw<%8Ckvlr$9Dxz$KJ7VyN{Qji1T%gRaOy7Am15rp#CmY)#?Zt1%rIUi
zcS6b{`ypaORsxjmM4wLCMu}y~{YatGA69Ed)`ZmIO|AwGW{r{7gLkom+vk=R?J6e6
z^T>RzTx!U%i;y4_E7zh&*OOm%Iy(n^Wie?D-D4-~N>#<wxaXJ}m-8`p`@>2NJ^NPC
zKqKO>LucSJMW?{#)glioi_2QdlNE=KQzKiI{^4{W&1=p6a9DYqV_V>?&y?=@)p6s^
z@0D4=!nt7W?9Ybe%me7?bT%L^x>}hxMU^=jzf!o)azmcO3BkH!-AWUWR#SqYEynK>
z9~P;m^C-Y4&cv<KfU5~h)qdAU!+S*+a{`>9gYuWRX1zetk<962Yr><<pE4~Ovr*JO
zk)vGE`@#;{cmg8yg?*AwLwfZxN#_o{f#0U&IMTLhui`_m2)rh$+Yq`{YO`6poI!3j
zM#>tKg`SyZVRA>w_H;2*QxLjyud9KFO#jDk`};a2(FoiDzU%BAT)e#*PlZ&XIGG7d
z0!`k^Oy)r=MVL3YU`~EP9(i_#L6wyR8aJLAjjK87_$=x3X8SMSER9}~WAi7|Lf<Ce
z@z_a|z3VBfa5xR5V}2@;x7i<Ga2d%q^11z3AeCyC7CMjBOf=A;e-$T3&r}l&ODR5Z
zMlzn7*g4!2G0B>%xpKgs)z~~7aiGntr2ObOPd@fpjUmuyG(J&Ng)udKyYj9sd%azK
zXGxRC&jG$9G8I428(<NGzUfjFXXYm#E}4qFqkZ4F@cAS}0@3H(DF1N2YgWyD=()t>
ze!?h9Dj@f@W-~7;_x;~9p}94!IM&SM^iNpu$CBneVfC!l<!1@=_rfXA&AjC@je24B
za>{!=!}E*Uj11Q`5&N*^_#jai_5;pzN!8ZS&3pC{8mlH2hVPltCV{ExG?&)~^|x3p
z!%em^(|l)yzoJafX8k3j**qQuIwQzDUh+nA=1g2<p)Y%;Bg@6?qusK&xLe}I+0#9f
zD8=GRUXa#2FBQ;S9_*HR&>^dfF2K?mT2V@lJ<oHT!gJE=@G~g02I}Ct>1626>y~Yx
z==A%ZEFF$tFUKV_=5Z0u&xGC0_>@$p<M(5Hi)mFV^*Oyr3e&38=khTr_7R-JSJ6-d
zvMMOP<gt6{<8-5#T4a)!DKKV>k*!5cDYoOOru3<~Vheg;F$tL^tw{efkSBDX*#b)%
z{EeZf5|PG$a};qgY24=6fv)}}%|oX&enwwliL!ov=C^MvGX7|eDBYZX^LjDTIrzaw
z269$_-!1Dyl|F=ug4isL)_o<6^fk-5G%2sn0z6U*k<<k2*3T^Nxmje5aK!8?(sN)9
zMOSGIwQl+2M<KnZ3+=Z{GN~5Ghu??gc@;*wlYP3WC6ei|Wv{wg4byqOw)k4ehc7*;
zr2W=1R6Vg}Hy9XR;4I0dzy`}`kH5@TDd4hl9pY05HjWgp<v+*eT(KPyZ*rTNlJm`v
zL&Eazxz#XpB+#+;278f5Rx&;e$qQ&*-=w&i?jn!P+$1m$W6gaPAKbF73zaRGl@__e
zmnnHDX;g-y$-lx`{tD<-U9Bv+((hP<sU}&2y2%C99+SvaU4q{#3ni(4O))naX8xrc
znc-ekHVNa<QaN^;1sQy@d6(wN&7)DuCT=md@bS!f?aE_PFt-fvyR33_FECT)&S$gH
z_BuQ>RwAB6?rNx!XRnARfu&iyEqTvHmO+UCfc|ipgtO@GYc#Fdd(<tk%InP(`yA`;
z3JyyC1u%lJZEG>}?Dyt7`^hb5bcA*C#*LSEylBHY)Gc?j<7}dy3}0H-L@IBa<u0dM
z%e?bg#iX|2Zc7}kvrSjun0>_KfI#c4Q=(`ioN_V&GXi+V%yauKIBx^fqMeQfvRPB#
zLosE(xo3-3>It2(%H4^}ZqHbc46Fs$!9=@gAuQ3JMXT{57S{^NzlbG0y5Uz;RUjsX
zm_kdZ;@0u^r?6ap5UB)%I!O<C4q)(2QD*8vz(pF23S$nYF~UzVjLMCA7xv6(dQwz7
z1q*{9XM=_gtqpB1xcu=tNxbrP9Gp|4F9q)Xmxo6u?Jlx<os*s2c5b%!v|N?o$>f+h
zB4F|a=$$HXU&#o|Ji@F>A8<F)ltV9)`P~u)-B{K}nq!i8HqXn)&?ha$cRODTlIn%R
zfq3|k`<CZs^&<b2!)|M-EN<P@Hw8B^B}9FiJyiPcy{1yfig*NAmpoL}ef3*Z%xS2)
z42h)PI<GvCveAeNHqU<#Vth@fGfrG#DQm+z{rIbdYC>STsS4alujf|sb&jb_AK2%L
zV<BgE;*#||5NkT^h5Qy4&ZIqW4#{lEP@I@S|H-bT0DESgPJWH8WcQkA*~MhbNKH{`
zwJM@HSBKSibC-)V^jkKTyD&kQlB+9kzYklAA>KxH0WpW$-}gyC+SY?qn)%U=LR3_{
z?e9Zb)0=@IEui1t6`Y^Kb+5&G7@L4u2z4nXliRuTVh}0Xnfqicq>1B8Og^<0+KI}-
zaC5X;CS<87SRA%haTUYud+y>e*|JasmXBtoD1q#prxp$&(L($s|KL^@J*c;TNHJg<
z<*M?>vW(dd5fT&fx2F2>T`r89oNW84&N$XBlaIoI57$WiDl5l@E&L2oZ3$^RkDRl{
zmDi6hTI3obdW|zD^m+|{FbLg9e%K!OTVw<Ox3BmI&ufD`3zkpXJA1F&cQD54%F5Q(
zhWIyF=|`!5@n>yqV~c;24TacReY7V2?c2|n*?-Yse-`|8AM;%eF}=uk-cPCY8_EIW
zD;(5GvVuyo*E6hb!e8PS&q^iw-qYFHgm%%U$f%uIycH+z#1Fm553cKC;7{ROCn{O|
zTVw+F<iI=xIwkpo2pBjZN0hz3)boL<^~PA=#_dfba#R_3Lzl}iAx3d_StI{Fx?!P%
zcnMp1Jc^Jtmz5GKfs~x79u5EvrbCU67<y*`5EMDCA=aZGRS)>)u=ING#TrO=4j_p>
z0}k3N9Ab=tM84|0KIs0()a$+f1(Quw@o&mI5sHyB1`3Edcx(02@x^4%?@`e}EN+X1
zEE|3Kfg^=YlA`?ppzgis?!kCRtVOHh?_!7f^qs`;h%}6IEiPbV0=FNMFCW(J3;ZiY
zb~r4>o<P!{E5tfFmL06eiN(>M%;y|y!|T#H0F$NO#B>5HA+wVLZ68v3^3f#lFS*c<
z@~^-x96ICkDV4D)?H%pDdEGwj?2sEr>fr7r7GfZsKPbHK%+-gk$f>GXl1Gj~Bv&>8
zN20fXc-jGGpU#}F6kMV&@yI&C82|&kr2x_rdq)BU7;*CEkdgaszw_$oO-BJjA!WY<
zS5_vIR0q}N3J4_$Q82z(K<rx8eO1SpY9O4r4wpRgq=OJ0MZimrQv%Mz4`iB3z_0WQ
z&g?a=Htb0q^95h{6L||&#yLlv2QHQ~z!;7JCqu<L@$j1a6Uq^N<p=K{luAqc{g&YO
z2FU-)`o^X}x4Op4&yBS;v9jJ;Uu~^#{ik4mJhAkRPJe;-|MWVH+z}r5FZ%v(Y(0AP
zDE0n7THjpx_Wpl~pC`|drIn7rzW|L|-t#ct3%z22gm{zbP%4wD1rl57n;MD@qSNy_
z_VV${_t?#M*tK}z{!A>u4#5fU*8g_**VC3Df)!s7vG!<d{iiJ?T0b{d)*5RYVr{*(
zxz^eQqSc=crhkj2c|3LH@+@noXT!S|HzVU*E1iMGN^_M&3$=5^Fvw)Y@NwY&HHB?7
zVu55RQ1Xji*hL?<{3RtRkWEU4S31wQ3;&;ViD{}N%1hJe59PXG)e+3|+zWiv^1-o*
zC@mIj;{=Wn&4C-n4*Jxat6}R8>EY;m1FGX433M)VWd5vE&i;>&h=3;+nAC^j&Di@u
z=kPag3~wQ{>PU-PD06Ay`MZEacILWcigFw?`{qShp9u4}V)!C(9}mUL!#9X89Q?in
z6r)9toHBi4lwwWQ@=&%&91dFnAgPEj?H8&p5MH6ALqjcAfL2wufe=<3_NesG0C9FL
zHBGE_tvs(lvvXji2ay~~!$CDrU7St1v=Bh?I72#IZJ3@rMs{IB++EM5ykxL3PM<5o
zk5j?Nh&e!z?)@O&CWC#ewNJGs?PQX>^2bK1T%AQ>;1O%og60KW7J+Nal)<!v*nvC-
zpYv&JwSrN#(g=vJT7~lxtg_+bp?0eh<sKauoHu9ZmyPLs1*_%9(D)M#wLfMzT{D5P
z%3(~58=oiI!w@blrsjPp>v3Pm+`A!0Yp6O)tx|k32vxo_fG|445*iph1X!SJ54O#a
zPb>9YFx+9j@P%8Yo`t~+3sS^+!VOG{i0!$cyN*1N>-JCD{GnrdDa4s>{16kh#|78@
z0o<`fnRQFaZ0&4;b-OQ937QSK1sy}!%}A$dV59F4b#8r`nnX~GM&z7_1z<4Kb_~S^
z23sVdD36guy(db<s<WcV!l;3psPz#qblSL+C|{H=Qv_It?oMzXR%yBFsma$<vzSro
znr$Qqh@5+Q2XYgG(zn}4K+n4&2;Wh)vixWG<8p;-u3w^0U|k%av|n~lj}P`c-NU19
z`}J|>kD?%b`G9u$0VSts_;<}dy_C)|K8r`wXflmd<vDH0PCXJ$@kjD)h+hW1E1Xcq
zcq7Ws%lt+lK}$anEuo3&=snP)YO|>(n-lpU-?>EY>A+Ie*Y0&>M)=dy`8kKlOwq{Y
zVJzo_UDb6Nb$b~ZIV+VmHa~TAjvuXz`_J_x%m(UbkH9X<&9Y))i0%x0BehvpmGEUz
z9iuLZJoOc?p4v6FtzBr)L7OUcs#fTctc#VJ*nS#kmftbG;V`Df`28((3E!c8Gu<lP
zQvFcY>ZkO+roOFZOCi4{p7N&fm$CPnt<7q(&3X<diQjFM`PhN;Oh1Q4z323z8(p#V
z1hRcgBj*F^Rq!+TwF&%(tJ6;neg8cM4d!-s-bbo4T#O)M@1EHJ=weZ{1`>!!-2yH+
z(D%7S&d5`grdj+BB#xS#_lyfGX3&50H1g`!^-|U2d2frAx}HQ%PW&ZCPfH_sxWfu=
zyOd7qqQVl3@mb0`UquECAUsE22k9T<RI8C63=eCu&p(i;+05~p<1>l`?P@L*$H8Tk
zN2^?$!)`4nO67xo|NVE-OF}bB^Q6+*a=*8{Fz?9VC{Oe@z;=cplwGJ9Yv_G{Tp<rN
zoN1+5LGoT{!oSZ9rwdC=wh?&GLJ_{hRbq5`xIV2f{3j>jJ+*wWO=IF?9{=66r}RK9
zcv9GO4%hSE&<|aWMciTRL?OJ=)g?=o2z?}<#8>*`$M|=c<VqU5IJ%n_N``P-=P=>j
zklWG}d;2Ht-Oka;AKlaT@y^K({ECjW(EV{<DngnN!XX|A`66Vn<wv=p4bf=Ak!aS3
zf;!u7=8voTUgqR4NL|bB$PLcjF3`&<hy<5zReoP56l#kmI#5Sisv>y%5!ppD8<cV`
z*d4vh#6c6nxiSPpTw<#fJ%nT%LCCSC3a@bv!Oo+~7~pN);93rS9!-al2O@WT5@`I}
zroEvXp@Xu74vnda={ptQA-Mn{FHerU6kP)TK5+@?BkRqZaRIO+GD^10r85pVK(4D+
zwK+YTSftTKH+b~)X)nkzYP%L$syJW5kNIu|6;v82371rMfjjaq^_fk3=!QZauGE=k
zbLcQcBcEJERe5wSp<4^PT5u<1M%lZ<GK?^z<I%u{Nxdj#C+8fS&EgdJF9stL{jxU(
zM8MEIZAnQO??5o9@H1Q<lyybJ3!Elu@%Ditymv8kXsb~x5^->#JO^M4bHeRyLQZ@I
zu?e!>cnRV6T22h9tXESB?C*8ok8ep%{as54HejA<Y{dDRK(lh4zN&iJvjmPNx0(*$
zjVGVFTe*}-U*qS~@eJZ)Ol;12qsh%=ZY9ay&BULZ5&Fpf<YFI;Vn*#&a4#f&sYA9}
zyuPx=s`PY?iGEEygJXw?S40bQ58wt=9_P$ZLb=rq$|s}nZypUL4{XIJcrnQ|X>4Pn
zw0C5F=n*p_IKh+IcQ%bo1scU8SFb+;fEsFu7<`s;D#5aIo3wKDeh+u>hU9WGYE>*L
z-ENZ-meN@xRvtZiL?l|(MU5jWKZjsW>;#iHLniYI?IcqtK{VlwtnfIaC2qVbPl@Ht
zgW)xK?DryPh!syU7ig7~4pI@hQnMya_s5rR5K)zAtZ~}&M$XV4bsYsDE--$poP|OD
z{?E!MLU*N-pE!*g!qfr3J{J9vP!^OM41@t&ZyXhl_9JZcJgL*wsgV8VkU(d>X2~6|
z)#f6WIn*3KSIK%al6p#FuRcIhsB_y9M38bHC?d;`fsv!pHW&))7Wp-AZ<%|Zj>8LY
z5LGp{Y!u5AE?Hdz|3x}h&1so>F3psHWA}<d@aU<rbKe4GakvV+$fcNhjRHfg<#wI@
zl+4Kdmop=c7Ax*09@3-wGqL$}D{uN-r<AmC&*wXRLd|uKiQe?}UgY`S^~Y$k9Xryl
zoEBH!u-RJvwOT_xPGCH0&>1uRqKUg1eE`zrh7tavpS6c#tv0i@c#0-<XPD}_K2J|;
zR|VnFkK7jS9a%ETmWtj11JpX!#WWa(XqVLP7$m_}5jMHf)@~-d*;x<Q;bgdi;$uIb
z^Y{Um#Ljr|xk*M!N*#oSj%H1fmWqKi&wRsUIG^D$#-`^_$5B^8r9b4z3H1q3I}cfw
z#{&L+V)nvMe*DqOl;GEImpo=8o>q#geO9i{Dz@T}WXhCkUj^^S)ps-NfTY-&BqlRZ
zan63cBV4Q*UGOxpjzwWPhafAF>1U~u!2nok8k-!<{&)qe#`KD)AzCL5qEld(FaVY<
z&#Iz`0I$euVdZf?-AJ+bV9A^=PZYHaH?+Gf<;@IT_PuewIwFx&*k_XzS~LKseqF4s
zZ2VNqd)t6E1TK5g=nd=VzFGrfFye-kHqWYRFIJP|7BsiH^Zc(LVL(O_oLFwy-+WV2
zfOLb$H<OW-_8mPC{lE#XrS_0rxU}TViD@-~m#%sv|56LH^okKMsg1`31MHz6_5u&(
zO?V8w@Pga|Iab7yb0PVt3wqWOH%Vn;cMANlT4q;_a{Mj}eAB51GNP6qjlQsSS}z>N
zY`Ia4P$Lq{z=kZN{yRO60wOcGG@g<MLcZ4&AEW&Ip~ZxK2&G#I0*{M1B&_jODJ+NB
zwhZHzYg#wl=+iGS(vGpixH4)awPl`kP-Lep&q%M(h!hOO79`hmH)0SvfkX_tid{bv
zi<ugsDfS0h<jH|iW{e2M2*@-kWUsXbfSg^%mzc&i6rI<{$f8I`RG~Aj8UUdQ2uT=b
zL4K<W35+^I3=m%EGBgYtBCbjfn+4Wu{dvV>{Ye`Dmx4An0X2^iOYvcyLN-jP&e??s
zYhR$jQYw<v9vO=Zn4}zh3{zA@hre2z#lsaVkLWxr=E~+L#!!*$gLv1Cyir!|Jcphs
zYW2UEp6SLKq<$sO$kk;jY60z0lnaaDETHbtshbslBPBvkC-6)df1}<OhNxtCYfijL
zgIltAD5TOyD?j0AOb}7~sJwC~mAcTQ<m_dNZ8Il|mu{QL4A4M@Ze1-vPEjJgIhg^K
z1%XWDsJ%Ml!aNvHIPrlPp!X|f%7GW2a|sC~cBMS+0NEs09<8ht6_T;BP;aPCO{^MD
zQfX=6mh&yolmD+cwt%^60JrFhEicajSSxLkt_SJtgfYFSS&KS>9OuCR!KqBv{|jbB
zln052#_YFUW<NTk$uERLEwwsHvXp<ebmkYeC|MrqghtA+NQx|vu7O&1;L9|Z<S9PK
z)tRN?jc0BsuBLz(X3GBE!1p(~9#xySrW9richXj>Pa1`aJ0_Put$uVlZzTHXr#8y)
z;g`+QJ2`i_j6FY4HXWAvxXN7}8utw@g9<JUWlR<K2fhSd1Myjh?}?8cUwVN*X1n;M
z%4g6_>Uhxg9$4Ro85_d8#mb*@yUYPI_=g74^@F|}kS_-Ygz94U4vjw@qn|#}4(PPh
zZ6E&1>riJ-64~!-3?l9Oq>z%<25dLuuqAU3buR2Q$+xUeI@gfNh9nPSezh#35Uj_O
zR0&ajTLHcfD}p=|=HKwB0W%7FP^G_%h%dq{l0S3DZKnrrr$=tz(a`Aae0*~B%l<(-
zfkEPP0}=D{yTAuoVJ}FaqCPUPkRN>x0&z}6g2<Qt#P^YNYKjW+;`!NP?1u-0g7o>J
zkCI0SKgwfIl2~ViZ0+$`K@p)+D{|~9Q|5%S_U@^M7yeb2_jgo-T5&0YN#LL3-<>!l
z204n*bpl{^2eFuxh&6y0Qe|TL6(dhL4FIS09K=9nTpNYl7v_cC$pk4Flab<zO5$fi
z%f5CTe^pSE#zt*uNvjI&x-q*P2WMdWT+HPNT;9&{en#cYlhFXlWKyXh2OocAKPQ7s
z&Mbr7fKlURp-7;_$QWkIJd_^fLH>y3n%RXnlir^s52m`L-cq%#+af#EjO=`X`YV5o
z&I!)IO`7HnA3IBhMKm@kSKMraF7im-T$-Ues#|)z(|J{?<@laRN8KE?T^bVnDP6*-
znlzTzB&EQ=rXf6_(R6~fx5xhU{DKpf7*(t1RQDw}2y3%_;OtB|i`a%+=Z5(_bN+j|
z1gqEOT8CspF_)?Rd#6$>%0xy#&vKE<z?u!Lr94)ffLEnnX`VR|{?i-v=^uZT-aA-*
z3ZtW7PmZaQGz>woZm48&dH^}ixb2lD75dBxDzGr5=CVQeN@1h`x^{%!IKNG`rpRI(
zEJ<2X)=SBvUK^>S0OYuv0E2?NqF>59TS>I2u<KRwGZf|F6Xbs@vl42iPKVr_N`@-f
za7zt4L!*)y3Dqk2N4|$e@?sSESt$DwDk5?{_!U`e^0;>L@Z2)b8D46drhlfh@4%Y6
zJjE4Y=(c7GiuB^?C^YPt@YYCuRi?#jpij8ym*;3Sn9+#b+#X^~@!Spd?-$YN;f!7*
z=R@C}0I^=pD$kEO6dcps;n{Kf+E_q+ji1I-Onnfr$S0X0hvW6LA!c%M%+7M}{PFPG
z<_RcQDzAs>v0%*T$@nR^g--;31e~7qv5iwo^I|=LTN1eebb$_X2J$0f6)xbFx`xx+
z6t9)<H+N({PlhMwD5#lhYjXu=j*!5&J;lQ*elihbok-Qp@f0u#&dQXScapWUGj4o%
zZO#H;(E6Y9fYQu-!jFj&NNG@Qbjw^HdxYzf+(vuWT|O5HH#zjgR&EmbJ9+kJ)a{62
zm$W>KxGu!K?5+zToCYG=${cU6U;?jCg)T*<mFrFw$6&<n0(Bkbf_l9{rP$fa^j`RJ
zwMadm_KsJ}H^Wb?(DZA<lUpzgTxtGKaq$-_TPqhG?|japFUhjCbU*%@`e^<(m%j2{
zCC3>Mm>x_nHge9rp6FdTn9Kyz&pe}ml855Lxs<Fj<$ZC(o-=X#^*mT1hR0r^Mhak!
z&t-5ucZxF}0iS)md(xIkX>{Oy&ZIDVD*EQZU-}UJ`HX_1fFXp*{rOP-@i3zw&fG-K
z7z>;$!2^D>^7vLaNj(918>KFNp(9P6GffVOxyTK`V*3e=S;uH#BqZtBOnqn2r&u2N
z4E;^`ZgI30b9XwVLrOQ6ND9M1HVb?L#4N5i)hVN({$$gNt8-vcfQNr2Z;*uvwcR8I
z63^9l)&J)s94!EaC#$Kl^j1Dr>hTe*H7nJnxY>896DVDOtlq{v=QQo-=)z3sO8NmX
z`r2OrMGug%k$i|$kWY}olB#s#)X&_Z)MWunlZc|Yw)6G`!Bj`E{}(<pb~c_iV&p`m
z?%|cI$Dj&bR^!M$i(A<&VLszclf&vGbj9a?GV}kT-g4+fZWB{teZl;{>yOqp`8SpS
z5B^=*_?G|gOZ=R2kp`~0+X9Z5|9)P=j2G~CFd21aPNwIjU-=zu=@d`TOL2mylFR^w
zo%qA9%oFvzM0uuKVlU1Fx_qGW;g(LxnXIMKK|LQiXkP7xZUCb^Up{xEWt9o*dE@(k
z<j|j*(fQw{7gKN8N8Ni%eE&~38cmR-ep>$iAH1ud8UcJ$dUJA+3tXj}(gT!^$!1UB
z*nIzq2iXCt;zcfnc!w}Yq%zM-&)pAE;B+rsrw?d7FO|OUyKF&4Y3aG~2Y!csQ>9=e
z8o>bIpCMSp@YC|c()S_UPmn@;qR}aRN4XeyU8FU4=*uk0h943+I02zUwSnl3`X&0M
zafwh8;PLaIC;rsL0KLpECitXn!#s!H8T<y#E+*78*|6`E`g403ehHIbodLfrVVsd&
z<x{Gw6FGT<EaR8S=4c4aZO&H0M0;5KRCDpC+>o9>9(d=^<JKW8Kdnf~?OpgnpPOxS
zp>T`*Fq)2G2Rsye2kOCE!6##^@*2nK1ldm77gf}@O(*98CgQD?pz~W%URo`ShWnQ&
zuaw2R#{_{8qBWk5RXW~AV+?QYB!puD(y#RI=pq|Bc8Aa7lSx#3#8>jeXoypP9v|E$
zd{i2EB{_%84AydHppZ6khVRR3Hk`R_65|4NT;&2ry{+?|F`4gWCwa8(=Q<1cB+<?|
zHA^SQue+y5Z%%gGU0{>)2@5Q=WvI-@wv*b#8#{6)^EHNx{oYCwtgYGk1b7wRt><_-
zi9kFrQ$5q<risyI5++{Zc+SfYRf!hc_}CWrfP9EB5Y_xPv2U1jS~NcVJ(zoW)iG4x
zuK_6D^xg!A%KJJWht%0AeP<`L-|;#6D?T%+qtY1X<M!PgOYz-pP2l@jQ}sQ1n?@i?
zHtN`q{!^3R_&s490@m9uQgA{Jieugxk5SD3J=y|pFUkLjt+mZ>{NESK|BR<n-p%du
zY7^cncii*)z+h~b-*kRy{8Sdto|c|G*gM+o{BhjYFUaX1r=9j|QMP6A>_>gYS~U<P
z^jF=IL&;AA<5LhtPIfn-i+F-e+*4#spDfd_@R8(C=~M9nRTr#4c(Sa%fkp<~^;DON
zPzb0B4OG=dSFrF@A&ELkpyWJ9iSGMIZ@sf=BwetLdJxEisY(YXFr(h^@vGxaGo3DW
z8M*kjd*LYA2OFJI#IDo7bjCg4D(3Gvv+2=k_vIA5^f;7{6Sly_+)H*B8~DOG^QVz)
zT%wp4<S#K3CGecVbc{981Z4uJMl$Pj4DT;2P7$L3Qa5VnF%z&(;Y?srcb~`s6PqrK
z4KXrWL$6<8JCN~4cGnT(X%t?#!y&4w9<swi$Z2MH^O$uCOEQ|Fp=u<cMFaiY#=UDy
zXX^D;oy><+-`SvrVy(F%WbJOUQ-mT4&>GnHr!d>0`@uW&hF)|nBZEe8qVQDV#9!<Z
zL=z)bV$ww59AzS2gP}L_&{fmy5>C$=j1V8Zha&LLP@QRjknQ7Du+9%{zna@*NWis5
zu6_e?xC>u9;jw)vnh5FF*$`u&s(rv(`oNlwxE=GOF5ZqFB99Oh$aq~dn=|t8q^dcY
z-<(b5$q7MBM3+ZhMFiH?$1J1p<<M0%Gcx_9!@phwthIt=W-wS4>oZ}>YlfKV+JlAl
zN30<Ve04O<$-t=LdpJ=~mQCUUf2*Ab0*0<X#^2-#^aLwTJ>@zUPnPKq`k3h1OJL{3
z3)g|^Y6=J60rTh$Wgq2M^kkVor3Q%NQxLKHPnPLd9CtZ6upN(y^DqC}&ERqD0r_wn
zJ40wM{+(K+v6)bl+r=gf&oZbOZdF+%LiqA_QRw*}GAJZU5?J;nnPmHR@SvIj8BAWe
z!*fq`E|3mcP6&0n-Svn(C(JGgd?;Q{$6*!)Y@d&Tto(wfdr>q-|FWPl68{btIP}Lh
zL`MJ0M+6>=n_%IepJy-a3pa=YBo8mAm<8B^3U<3~TrBJHno`5Ul8i&!W%;c2SWc3)
zCsLzF-$`EWDY0r#mers56+AfZQ!a`D|66~uOdsGkQWf|#l`j5?N-R%}kb=8#%hB@%
z7`jMx9>Z%DKE?VZAB1=@Js01tZf$NnYLQ>c<N_o*UCK%GaTxuE#nfFaCQIIz$j0<B
zZDWt(BHq&Vc}KJ50cZy9B;<vH-vpYAx69~90x#WgyL|4JV+MAkxdANfa;EkBb6e}x
z=6Z9zEV)@|y+F6s@>9}2Ub@{5(t$;Kua%!Blaw#keFXuWs??TY_hsNrE*1f?(%eKo
zUok-2<!d+ORp|Z_04EMlb@w;-Y%!1<GeN$L-djPsA0i3z!hue}>CMw@0^)#fN5Al4
z!D3_{)+Xj&#I2So4tBe&81AxIp4paJY1I<B5X}F{NNJu#o<jwFnV^%86T2M49i0qS
z`Sk6wQYUnks=h2Df4eOIDyt=yLK;=DmPeU#W)}^POTE0yOg5DaI>xZc;2v>dFQ8?t
z2ZY?a>OF6ldq<qq(F<bEeeNA~c@Dw_vDe-1e*z?=ehqk_$zsuE<WBdFyex{iAoi-)
zy`z5|Oa2R>uX^R9zqixbY3%KvNW7IjOe5|(L4!?Ia@c!Y0I&CcxbXbB)4lKBi8P8V
zh`#Rj6-)s2F$<$lo$ej^*QC%{5P8|@-jVNMGPK1|r!Mz~_?{~F8q7g{$hqg&_Q`D{
zq1f!@-Glx6TMAwKdHDp37~c0go<?Ud?^|x^__a&|>p|aa7S!{rnTFrH;Vhuz*D{Ir
zhv;ULz>Z(bB#tj8H=6`@{8}b)O8Wns%|rJ6YNit0@Md7guVoSoJmR*VU&}OpySlpB
zEU@EOGKu@cLvll;k9z5jIX+|ga`hhAqa0M$?im%<(iJbs7u+O;&f3?3&gI&2aP`%o
z@+({K?^8rdV6^(Rtjzu4ane5REU&KIHv+5ojllZ-A<%Kc_shqA7)dK1J7V1Hy(N@R
zc*y%l1e1!o{_y@0kvUMm3S916F<?KnU&oRCI?n4?b6D>W5&hsVAGdc8?hlWhY2>qh
z@&0fi%Vr@0cf~FnM(umoP2Vp9_iGWoU!&%p_M+W;@iky^AA)0SXSlx=h+X3E5eMbU
ze}5?a;(fp{0{s0qCqNf-_L^9p+fMTpXov1ye*8Kl>3g`z_iyG#x$z!HpN{WW%_~{E
zd*mp7e|_+!UG!MUDN`7alzT8#yS!W$m}CM&YqrY|WJ<!aa@%b<A$!Fr^kr=pjxGx?
z@^HVHU;w(rS^l+%lMTnh8~qn_(!soai!NLSiZ|{Jr+uvd7+uVZ%H6Df-@UYL0DSyy
z55CME^oH3D=ncQE{_U=Q(FMTNuz8mNzp~FjX2g)l%fA-fhtJu^uVw}Fmhaoz&00IS
z=GL{7pZ||vJ7Qie3zt4&y%EbbmP4k#`bH~nam9PX+!c?%`nKY8t$5$>Sy!AF_F#Xv
zeR$fo2>8YQ_76`xI|m20eoo{RbX0-w{iwfq=S14LJf%c#Z<J5IuwYb(%Vv&hrFi8}
z+B<u%+Y3*g<G${6`uv*=CwsCS$8kR4Jf}ndT*igQ5uS+{&!3tr&Tw+!tR^Bold+!b
zjg_C{SkF15J$1Y%fj7cEjeyU6tXhrf;>3yj*A$COf491_{%F00$*nLwTbFumbI7O}
zv>yliZ=bo5Q<qu%rxVQKipP}_!$yt@E7akjIfHKgwAvD|Sl(DH<G+|HL)O0@IRsQ@
zooJ{=#^2a@2K=AaHe2F|b9skw2CgX+#t)d#^RYLkWDbI|CvfUFmCOV;mm4)W0|=~(
z7hx49HxwZ*^^Ad6S0AmkRM9V(#X0*cxk9<Szm+Mr-%(nOnZUMMnEO1yf@E?5M6=nX
zbYs&=pKEzWSS!qr{GLAy#mEgYcl-><YmZg{G9_=qvn(18fDHOv6vpY#!fSmKj*QG+
z*1(h(cv4h0GdV%Z?yEk-1Q)8t7AEt>1IGD2h8WX6W4!g1RoKm)exK3~VmkM*2P=Z5
z+2Zsh#(KhO@y1@{QO*m@Wqo!nWOVn5?}xd={Ji$4rC({4fJYrmN`TBkvRrN_5?5DO
zR1NYiM$6|x-B@4SXu<IBIR|ngb(>1Je&!PN&>ML}_!_fwOri!>UM*f2fDH?Sr!$#Q
zj`EI-eNGG?D)2)u)sD6<j@xb|KJPhWDwODtL$B`!Zr=>{_OO2AC1zq7KtoR5V;$V3
zB+_)OCP1uIJv$&3@P)X-+GReaq*pf()&sT6T$-it1K?%?Eh@$uM)=<=KX{L|Bs@~e
zV{O))RoYyE9dO|IIQkN4<aFK=S$bE^LMN;@*XM|~Kg7g&?%zE+^^JxExs9KkW08=)
ztmLae8JB~mfZI#dQ`KrxNa2g`4ZNOe9p+AGb1QjJ8)N_Pp?B7#;C*>usc^3}JJB&^
zPKwasHTUIo-uA9sFMRLj9Wxkii|=2b9r!T|0<OHH3-_ui=nEJ+!|3|Vb<T$b7E=vi
z>LbcFu(AHrCfu|}L)P(Va3v8gu`;}Ju0zbUICLow4koX;=G;kdIfqLY-lO$3AV^^Z
zR1gb5UP-eK9#gs;>b}Ld3Hx*AgY}<Rerl;}Iq>zJ#Qz&v8{kU^4g_2y#1a<>md@?x
zfLz<M5R$&{av2$<9lgOhZ3;XvjlQBQL{#MUfiosQ)#Sw-VFM=2IXnlBH{|NuxHDWu
z2SBL2TyUy@0}A7v`IjFAUX+H16rB%91F%?Dzhb2_!boi}yqu04GqoKW5-jI$h>n8@
zMG{N*gBMk6Txc9C>U`+CXV8J@INp0%VMo1}{d!Egy}vzC-E%JC$^Lg2sM3Ky^}?EX
zi=QtG%ldDuYyfxhW(?%2@Aa6MnZkoWsNh?Pd6+me5*+by&$aI22Eb{FQ_9DrjudYn
zP>cW|Fdd{fO;z{IP>lq@wbhlxqw6{1ETDs`PprM)qm5P~=^Ezg$J|X}BFC1>Ggs%-
zq;QZYLplMRiOh>~p#KDS5vaY9a+T{-N-hw{6?1lgZi9ZiV(>&wypT>UzKGo1I>!16
z%>3A3vZxg1D0GKd6%(Ht9Q_Onw*;8~6;FkH?B{;cjo~)dVM_kQ9aEYrEM6|Rk1$7q
zh=0f#SP|aDQ=Bq1$`Y_4mbx@+V@@M{AtksezLZq4lsE%}vKr8T#$+psHot;ta)~L$
zjlROvUuLTHSDntWrpGjgDK$I}{14Y~5eDx01zgPZD32cTu}K)Ni42W@a3+5EI08ER
z*A!;b_3;)c;nBJzn~yeE@KRApC)#N^ZImyWQia404))$ZKl(X+0z5dc0j?r&=_>Ir
zO^yn?L|h$A@dcE#Y^3VmOy1|*mCc`5H(E(%NVy5ZmJJ3j<)~Le3J_m-WxXJ-NfFm8
z)Zh<~I_(FgU*ydWx!@`>RFv@7;EIqNUH?&ByAHh<yfEzj1LTb4K@s75<cN`vPe=*p
z<eig%Kt~?_hF3*xJ3OIoFm~|ONe(*}GW|)v1+zDXY5Z^=JvI-Ps7^ySy+henxJJPD
z*DTQRQH1j|>YV?L7r_8%Tn}nFFj~z4a4$~$HV0tivw47@a$%!ln7@yPvH;Q?5V`PC
zF~FVi^(+K|P$RT`WHktwlL6Pgd?@_0f5FAzTN<iY(GQ9s%M69CgcOg!b%x{gg@eq9
za=6e27Wnbu_1`XMPv6BWKNIaDEc-4decv;a3fhjS0-V>UU<67Cd@R!g73^B~a+TV5
zEggt4&vsbrYQNIFuC)@fr5nu+Vjwr0tIaJEWyZ2h#t5FV(R4)2t0cZu6p!<yo&_Wa
z0{<SCk}1M@(^&kG6%<_`Ng;7(Sotf^b#+RH@DXtxOCj}9;tV(e;4aUnAOOLe;D!wH
z3?(mYj#S2r_(Kw~fYMCdV0hguof;V)e}8=-PL6kVZqPUZdLP<jk)H--6QkspK++`r
zniA6#m8xcXTUseH$jA?BOy{UEt{FPKkdzk;NSO!YGmV8s1+<QKj<po$3`1W(CMX*s
z>lQK^FcUcYlt*=pUTDqIYtpO0nWpThx+pj9ja0GW`YEm38s<;MlO(lntXqqdoh9^v
z#VWv)-D3UU+M}E6|BywqtN%=fY<*Qelf6r5dd@3^8y@mHcqI1AqA&ae$1IQS<=tA@
z*ldY*_Yh<-EI;uE?&`oB6O-I`KeV(2As@z!Tc}Of0lf{i)7m<4AX0U}>N%zDBDR53
zq0$QuW0-0o(jd<QzrKnL4obOZD${|FmyNhGWWv^0)&xowxDuhE8<_hb6rPbe_n8OU
zC53Z{X<Xq_z=`7Yy~ZX#`gyG-UN|7f_BTVIIW!+)y@+T?<#?Y&MP!TO=_EH6g!M*%
z45~`33zuTU%ruPa%>}LUKqyvpv(-9xqf<&PdrXuix{d{7RY?!Uf8^A9u2RcPR9iIw
zjBrBNTqT<Yiqw4*fmq5JluZp4Gt1KnJoc_*v{VP%35`s@r4lTqkabwZAue@hVQ=U5
zq}S-S?hgUJ(<_uez-L^d(hk{0Y)gL+c8lC$Z_RR%JHp-DF7k%Hq4lBw+-KV_@?g(v
z!N|q!&TJTYBi_0dBX^+Bv}5GKy&X$N0rXq6WqeU<#+}(Sa@XpXEE;!c(<riP<WK9a
z>>7C^ezs*pKjOD%+{i*))Vz`6EN;odkp_AfHjeZdpKs+zL;M^&M+VltSUOU?=#6b1
zDLA)b?MQ)Kz}}JWdD|9`H2k}<d8EaJJGXkI2E38oBL(BuEgvcPcV_!YkMr5qk0ijw
z?H{TBcW41gk96xc5Ey~YAVS=YAw-B<FoobU+@>+a2JbV?Aw?i>!5~ru{-!38BA7Qa
zir4_&mRZCG`&JAiHo%`{8nGVMTQ-i^#<(@}$c+soXj-`?8%es5>Oxi$A@0Ub0)TJP
zR3gM}8cP7Ro106Z_kCGRip(V&jn&PYn@cj~ajXWDt(BjD7XOD1S1)ivtm=l7-hj=)
zNMP2b)^1`DNEHAowhaB$SpDfPEJHTgcx!EST`Cz!7D9z7u<;Fjj)DD~%=E<GT7RU3
z&+u}Ly7F1=f7)s(qJ?Z_tHtLN*u+@4l*gA<3)jpiX+gcn8+U8{XH*+X`kAP0C)Ep*
zY)GaH0}Je)CabGIDI-9@;KQWC9Pb8-*Ua7PH%flNigv5-(Z<i~t#pZJe=rz=l%8Z?
zC-6{5xD9;#a`0T=P#a*Kwim;@0y!7NSCXM}TpPDmQJ0V*{5mZsJOO+!jBCLxt*Urw
z)7K?Oz+<-`mjvy(0gCu>`9c)Rfs>uOG5@S3!MI+g9roIqlq+Q#0|LgXEkF=SAk3e2
zGgbiWs4qe})1yH)n`_P06@jJU=z@&lkyTPL>E?0S?SM!EO<D#r=Nmphr`n(JB^?`w
zM#!k9vJRqK8yg@4oVqMTOvs*wEWSK<yo5=_tfGA=%a%H9g+dnnA|f2!4=B^)YZP5f
z;oWpRVtvMBz5>v0;Pu{r9wl5Wq=aiLcR>m1`CJ9ogbZHv81{NjNTsphQ9N^*H>S|F
zK5+@Uhg9q+^({TU37(>N-AgD7ZoV?>#VfOVM{h(xe1fFohMJi!og3d!(#~`JIMf6V
z2e&fmjp9kK-;v7%az?6DtGo?(Rs6t%yXg$|E$q?rp*1>EjjXR;S6)5m9En+c^~jzQ
zP6IcodSnHWqRg7@B$ZPjHK+{(%n?7vUKmc5eV-p)jNiRTUUf40PmwJK?heE~;OP0<
zhPSX!1)G$tVR+k&+8tCf%wK~i%SOE46IGo1Y3W-9^lv}ke*X9V{Qm*~009600|4xX
Jl?nh-8vs3eK}-Mu

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
zcmV;89dhCyiwFP!000001MEH7cH2mHIeCko@{n`#TCFGs<wzvKO*`FcTkg?}yhM~b
zleiro5GaZmLjVJSTBh4CIeE^>$0RSw$K)sS0lBvppb8r)S(e*9tkZ3QKrOfKt-4#?
zs+wB%2kU~?Z!Wz*`&_9Bsn_WgzHc_oUdJ@~v&r*ecKA!0pA8}<&7#-}p~=T+>lc{z
zp8@5`6%8Xd@DEnadUKUf-wqttzc^SuKYO{kz51-bvOneHgowYPQevlWuBJ7#um-5p
zj}BHRaXj5^G^W%F>(j}!?$fy8#7;w0vYF=HjjiZIMG5wK(@gW<L~fG%`ue(l-L41W
zMWY3SsPX$(Cj)yzFRe}22kQDZg;J5b8?l!sfo;VM)VYljOmlP9Zz88Mr_$X;^I@H<
z{S~tBTbHyya4)AGeSSFDZ?NC+-kw;#PrZJ`KG{}OzX*a0cnTa^w}Z<@bmi|iWG*NW
z%`Pvk@V0+Q-u~uomw4_dgr8&_gaj%khqHJ>{n+KWsqZ&rekkhD$PV2pe(0Y~+(-@r
z0*@B2F7Ulutxng$+QzpqjL0m4!Lj1{komWVn}g%;S&I?1XCZZ9v|YJj;9o+1XjW|t
zn)ayWz+Zuf??M{K<U5y+Xqcda>|_1?$nxUb5w!pZ`wjL6KLNd6uRp?a^${!g?FGI<
z6zw<oSIlSGv3o`Pw=~*sh-YZMA)4QxP;V+~WUc--nD_)x;l&qNLWkrJaq=MpNAl%P
zKqQUl!1x`#0<0d6sF#J|1AeJn@TK0&fuVkUAV`iv*CwY{bUBM6>Sv*$@HLbl%^W=X
z=X*lrSTXIlK!j{I&CS*pj3j&kA7U3kF`K*1)^5AI-(WxCwP0AR@{j_dBie7)yNE9N
zleIf_<!gMzHq(;(z+FbJ=f<~MH6t2Z`C9l}S&3S5-*av1N0iJ$jj5USneWx9GizKs
ze&gEx;5G)qIKH+*Iy~V;R{P%#UJ&sE#w&kdj3bC?)L(f@4m~fphS?Tg!AEGqBXK}R
zl-MBof=l<0Fa@vOctR2;v%4G7`26&wwg#Ek_sBb)KJO8HQ9JOVz>i_(My#8T8<G+9
znXz5ZgP#Yhja7n!0Ut0A*&n+eEy{K2bb;r90BLnQ-JSN>Y|^paYTHf|CZRQIH+Q<t
z9yPnNJ}0oF2EDNm>Zrl_AhOd{5(XaszDgR4wYlT;wtIHF+ij0}_V$Q2t?|zGw&RRP
z?OuD_w2RyPC+a&xWSql8$C}18940utFCd-Xm|D<yd)w~OQFFXCZuOdGt84W-y-|BS
zl7J))HQt6n9N2-^_<;}0R^tcDa~;OUPiZs_U_7YMu*U_V*=}z4T5YpC0;%fQW6K;n
zbf?|fZg<S_xYKUUhsL~b)8h_xnm`MSc6ZEedpz3N+G*O>R?F_Sx;>}403z<&^p@4x
zu`JW>ZFPHX>hxOMt!B$^)16kQ<JgW}*!0cq_n`$6&%bC4;vfX+*m&uB_r`pyH|jZC
z-L~Bx?=*K{MD{v6ZF}3?wycq})7@DRhWj?}AeCYMSzFt^?#}j3XM3mJH9Ig6dhKq@
z>gAh<X%KjU<=nePYuxP8EvvcJrY+0vY&p)TX>U=hXKlA>yIoH2`?g4TdZUhQwp%c~
z+B;xyz~CNjJNCBIp<CUKIS0k}ZPs#j>}GFl0>7c#fZ#Up9=c`r#yxvy)Y*3O%?_Y7
zj}F`m|IIAEce6XrPS4(QTFrKA)P=d*1|Y^G3m&(f<~ZNm;)X!1x=h?Q6vht<;uKgR
zm<=wCge3fznG4DthYgCe2eN<Z`u%RbRR=kYkL+the%?ogSb)#<15v^R`P<P-<T6V8
zM3iFc$8XNg-VRRz5*o#=R3#y)@~mp$s<JE_Zq`i{{7S=VD=6TTPNLqbp#b|V6aa=e
z*5n2Cf(uPkV6`fmh^C8}8C@jNM$A+jA(}oyG8&0eo#jm@R#A20Lt33)gVd{<+nZ)<
zv$>t<Rphg%EhJG~Ub<lvlT!|For5N|4x(#U3u4nO!>0M`$L3S=(!C+C12FLDE;$RC
zT?TsK1&zrx3_ypDZ%HsFe&BBgqd!nPCSX}8JcwER^K=X_1HlONDQUH##pi6uqkTw{
z*>Q`FG7j(%6m9*2D7v%R1d4Vak)r2QY>K=+Iy}uFm@!Pq@yd$r39*q0p-p}TT+<qX
z=1OXbCAtpTj(uj3U$r0yBP%^~?GH5GAo1-KeG4&(X0}bEXgu=>*wVAm$E-7ojYV;Y
zgGsIOlS$huV|}eJ!TK0!P4f{+D{ZzIH4UN(G9spD6c7->WA|bfvUvz(_R*|^LdY%G
zA~s_;pIpRyFv&&f+B$myd7iVfwI|jzi1wn$8$xDxd^?;{8uFJLWNdj6UEf1^9H+F#
z4ed*me$l~RLo5wL{&RgrFb5Zuh;VG#e1P(La8Owz7*=5C6Wg<*=mFS&tBn1B!4cJZ
z#1VCLGldUs?A^jZ@jNmd#=(Hi+}b+BJ+kR;-Go7PIfVhmp{|p6$+Uhi#zBSEi<FBe
zlt>F%FaF6iY?pC`_7|dI8~%Gl8XiXxuv~K&v?5eyQ}H|;BoilnC+#EhPH~OCPpWC{
zlEJl$@&Tt?7+SXx8wW_gsVoW{2Ik?+25S<DnW^aL#sxLu@{&3(pa4deHHP5;0%8-4
z1mIB*Fm2mq)3*JEWPE3{*?UBizYXaa6t@UuFY@?Qf-{%ha5y-A_4eclr=CunPey#F
zY_4_gG1qbqQIdCwmZP1!bRSh&=JHnvD`Igzm-Cy#j9?!42S9h$?@S6j&yR|3#e@EM
z>dphYs7ndL?R;U1D;E8iUWoldDM9Hb8*7a+ullF7QN8}(G~3N~X8qr6cbi+w_5Vjm
z`_F*5E3WSjVMf&q$Bm|*bvvYC2qNDA3ox9a31Ck^q}SkoR6KHjhr^f0Cr88KI;6do
z72y~g20qMYqu57m>}9f{wa}2(g2=J57O<7zh#YVgrDjZmD8@Doa?m$m4!geOLB<B-
zbXqc|K^PnC@t{vSopw<kU}`)I<}twBHJ}q~i4Jr?e0p7=R}G~zq$Z)nz9;22`<mI+
zPi-zEV{RF#rM0qVdoJ~3XjI{K{9P@n8o}f5Hv6Em*;HS=uVF>*nAF?|X}UK2{^;x-
z;wqTM#{2bk^3%#+B<1;QEb@^TO1`*}QZ03AtRP~E+LM47`xCRTw@U_zli-{E27Cqz
zD*31VGf*vY>Gww?B8+qxKw#9976D=B@R<#%^|}Gf8LRlXg7GI7nSd&Eu=<PxyxKou
ze?gq}zw{LPs#7)ppR>ZbU>kGzf3MqWX8HeCr`cWd|3^ri|2LjKT_H~i3+`b-Jqh6x
z<u?;BRLA_sG0x{G<yH6=KkQ=|QXikDvk~ZgWIXe2;iZZWZO*0e^H2B>rZo#2J4hSe
z-34}VEaJD2KdBkTXcWBp{PoH3xfNm2!}McKmcYcSJ*5{en6tO6>YBmbX9n<Qta7st
zpvfY<Ir-~v2(l$Iu_6L0B`BuUm+?(5bvB6QJ7_kC)Iik5%y)|Jb2OzvNtM+gcl~CK
zw*_?_vl`;t+B$jiglN2)S0Q+{(hIfkOrmf<ZLZj!Rw$&=%tMhP+O`z7UQ?^odo4j0
z<xwCouYWBIRf69Ew^Da^LwZ4d8bbZYPECjAqx|tv$MEYwA`X2J{OKAH?)uCpT_>lM
zI~CA0kmIist6AK|Ft|7S!%);y(~$`y;siw!8Wrm)$P7yM53YFfG2K{MkrU?Ih|&Uw
z*s=6#vfR3!gSk-?nlwc2Mv_}<J!*lPQMw4jvZJhLKGI6R9DBeByP|9<v|PTkzF~UG
zmIb(U7H=Bt?=*C;aOq)fC{+@GB2#oAtT|50lH&YhzVP$Z?<8KyFW*kB(7Ke14#M+1
zlv-hRE>s4qbAT$CWRU9|f$K=<2?syJ(uTvtO_r*HEay*&wkb#7{j^Fx5(^twm;gs+
zS<7Nh0T+-+mpMd7Sw^ibg&?Xb80j>XSx~!^ye~o*;uY{nVYnwy7E@C|FbV>&(*0^|
zYuqc_S;ntihxJlN_-0>U+p6h!*#Ho|F%t}&1FS2xDo8@2r8DT1amHHCrpV^l-5s1i
ze||I=<joI&Hvf{_I;$D=I$eWXU0+Yh_mNOA9v&9lmxsqE=ch+`$o!e-Eeh}0ay{zk
zu&$*4W{21*136++)1HMPnn6GdHh@6WXS~Q7kAZdLjAa9d0^{O~L!4<$K^zm#-aXJ%
z!r+o<`YK_u6Ec5xrVCy$3q6fnfd&Fy%8f%gQVK?(l;wk?(;tpb-!ap60Ag9g8_4``
z=;ah7)%=XP9OU4D7=dqON2zMH8tA8sj5z}(SHj3rE9E5Um^(;I)Q#On1I)JsIR1C|
z`ta3}@m_g<di3|_M}xEB`RTFoKCM2jIHXe#<PR56iK*ZCQ5bs-L*_&Sy~xhjlF@j=
zC-uR*e}3}*DJ#8T!5^QcCHGiSEck4pl7HLkrGSbi7c2QhD|eTYYXv2Z^&%8=+D$<-
z8wzaK7@CJ4=xtQfD6n4LGB3uK|8oTi_s8bjmof%Emx&m4{^Ps{J&!vHz~Z>X$P)a(
zHx8hzmeam?7VG*(e(I*WUS|HP!cY?*YN3p*kUb(RAHO;`a@PL8dtmYWHs;v>ZL{6U
z*#E6&ySudiA0u)5pIZ<W+UPJ(dtoi$3;}ryf_Kf*<iGF+0@q>Q&An`H^aL`VRq}m$
z0kzC3zK6k$OH+BVUSURnS$>st0Ot5K!XC&_8m1`d+yyN8P>%7OzMz{9GM~nBij4!A
zHK(KF9z1Rlym<5KMPSd6pVkyc$`o73g$`TG`TeUCrLwFN!16{3_IWX2R!71F{O<P5
zx_FIFR-=$&My|$etpEk}FF>#FlV+i;K%HgA_3)&K8`H~LbG-}{91g`TGom)gKTtBU
zt|%iE8#`$5Z4i4x?GHSH<@>YaH|K@Lxm^IG=?(x*)o5>SG?c@qHX^Z8l^2tcF=Ctp
zWUOogl^;0t2b8jVrL}x4{8Ic@v{p7pah<2QAyJT_{D6^lF(7p?(qB0npvbgKVVfhN
z3(M@4HUXsO!(>jioG6v`pigj4Er>JM(G(tqF{A-lMOJJ@_iAO<snTp#i^mjC!r+>5
znWGz<GVemoNEtixx1obGH8hR&aumpwqYUsOKd#z*Y1y_+^V8z`pLy>vfI0f#mbul<
zuK#qp-R1uO$4J`x&vT{*f_enH1!Zy%6sJ@vBG(hwo&bB8q9-+yDwCPS3)ZDiAA?Cn
zs1oVQm*1kx?ji_pNoKb>|0*|?lT;67?~w%tOjA_1f0O;<P2GLoQZT&@-HS;~aIXcJ
zmKV&m5RAEX>AMU#zUARH9fel(!D0nvpi{C*f3YYhq69gKdi)QZABuX|zI?t#pKZ^d
zHj<tD4Yo=!PX#v#y@{#s6y*`BIMX!A4@aki<2SF-pJUdW!kv><o<(Sz^07p1*1Xhm
z9B{okYk?=Le&T0!@CGT4-grv#sVs`4FmGWrM*`Bq{&zF$e`g(Rs6EWs1HuYfzzir^
zBLE$iS}?zo3<Tt{cs}T_fdP|q_i=eI@}PDGneOgwMQ;n}3=X<nq?bHd$jtd!bn8cW
z{0Uc()f!3)$S6PI;=%UiD={b;+tC<Awa2y?<Dj9XstpSjl%9SGLW%Ci{if*JBz1{l
zIdI{P(J(5s`lJL5LzY=$<5_hnL%?)^jm|=k9l=6tI;f?ErN5IytSs*=Mtj}UCWF8$
zTy4b^9VqderKHST(~HqE@x6Tl^{SDGuIz+%bFwmYJxgd-nY)0RcP9=mfC%aJNpwk;
z<;2uOQ{fXx0$`~$L78Jztcb||=lGaX{uzLIVAM;omSQf!9;U}8KgQBk^8o>N6|G-N
zY!)$I7FHq=11iJF^|cwa7(>1QRmUfz+hpkQAc6&l%$+$hbJhJUs(Xn)h*$}ng>)nJ
z+mLiUvtB&Fa?7=Ixc6G>;2VmCDo)M?1VPb)iMm}4Dzm-7r%IJcWM@%XhmNh87jt#`
zpg_ym-F<QN^6>oRY$(^po}U~J1{r^!27)}w3b=q)e{L?RrC5*<>$8p>1!@g)R)KUZ
zA_}vW`A%)#(sKa-q5D7pgn6tN@B$r+vNlGxL2SjdsJ4y^s9+js?LK(|LlXBLX3BgQ
zIJdaXvAIFote|mAqukP~=K@@7moT8gh}mF%GRO={`_w}&w)&&Lx<QI6&Y&V$DU*&P
zy_4!ZTU3lFntP)E;y{-E?=(8-4vT7<qQ!OQGH)1PE)#Z%1bXQp`bDHWtp9y3|4+Bm
z%%1;fcDkMR(*N@a=>hydEzSQ^<o>Dj{w$q8^PNAf3g=JiAX1_{m94?*=|LNM`E-4&
z%!Aa@JxE`<1L0x)2ODgS`kd*S7#H^_{shtX4`0ZwFsA^=N47Qow$keT>MfzAA+$7v
zesPA-T>B@7v#VT~&-_UBg4m!!3o6r923)?qh1a|>Nn@#~8g+qPZ#f%_pwu+iu9A!w
zcltz3w8EbYpP++I_~`^~O1RUdd&8oaKmw4p;oCQZGXnKlC2Ryk;;Y#L_rl3p$m%Wf
z!0{cXWnlxE9RUlXMT@FHZ9=f9Z2N_A2N-COC@j>eiZqa2Rof`p?QplImNsa${a10Q
z>0R2GWB)ZfooxK4*=x6#_TOWq()iDm_CrDYA=19s$SBM&Y>ITNl66Hf@(SbJ9-2i+
z4y4EHJwQ{xb{28R`F}4T(7gFy5dYKdEaSf)CCT$Y<S~4oGN<<zpObsP`ib?Gr1JT%
zp4RedZOobfolZM<{zDsHFX#UwBtHL>Ih#&@Nq#&K2CZu`^U;=&t7Pm0TNm3|C*R=0
zSW;YD9xF2<*2Yt?F25ZIQ|i~C#$;!jF*G*NF}6WO<LF#s+uh-Hn4U@`0fLIu_Qtjs
zpbZLd)m_ePQ$1O%9o+%(4f{HzH*OS1Nxy|jg&R2&{#l$SYj-&=tz{Gt?jm8HHm-~T
zBuPNF@W<ns5|ATj1uxVkQgeOVn>lniwc^RaDmDcidZ@mwtryg8tge%H`Eijr_}QM?
z_eOr3uR{8CcY&b1bSuomfE~;{N1VDruvxI3*>)Wj4-54lXo2dh6Hty*MyNX@Wl?1C
z&aUAZw#<9O{UB%fv!)DO5f{U<y=%Q!PXdwe-WhUo8tl75AJ-r9pu@t<8#3xr9lVH~
z>|izY-R@<xH3zR*0Izu$c+JlWFHAC0t8owPI#7Tgan)$xVFYA0CBva5sK?H|l7Pq=
zY(!Hp$pOO)kB(7yC^5cJTN`3Rzo?d7R>s^`KmUvjLUi584<6`aX<@aag#Z;+nAtd%
z>ss1%gOM=p#=$`e%L2TmrC>@RYZ_5;yO*;;Mza{E)it?h6BZ_`d*KHmI~~VyvNgG}
zT)B}o;x2ppgO;zPyDIF(p{_HZZ@*_<LaH<8ETdN?CS;eDpj|5?1j$cwxRndaJ!Um3
z15ITnNDt^eav|S9S0V2f31(q(=z%9Ls9RxOz*3PCNb>gZ>^H-~(c8n*!?QQ18wKnN
zkB7sO<6!1H>GsJqyg02E1B~S_bzmni(NA1)+Ml}Ypf;)RCL2M+A5w#wpV*URmz6}>
zjubIsqIVx&R6vIlUKtFm%kVPuN`J#a+WYGEao;!1kN^1m`hT;xmDm55@gI+pwD^zY
zBq)MM#HWED5xJa2ii0fK=W~P%#SVNMxFY3e^@|`8#ZAaU%|rxA>S$m!ig0AC3R^^p
zFb?oAU=%Eg99(WIx_@Meev!hwy+ehIu^0!U-Q`fdr-<qCx!wAe8;;ai6221wgFEC#
z1nA4%0^ZLicZ&|WO8|U=&+5$y3-uEh3vq@1-a9T1WjDn<O83UkrpXT7hv;2C&YuOm
z%<rX~t!#<_8_3i0-e4s`r^Qfw^${fxA6uVC<J{PiV%&a@fm+b#qKj$DLWtG8#Vgus
zFiB?3MtB533+5+g@#qtk;jEKqBF?y&hwYMrLK!cQo<j>Xu?r(i^!(hT!Lt?zX6W1W
zB}<fB=8G^rP%updcFGXVhnwWI#W+^3=aCsp4h&3trStAz|B~3BR9bNT?~{yxdFTJP
zI{E$o&2Dq4|35-1(f`xixKNH;itbO?xj5uP3=APqqh;v#Jr(r1ORqvf&q@ZoxzQ5D
zC_ImK!60WXaI09{$3Qt$m=rats$DLJX8s31xb}y5g`gfiTo%bz6yCL5C;rT-od4&p
z9lm!PbNPQW@Bi8AE#p5PBi)_<XQE!0&Y6eh{o1t4pUD0K&pf_#eHx+7!Y=CzBJ{8%
zR!bxgJIuu=-zzYgu$5=sl~QWE-!EJlnEaQX27j`tl>dLa+doOw{NL<0o2@MWH(PCU
z$^RcAmE8Z5Ui^@8PHFeR@H=BAuTL+1;g!O}U2f6Jo(IJadP+}ldP)|(8!OFPdOena
zxcZVTalTZ+RaxX|dVR?PcV_W=?sRRIR^+}nXX&+6+@NKoT}rPxSqk+B*~^<3;XkN8
zaqc)4lS+5j<~HLt>&?1ZvK^PJ4ROG)a_1hxten5H*wsy1Bl32G<VqIl^(=1YIO2Y0
z^%f52Sy4kdRUmCbE3BXIoNX_;#8|G8h;_tp=KIY1pe&mxiirkE!J3y2mwKeMxXq>r
z7Mx+p{9}%GnEP5^3Y#xFkX}Cp8|%s+UR`^`0^{)1H_MALR}7;)S+x)=KQh2B5SK5r
zTQUk)x8?zrjD!@numlt80fCC7sPs!0TuhxxhvXIX12Dp<UEB+OEES%wSJhI9vs)2U
znL&_rACq!0Z&E^8B`8zkiISA7zEH(3KD=AGt4C`ry~HM?Mi<wmbWq5y)UBfCDcTRI
z^;uj$J;cku*a0}X({E%BRHhc$m6~3WGC=P3&QPwh9-bXP|J~7<l*0MW<QRw^ZZ!8q
zpyFBtA1b3(!NqKO$g=Bc`Fq(k7>n0@p5uw;%1v@GC-9mv9ytbbpI?ZUHNlRvr^69;
z#VDSTA1606ZQ!m|ahEu*#)g#jU0h(tSi7tbK3`hl2mBh%;c|tGq+*R!J6m60ADwGF
zrmSerf@R?W+B5YYsETW#7Q6pR)B|Hd*YMamPkTjKlZ)mGZwrwr7a+~XMa7j)im;qF
zkX`}(^!t<~?e9oZMCEz1yvzXsswgYpbJq0LOVr9pTa4N)zpmyOIbKkb|NQs`WF|x$
zXs_fi<PB*$$c3_Jk$x%&%7a^#N@iL0;nQxgN%j2<isT}5MbE3?PZi0;JGCL|j1=9n
z>{bjW{W$*-m+C1qU)M`>qohnX&0ZnOO}@K`dA7XIIXRz=sh*pg>Ddgzbj8=YnJH5F
zVU*dLs?ZMXTWC=(-=Cljo(&#7bM1O~v?}K-O#PK7w;~6pH*TIRZ}4K$Yd1=Wm`vH~
zaE&Z266_aR)J5nPQ>pYCX&v9`wVYXoU2*Z!+#ri8j59IIov5y`Y9=hGo%)%X3(6=^
z<Q`7XT;EHkY7x_^0{sOjePM7LCH$N@YPpGoVx0}7jbx-ms{0nN@@2}PtPHgLc~{(E
zkXk{cnN<7dMw;c>e`ZQc^^~7ilRraNs+SJ$c=l!-5fy~TspRA~uTmd4MZ+d5wM)jK
zjD%xt&6fk8aGhbXSa^Wz3B|R8f;$x<P3K>U8K@&{dDG$Yro$B0<xPho72I?vzf11G
z!}=^=^XrIm?7nc4%>P1Gyil<$>&@J!E7*preJ6Y^$9yFlVCpjTt2$y4R1u3zsO5mD
zVIC@Zad#>*&|L*06;u<1e4h1@N}uAo?ksn*ollv5LHBu2YO5z=Th=avXjP#-Dqgip
zVITu$uS#9Ni`xR_4F7(|@P6qPsAc++sXm=pVFN=1EEpuTK63pBZ-cG>_Iicy`3<0*
zKQqmC8*-UjtsbubHd~#o<@)a<q(6uM{|f&9xBvN%zx&zv!@vIDzyI-n-T(UU|GfI^
jzx>B94cjs;(=sj7GJU@E{{R30|NjF3T*z{*0I~o8+tBQ~

literal 0
HcmV?d00001

diff --git a/lib/downloads/Structures_Graph-1.0.2.tgz b/lib/downloads/Structures_Graph-1.0.2.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..f46064632a7e92cb769e69e2b8aff00d70116964
GIT binary patch
literal 30947
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
T`U3y}|NjF3C*LT+09XS62!(O)

literal 0
HcmV?d00001

diff --git a/lib/downloads/UNL_DWT-0.7.1.tgz b/lib/downloads/UNL_DWT-0.7.1.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..ea461f0f0a6ab6f7869f4db86fc8ab971447165a
GIT binary patch
literal 10875
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
R009600{~A^NoWA>000G@JU;*c

literal 0
HcmV?d00001

diff --git a/lib/downloads/UNL_Templates-1.0.0RC9.tgz b/lib/downloads/UNL_Templates-1.0.0RC9.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..7f448927957b41cf887ebe982ea454a09d230aec
GIT binary patch
literal 18324
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%0A!7PRpXbMZXa#Av(N_T<w6SpK@G|(EUn-tCxgN
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

literal 0
HcmV?d00001

diff --git a/lib/downloads/XML_Util-1.2.1.tgz b/lib/downloads/XML_Util-1.2.1.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..6338719c663f60adb9de34ee5216ede56a19b712
GIT binary patch
literal 17729
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

literal 0
HcmV?d00001

diff --git a/lib/php/Archive/Tar.php b/lib/php/Archive/Tar.php
new file mode 100644
index 00000000..c32e7627
--- /dev/null
+++ b/lib/php/Archive/Tar.php
@@ -0,0 +1,1848 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * File::CSV
+ *
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) 1997-2008,
+ * Vincent Blavet <vincent@phpconcept.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.
+ *
+ * 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    File_Formats
+ * @package     Archive_Tar
+ * @author      Vincent Blavet <vincent@phpconcept.net>
+ * @copyright   1997-2008 The Authors
+ * @license     http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version     CVS: $Id: Tar.php,v 1.43 2008/10/30 17:58:42 dufuz Exp $
+ * @link        http://pear.php.net/package/Archive_Tar
+ */
+
+require_once 'PEAR.php';
+
+
+define ('ARCHIVE_TAR_ATT_SEPARATOR', 90001);
+define ('ARCHIVE_TAR_END_BLOCK', pack("a512", ''));
+
+/**
+* Creates a (compressed) Tar archive
+*
+* @author   Vincent Blavet <vincent@phpconcept.net>
+* @version  $Revision: 1.43 $
+* @license  http://www.opensource.org/licenses/bsd-license.php New BSD License
+* @package  Archive_Tar
+*/
+class Archive_Tar extends PEAR
+{
+    /**
+    * @var string Name of the Tar
+    */
+    var $_tarname='';
+
+    /**
+    * @var boolean if true, the Tar file will be gzipped
+    */
+    var $_compress=false;
+
+    /**
+    * @var string Type of compression : 'none', 'gz' or 'bz2'
+    */
+    var $_compress_type='none';
+
+    /**
+    * @var string Explode separator
+    */
+    var $_separator=' ';
+
+    /**
+    * @var file descriptor
+    */
+    var $_file=0;
+
+    /**
+    * @var string Local Tar name of a remote Tar (http:// or ftp://)
+    */
+    var $_temp_tarname='';
+
+    // {{{ constructor
+    /**
+    * Archive_Tar Class constructor. This flavour of the constructor only
+    * declare a new Archive_Tar object, identifying it by the name of the
+    * tar file.
+    * If the compress argument is set the tar will be read or created as a
+    * gzip or bz2 compressed TAR file.
+    *
+    * @param    string  $p_tarname  The name of the tar archive to create
+    * @param    string  $p_compress can be null, 'gz' or 'bz2'. This
+    *                   parameter indicates if gzip or bz2 compression
+    *                   is required.  For compatibility reason the
+    *                   boolean value 'true' means 'gz'.
+    * @access public
+    */
+    function Archive_Tar($p_tarname, $p_compress = null)
+    {
+        $this->PEAR();
+        $this->_compress = false;
+        $this->_compress_type = 'none';
+        if (($p_compress === null) || ($p_compress == '')) {
+            if (@file_exists($p_tarname)) {
+                if ($fp = @fopen($p_tarname, "rb")) {
+                    // look for gzip magic cookie
+                    $data = fread($fp, 2);
+                    fclose($fp);
+                    if ($data == "\37\213") {
+                        $this->_compress = true;
+                        $this->_compress_type = 'gz';
+                    // No sure it's enought for a magic code ....
+                    } elseif ($data == "BZ") {
+                        $this->_compress = true;
+                        $this->_compress_type = 'bz2';
+                    }
+                }
+            } else {
+                // probably a remote file or some file accessible
+                // through a stream interface
+                if (substr($p_tarname, -2) == 'gz') {
+                    $this->_compress = true;
+                    $this->_compress_type = 'gz';
+                } elseif ((substr($p_tarname, -3) == 'bz2') ||
+                          (substr($p_tarname, -2) == 'bz')) {
+                    $this->_compress = true;
+                    $this->_compress_type = 'bz2';
+                }
+            }
+        } else {
+            if (($p_compress === true) || ($p_compress == 'gz')) {
+                $this->_compress = true;
+                $this->_compress_type = 'gz';
+            } else if ($p_compress == 'bz2') {
+                $this->_compress = true;
+                $this->_compress_type = 'bz2';
+            } else {
+                die("Unsupported compression type '$p_compress'\n".
+                    "Supported types are 'gz' and 'bz2'.\n");
+                return false;
+            }
+        }
+        $this->_tarname = $p_tarname;
+        if ($this->_compress) { // assert zlib or bz2 extension support
+            if ($this->_compress_type == 'gz')
+                $extname = 'zlib';
+            else if ($this->_compress_type == 'bz2')
+                $extname = 'bz2';
+
+            if (!extension_loaded($extname)) {
+                PEAR::loadExtension($extname);
+            }
+            if (!extension_loaded($extname)) {
+                die("The extension '$extname' couldn't be found.\n".
+                    "Please make sure your version of PHP was built ".
+                    "with '$extname' support.\n");
+                return false;
+            }
+        }
+    }
+    // }}}
+
+    // {{{ destructor
+    function _Archive_Tar()
+    {
+        $this->_close();
+        // ----- Look for a local copy to delete
+        if ($this->_temp_tarname != '')
+            @unlink($this->_temp_tarname);
+        $this->_PEAR();
+    }
+    // }}}
+
+    // {{{ create()
+    /**
+    * This method creates the archive file and add the files / directories
+    * that are listed in $p_filelist.
+    * If a file with the same name exist and is writable, it is replaced
+    * by the new tar.
+    * The method return false and a PEAR error text.
+    * The $p_filelist parameter can be an array of string, each string
+    * representing a filename or a directory name with their path if
+    * needed. It can also be a single string with names separated by a
+    * single blank.
+    * For each directory added in the archive, the files and
+    * sub-directories are also added.
+    * See also createModify() method for more details.
+    *
+    * @param array  $p_filelist An array of filenames and directory names, or a
+	*                           single string with names separated by a single
+	*                           blank space.
+    * @return                   true on success, false on error.
+    * @see createModify()
+    * @access public
+    */
+    function create($p_filelist)
+    {
+        return $this->createModify($p_filelist, '', '');
+    }
+    // }}}
+
+    // {{{ add()
+    /**
+    * This method add the files / directories that are listed in $p_filelist in
+    * the archive. If the archive does not exist it is created.
+    * The method return false and a PEAR error text.
+    * The files and directories listed are only added at the end of the archive,
+    * even if a file with the same name is already archived.
+    * See also createModify() method for more details.
+    *
+    * @param array  $p_filelist An array of filenames and directory names, or a
+	*                           single string with names separated by a single
+	*                           blank space.
+    * @return                   true on success, false on error.
+    * @see createModify()
+    * @access public
+    */
+    function add($p_filelist)
+    {
+        return $this->addModify($p_filelist, '', '');
+    }
+    // }}}
+
+    // {{{ extract()
+    function extract($p_path='')
+    {
+        return $this->extractModify($p_path, '');
+    }
+    // }}}
+
+    // {{{ listContent()
+    function listContent()
+    {
+        $v_list_detail = array();
+
+        if ($this->_openRead()) {
+            if (!$this->_extractList('', $v_list_detail, "list", '', '')) {
+                unset($v_list_detail);
+                $v_list_detail = 0;
+            }
+            $this->_close();
+        }
+
+        return $v_list_detail;
+    }
+    // }}}
+
+    // {{{ createModify()
+    /**
+    * This method creates the archive file and add the files / directories
+    * that are listed in $p_filelist.
+    * If the file already exists and is writable, it is replaced by the
+    * new tar. It is a create and not an add. If the file exists and is
+    * read-only or is a directory it is not replaced. The method return
+    * false and a PEAR error text.
+    * The $p_filelist parameter can be an array of string, each string
+    * representing a filename or a directory name with their path if
+    * needed. It can also be a single string with names separated by a
+    * single blank.
+    * The path indicated in $p_remove_dir will be removed from the
+    * memorized path of each file / directory listed when this path
+    * exists. By default nothing is removed (empty path '')
+    * The path indicated in $p_add_dir will be added at the beginning of
+    * the memorized path of each file / directory listed. However it can
+    * be set to empty ''. The adding of a path is done after the removing
+    * of path.
+    * The path add/remove ability enables the user to prepare an archive
+    * for extraction in a different path than the origin files are.
+    * See also addModify() method for file adding properties.
+    *
+    * @param array  $p_filelist     An array of filenames and directory names,
+	*                               or a single string with names separated by
+	*                               a single blank space.
+    * @param string $p_add_dir      A string which contains a path to be added
+	*                               to the memorized path of each element in
+	*                               the list.
+    * @param string $p_remove_dir   A string which contains a path to be
+	*                               removed from the memorized path of each
+	*                               element in the list, when relevant.
+    * @return boolean               true on success, false on error.
+    * @access public
+    * @see addModify()
+    */
+    function createModify($p_filelist, $p_add_dir, $p_remove_dir='')
+    {
+        $v_result = true;
+
+        if (!$this->_openWrite())
+            return false;
+
+        if ($p_filelist != '') {
+            if (is_array($p_filelist))
+                $v_list = $p_filelist;
+            elseif (is_string($p_filelist))
+                $v_list = explode($this->_separator, $p_filelist);
+            else {
+                $this->_cleanFile();
+                $this->_error('Invalid file list');
+                return false;
+            }
+
+            $v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir);
+        }
+
+        if ($v_result) {
+            $this->_writeFooter();
+            $this->_close();
+        } else
+            $this->_cleanFile();
+
+        return $v_result;
+    }
+    // }}}
+
+    // {{{ addModify()
+    /**
+    * This method add the files / directories listed in $p_filelist at the
+    * end of the existing archive. If the archive does not yet exists it
+    * is created.
+    * The $p_filelist parameter can be an array of string, each string
+    * representing a filename or a directory name with their path if
+    * needed. It can also be a single string with names separated by a
+    * single blank.
+    * The path indicated in $p_remove_dir will be removed from the
+    * memorized path of each file / directory listed when this path
+    * exists. By default nothing is removed (empty path '')
+    * The path indicated in $p_add_dir will be added at the beginning of
+    * the memorized path of each file / directory listed. However it can
+    * be set to empty ''. The adding of a path is done after the removing
+    * of path.
+    * The path add/remove ability enables the user to prepare an archive
+    * for extraction in a different path than the origin files are.
+    * If a file/dir is already in the archive it will only be added at the
+    * end of the archive. There is no update of the existing archived
+    * file/dir. However while extracting the archive, the last file will
+    * replace the first one. This results in a none optimization of the
+    * archive size.
+    * If a file/dir does not exist the file/dir is ignored. However an
+    * error text is send to PEAR error.
+    * If a file/dir is not readable the file/dir is ignored. However an
+    * error text is send to PEAR error.
+    *
+    * @param array      $p_filelist     An array of filenames and directory
+	*                                   names, or a single string with names
+	*                                   separated by a single blank space.
+    * @param string     $p_add_dir      A string which contains a path to be
+	*                                   added to the memorized path of each
+	*                                   element in the list.
+    * @param string     $p_remove_dir   A string which contains a path to be
+	*                                   removed from the memorized path of
+	*                                   each element in the list, when
+    *                                   relevant.
+    * @return                           true on success, false on error.
+    * @access public
+    */
+    function addModify($p_filelist, $p_add_dir, $p_remove_dir='')
+    {
+        $v_result = true;
+
+        if (!$this->_isArchive())
+            $v_result = $this->createModify($p_filelist, $p_add_dir,
+			                                $p_remove_dir);
+        else {
+            if (is_array($p_filelist))
+                $v_list = $p_filelist;
+            elseif (is_string($p_filelist))
+                $v_list = explode($this->_separator, $p_filelist);
+            else {
+                $this->_error('Invalid file list');
+                return false;
+            }
+
+            $v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir);
+        }
+
+        return $v_result;
+    }
+    // }}}
+
+    // {{{ addString()
+    /**
+    * This method add a single string as a file at the
+    * end of the existing archive. If the archive does not yet exists it
+    * is created.
+    *
+    * @param string     $p_filename     A string which contains the full
+	*                                   filename path that will be associated
+	*                                   with the string.
+    * @param string     $p_string       The content of the file added in
+	*                                   the archive.
+    * @return                           true on success, false on error.
+    * @access public
+    */
+    function addString($p_filename, $p_string)
+    {
+        $v_result = true;
+
+        if (!$this->_isArchive()) {
+            if (!$this->_openWrite()) {
+                return false;
+            }
+            $this->_close();
+        }
+
+        if (!$this->_openAppend())
+            return false;
+
+        // Need to check the get back to the temporary file ? ....
+        $v_result = $this->_addString($p_filename, $p_string);
+
+        $this->_writeFooter();
+
+        $this->_close();
+
+        return $v_result;
+    }
+    // }}}
+
+    // {{{ extractModify()
+    /**
+    * This method extract all the content of the archive in the directory
+    * indicated by $p_path. When relevant the memorized path of the
+    * files/dir can be modified by removing the $p_remove_path path at the
+    * beginning of the file/dir path.
+    * While extracting a file, if the directory path does not exists it is
+    * created.
+    * While extracting a file, if the file already exists it is replaced
+    * without looking for last modification date.
+    * While extracting a file, if the file already exists and is write
+    * protected, the extraction is aborted.
+    * While extracting a file, if a directory with the same name already
+    * exists, the extraction is aborted.
+    * While extracting a directory, if a file with the same name already
+    * exists, the extraction is aborted.
+    * While extracting a file/directory if the destination directory exist
+    * and is write protected, or does not exist but can not be created,
+    * the extraction is aborted.
+    * If after extraction an extracted file does not show the correct
+    * stored file size, the extraction is aborted.
+    * When the extraction is aborted, a PEAR error text is set and false
+    * is returned. However the result can be a partial extraction that may
+    * need to be manually cleaned.
+    *
+    * @param string $p_path         The path of the directory where the
+	*                               files/dir need to by extracted.
+    * @param string $p_remove_path  Part of the memorized path that can be
+	*                               removed if present at the beginning of
+	*                               the file/dir path.
+    * @return boolean               true on success, false on error.
+    * @access public
+    * @see extractList()
+    */
+    function extractModify($p_path, $p_remove_path)
+    {
+        $v_result = true;
+        $v_list_detail = array();
+
+        if ($v_result = $this->_openRead()) {
+            $v_result = $this->_extractList($p_path, $v_list_detail,
+			                                "complete", 0, $p_remove_path);
+            $this->_close();
+        }
+
+        return $v_result;
+    }
+    // }}}
+
+    // {{{ extractInString()
+    /**
+    * This method extract from the archive one file identified by $p_filename.
+    * The return value is a string with the file content, or NULL on error.
+    * @param string $p_filename     The path of the file to extract in a string.
+    * @return                       a string with the file content or NULL.
+    * @access public
+    */
+    function extractInString($p_filename)
+    {
+        if ($this->_openRead()) {
+            $v_result = $this->_extractInString($p_filename);
+            $this->_close();
+        } else {
+            $v_result = NULL;
+        }
+
+        return $v_result;
+    }
+    // }}}
+
+    // {{{ extractList()
+    /**
+    * This method extract from the archive only the files indicated in the
+    * $p_filelist. These files are extracted in the current directory or
+    * in the directory indicated by the optional $p_path parameter.
+    * If indicated the $p_remove_path can be used in the same way as it is
+    * used in extractModify() method.
+    * @param array  $p_filelist     An array of filenames and directory names,
+	*                               or a single string with names separated
+	*                               by a single blank space.
+    * @param string $p_path         The path of the directory where the
+	*                               files/dir need to by extracted.
+    * @param string $p_remove_path  Part of the memorized path that can be
+	*                               removed if present at the beginning of
+	*                               the file/dir path.
+    * @return                       true on success, false on error.
+    * @access public
+    * @see extractModify()
+    */
+    function extractList($p_filelist, $p_path='', $p_remove_path='')
+    {
+        $v_result = true;
+        $v_list_detail = array();
+
+        if (is_array($p_filelist))
+            $v_list = $p_filelist;
+        elseif (is_string($p_filelist))
+            $v_list = explode($this->_separator, $p_filelist);
+        else {
+            $this->_error('Invalid string list');
+            return false;
+        }
+
+        if ($v_result = $this->_openRead()) {
+            $v_result = $this->_extractList($p_path, $v_list_detail, "partial",
+			                                $v_list, $p_remove_path);
+            $this->_close();
+        }
+
+        return $v_result;
+    }
+    // }}}
+
+    // {{{ setAttribute()
+    /**
+    * This method set specific attributes of the archive. It uses a variable
+    * list of parameters, in the format attribute code + attribute values :
+    * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ',');
+    * @param mixed $argv            variable list of attributes and values
+    * @return                       true on success, false on error.
+    * @access public
+    */
+    function setAttribute()
+    {
+        $v_result = true;
+
+        // ----- Get the number of variable list of arguments
+        if (($v_size = func_num_args()) == 0) {
+            return true;
+        }
+
+        // ----- Get the arguments
+        $v_att_list = &func_get_args();
+
+        // ----- Read the attributes
+        $i=0;
+        while ($i<$v_size) {
+
+            // ----- Look for next option
+            switch ($v_att_list[$i]) {
+                // ----- Look for options that request a string value
+                case ARCHIVE_TAR_ATT_SEPARATOR :
+                    // ----- Check the number of parameters
+                    if (($i+1) >= $v_size) {
+                        $this->_error('Invalid number of parameters for '
+						              .'attribute ARCHIVE_TAR_ATT_SEPARATOR');
+                        return false;
+                    }
+
+                    // ----- Get the value
+                    $this->_separator = $v_att_list[$i+1];
+                    $i++;
+                break;
+
+                default :
+                    $this->_error('Unknow attribute code '.$v_att_list[$i].'');
+                    return false;
+            }
+
+            // ----- Next attribute
+            $i++;
+        }
+
+        return $v_result;
+    }
+    // }}}
+
+    // {{{ _error()
+    function _error($p_message)
+    {
+        // ----- To be completed
+        $this->raiseError($p_message);
+    }
+    // }}}
+
+    // {{{ _warning()
+    function _warning($p_message)
+    {
+        // ----- To be completed
+        $this->raiseError($p_message);
+    }
+    // }}}
+
+    // {{{ _isArchive()
+    function _isArchive($p_filename=NULL)
+    {
+        if ($p_filename == NULL) {
+            $p_filename = $this->_tarname;
+        }
+        clearstatcache();
+        return @is_file($p_filename) && !@is_link($p_filename);
+    }
+    // }}}
+
+    // {{{ _openWrite()
+    function _openWrite()
+    {
+        if ($this->_compress_type == 'gz')
+            $this->_file = @gzopen($this->_tarname, "wb9");
+        else if ($this->_compress_type == 'bz2')
+            $this->_file = @bzopen($this->_tarname, "w");
+        else if ($this->_compress_type == 'none')
+            $this->_file = @fopen($this->_tarname, "wb");
+        else
+            $this->_error('Unknown or missing compression type ('
+			              .$this->_compress_type.')');
+
+        if ($this->_file == 0) {
+            $this->_error('Unable to open in write mode \''
+			              .$this->_tarname.'\'');
+            return false;
+        }
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _openRead()
+    function _openRead()
+    {
+        if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') {
+
+          // ----- Look if a local copy need to be done
+          if ($this->_temp_tarname == '') {
+              $this->_temp_tarname = uniqid('tar').'.tmp';
+              if (!$v_file_from = @fopen($this->_tarname, 'rb')) {
+                $this->_error('Unable to open in read mode \''
+				              .$this->_tarname.'\'');
+                $this->_temp_tarname = '';
+                return false;
+              }
+              if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) {
+                $this->_error('Unable to open in write mode \''
+				              .$this->_temp_tarname.'\'');
+                $this->_temp_tarname = '';
+                return false;
+              }
+              while ($v_data = @fread($v_file_from, 1024))
+                  @fwrite($v_file_to, $v_data);
+              @fclose($v_file_from);
+              @fclose($v_file_to);
+          }
+
+          // ----- File to open if the local copy
+          $v_filename = $this->_temp_tarname;
+
+        } else
+          // ----- File to open if the normal Tar file
+          $v_filename = $this->_tarname;
+
+        if ($this->_compress_type == 'gz')
+            $this->_file = @gzopen($v_filename, "rb");
+        else if ($this->_compress_type == 'bz2')
+            $this->_file = @bzopen($v_filename, "r");
+        else if ($this->_compress_type == 'none')
+            $this->_file = @fopen($v_filename, "rb");
+        else
+            $this->_error('Unknown or missing compression type ('
+			              .$this->_compress_type.')');
+
+        if ($this->_file == 0) {
+            $this->_error('Unable to open in read mode \''.$v_filename.'\'');
+            return false;
+        }
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _openReadWrite()
+    function _openReadWrite()
+    {
+        if ($this->_compress_type == 'gz')
+            $this->_file = @gzopen($this->_tarname, "r+b");
+        else if ($this->_compress_type == 'bz2') {
+            $this->_error('Unable to open bz2 in read/write mode \''
+			              .$this->_tarname.'\' (limitation of bz2 extension)');
+            return false;
+        } else if ($this->_compress_type == 'none')
+            $this->_file = @fopen($this->_tarname, "r+b");
+        else
+            $this->_error('Unknown or missing compression type ('
+			              .$this->_compress_type.')');
+
+        if ($this->_file == 0) {
+            $this->_error('Unable to open in read/write mode \''
+			              .$this->_tarname.'\'');
+            return false;
+        }
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _close()
+    function _close()
+    {
+        //if (isset($this->_file)) {
+        if (is_resource($this->_file)) {
+            if ($this->_compress_type == 'gz')
+                @gzclose($this->_file);
+            else if ($this->_compress_type == 'bz2')
+                @bzclose($this->_file);
+            else if ($this->_compress_type == 'none')
+                @fclose($this->_file);
+            else
+                $this->_error('Unknown or missing compression type ('
+				              .$this->_compress_type.')');
+
+            $this->_file = 0;
+        }
+
+        // ----- Look if a local copy need to be erase
+        // Note that it might be interesting to keep the url for a time : ToDo
+        if ($this->_temp_tarname != '') {
+            @unlink($this->_temp_tarname);
+            $this->_temp_tarname = '';
+        }
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _cleanFile()
+    function _cleanFile()
+    {
+        $this->_close();
+
+        // ----- Look for a local copy
+        if ($this->_temp_tarname != '') {
+            // ----- Remove the local copy but not the remote tarname
+            @unlink($this->_temp_tarname);
+            $this->_temp_tarname = '';
+        } else {
+            // ----- Remove the local tarname file
+            @unlink($this->_tarname);
+        }
+        $this->_tarname = '';
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _writeBlock()
+    function _writeBlock($p_binary_data, $p_len=null)
+    {
+      if (is_resource($this->_file)) {
+          if ($p_len === null) {
+              if ($this->_compress_type == 'gz')
+                  @gzputs($this->_file, $p_binary_data);
+              else if ($this->_compress_type == 'bz2')
+                  @bzwrite($this->_file, $p_binary_data);
+              else if ($this->_compress_type == 'none')
+                  @fputs($this->_file, $p_binary_data);
+              else
+                  $this->_error('Unknown or missing compression type ('
+				                .$this->_compress_type.')');
+          } else {
+              if ($this->_compress_type == 'gz')
+                  @gzputs($this->_file, $p_binary_data, $p_len);
+              else if ($this->_compress_type == 'bz2')
+                  @bzwrite($this->_file, $p_binary_data, $p_len);
+              else if ($this->_compress_type == 'none')
+                  @fputs($this->_file, $p_binary_data, $p_len);
+              else
+                  $this->_error('Unknown or missing compression type ('
+				                .$this->_compress_type.')');
+
+          }
+      }
+      return true;
+    }
+    // }}}
+
+    // {{{ _readBlock()
+    function _readBlock()
+    {
+      $v_block = null;
+      if (is_resource($this->_file)) {
+          if ($this->_compress_type == 'gz')
+              $v_block = @gzread($this->_file, 512);
+          else if ($this->_compress_type == 'bz2')
+              $v_block = @bzread($this->_file, 512);
+          else if ($this->_compress_type == 'none')
+              $v_block = @fread($this->_file, 512);
+          else
+              $this->_error('Unknown or missing compression type ('
+			                .$this->_compress_type.')');
+      }
+      return $v_block;
+    }
+    // }}}
+
+    // {{{ _jumpBlock()
+    function _jumpBlock($p_len=null)
+    {
+      if (is_resource($this->_file)) {
+          if ($p_len === null)
+              $p_len = 1;
+
+          if ($this->_compress_type == 'gz') {
+              @gzseek($this->_file, gztell($this->_file)+($p_len*512));
+          }
+          else if ($this->_compress_type == 'bz2') {
+              // ----- Replace missing bztell() and bzseek()
+              for ($i=0; $i<$p_len; $i++)
+                  $this->_readBlock();
+          } else if ($this->_compress_type == 'none')
+              @fseek($this->_file, ftell($this->_file)+($p_len*512));
+          else
+              $this->_error('Unknown or missing compression type ('
+			                .$this->_compress_type.')');
+
+      }
+      return true;
+    }
+    // }}}
+
+    // {{{ _writeFooter()
+    function _writeFooter()
+    {
+      if (is_resource($this->_file)) {
+          // ----- Write the last 0 filled block for end of archive
+          $v_binary_data = pack('a1024', '');
+          $this->_writeBlock($v_binary_data);
+      }
+      return true;
+    }
+    // }}}
+
+    // {{{ _addList()
+    function _addList($p_list, $p_add_dir, $p_remove_dir)
+    {
+      $v_result=true;
+      $v_header = array();
+
+      // ----- Remove potential windows directory separator
+      $p_add_dir = $this->_translateWinPath($p_add_dir);
+      $p_remove_dir = $this->_translateWinPath($p_remove_dir, false);
+
+      if (!$this->_file) {
+          $this->_error('Invalid file descriptor');
+          return false;
+      }
+
+      if (sizeof($p_list) == 0)
+          return true;
+
+      foreach ($p_list as $v_filename) {
+          if (!$v_result) {
+              break;
+          }
+
+        // ----- Skip the current tar name
+        if ($v_filename == $this->_tarname)
+            continue;
+
+        if ($v_filename == '')
+            continue;
+
+        if (!file_exists($v_filename)) {
+            $this->_warning("File '$v_filename' does not exist");
+            continue;
+        }
+
+        // ----- Add the file or directory header
+        if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir))
+            return false;
+
+        if (@is_dir($v_filename) && !@is_link($v_filename)) {
+            if (!($p_hdir = opendir($v_filename))) {
+                $this->_warning("Directory '$v_filename' can not be read");
+                continue;
+            }
+            while (false !== ($p_hitem = readdir($p_hdir))) {
+                if (($p_hitem != '.') && ($p_hitem != '..')) {
+                    if ($v_filename != ".")
+                        $p_temp_list[0] = $v_filename.'/'.$p_hitem;
+                    else
+                        $p_temp_list[0] = $p_hitem;
+
+                    $v_result = $this->_addList($p_temp_list,
+					                            $p_add_dir,
+												$p_remove_dir);
+                }
+            }
+
+            unset($p_temp_list);
+            unset($p_hdir);
+            unset($p_hitem);
+        }
+      }
+
+      return $v_result;
+    }
+    // }}}
+
+    // {{{ _addFile()
+    function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir)
+    {
+      if (!$this->_file) {
+          $this->_error('Invalid file descriptor');
+          return false;
+      }
+
+      if ($p_filename == '') {
+          $this->_error('Invalid file name');
+          return false;
+      }
+
+      // ----- Calculate the stored filename
+      $p_filename = $this->_translateWinPath($p_filename, false);;
+      $v_stored_filename = $p_filename;
+      if (strcmp($p_filename, $p_remove_dir) == 0) {
+          return true;
+      }
+      if ($p_remove_dir != '') {
+          if (substr($p_remove_dir, -1) != '/')
+              $p_remove_dir .= '/';
+
+          if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
+              $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
+      }
+      $v_stored_filename = $this->_translateWinPath($v_stored_filename);
+      if ($p_add_dir != '') {
+          if (substr($p_add_dir, -1) == '/')
+              $v_stored_filename = $p_add_dir.$v_stored_filename;
+          else
+              $v_stored_filename = $p_add_dir.'/'.$v_stored_filename;
+      }
+
+      $v_stored_filename = $this->_pathReduction($v_stored_filename);
+
+      if ($this->_isArchive($p_filename)) {
+          if (($v_file = @fopen($p_filename, "rb")) == 0) {
+              $this->_warning("Unable to open file '".$p_filename
+			                  ."' in binary read mode");
+              return true;
+          }
+
+          if (!$this->_writeHeader($p_filename, $v_stored_filename))
+              return false;
+
+          while (($v_buffer = fread($v_file, 512)) != '') {
+              $v_binary_data = pack("a512", "$v_buffer");
+              $this->_writeBlock($v_binary_data);
+          }
+
+          fclose($v_file);
+
+      } else {
+          // ----- Only header for dir
+          if (!$this->_writeHeader($p_filename, $v_stored_filename))
+              return false;
+      }
+
+      return true;
+    }
+    // }}}
+
+    // {{{ _addString()
+    function _addString($p_filename, $p_string)
+    {
+      if (!$this->_file) {
+          $this->_error('Invalid file descriptor');
+          return false;
+      }
+
+      if ($p_filename == '') {
+          $this->_error('Invalid file name');
+          return false;
+      }
+
+      // ----- Calculate the stored filename
+      $p_filename = $this->_translateWinPath($p_filename, false);;
+
+      if (!$this->_writeHeaderBlock($p_filename, strlen($p_string),
+	                                  time(), 384, "", 0, 0))
+          return false;
+
+      $i=0;
+      while (($v_buffer = substr($p_string, (($i++)*512), 512)) != '') {
+          $v_binary_data = pack("a512", $v_buffer);
+          $this->_writeBlock($v_binary_data);
+      }
+
+      return true;
+    }
+    // }}}
+
+    // {{{ _writeHeader()
+    function _writeHeader($p_filename, $p_stored_filename)
+    {
+        if ($p_stored_filename == '')
+            $p_stored_filename = $p_filename;
+        $v_reduce_filename = $this->_pathReduction($p_stored_filename);
+
+        if (strlen($v_reduce_filename) > 99) {
+          if (!$this->_writeLongHeader($v_reduce_filename))
+            return false;
+        }
+
+        $v_info = lstat($p_filename);
+        $v_uid = sprintf("%6s ", DecOct($v_info[4]));
+        $v_gid = sprintf("%6s ", DecOct($v_info[5]));
+        $v_perms = sprintf("%6s ", DecOct($v_info['mode']));
+
+        $v_mtime = sprintf("%11s", DecOct($v_info['mode']));
+
+        $v_linkname = '';
+
+        if (@is_link($p_filename)) {
+          $v_typeflag = '2';
+          $v_linkname = readlink($p_filename);
+          $v_size = sprintf("%11s ", DecOct(0));
+        } elseif (@is_dir($p_filename)) {
+          $v_typeflag = "5";
+          $v_size = sprintf("%11s ", DecOct(0));
+        } else {
+          $v_typeflag = '';
+          clearstatcache();
+          $v_size = sprintf("%11s ", DecOct($v_info['size']));
+        }
+
+        $v_magic = '';
+
+        $v_version = '';
+
+        $v_uname = '';
+
+        $v_gname = '';
+
+        $v_devmajor = '';
+
+        $v_devminor = '';
+
+        $v_prefix = '';
+
+        $v_binary_data_first = pack("a100a8a8a8a12A12",
+		                            $v_reduce_filename, $v_perms, $v_uid,
+									$v_gid, $v_size, $v_mtime);
+        $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12",
+		                           $v_typeflag, $v_linkname, $v_magic,
+								   $v_version, $v_uname, $v_gname,
+								   $v_devmajor, $v_devminor, $v_prefix, '');
+
+        // ----- Calculate the checksum
+        $v_checksum = 0;
+        // ..... First part of the header
+        for ($i=0; $i<148; $i++)
+            $v_checksum += ord(substr($v_binary_data_first,$i,1));
+        // ..... Ignore the checksum value and replace it by ' ' (space)
+        for ($i=148; $i<156; $i++)
+            $v_checksum += ord(' ');
+        // ..... Last part of the header
+        for ($i=156, $j=0; $i<512; $i++, $j++)
+            $v_checksum += ord(substr($v_binary_data_last,$j,1));
+
+        // ----- Write the first 148 bytes of the header in the archive
+        $this->_writeBlock($v_binary_data_first, 148);
+
+        // ----- Write the calculated checksum
+        $v_checksum = sprintf("%6s ", DecOct($v_checksum));
+        $v_binary_data = pack("a8", $v_checksum);
+        $this->_writeBlock($v_binary_data, 8);
+
+        // ----- Write the last 356 bytes of the header in the archive
+        $this->_writeBlock($v_binary_data_last, 356);
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _writeHeaderBlock()
+    function _writeHeaderBlock($p_filename, $p_size, $p_mtime=0, $p_perms=0,
+	                           $p_type='', $p_uid=0, $p_gid=0)
+    {
+        $p_filename = $this->_pathReduction($p_filename);
+
+        if (strlen($p_filename) > 99) {
+          if (!$this->_writeLongHeader($p_filename))
+            return false;
+        }
+
+        if ($p_type == "5") {
+          $v_size = sprintf("%11s ", DecOct(0));
+        } else {
+          $v_size = sprintf("%11s ", DecOct($p_size));
+        }
+
+        $v_uid = sprintf("%6s ", DecOct($p_uid));
+        $v_gid = sprintf("%6s ", DecOct($p_gid));
+        $v_perms = sprintf("%6s ", DecOct($p_perms));
+
+        $v_mtime = sprintf("%11s", DecOct($p_mtime));
+
+        $v_linkname = '';
+
+        $v_magic = '';
+
+        $v_version = '';
+
+        $v_uname = '';
+
+        $v_gname = '';
+
+        $v_devmajor = '';
+
+        $v_devminor = '';
+
+        $v_prefix = '';
+
+        $v_binary_data_first = pack("a100a8a8a8a12A12",
+		                            $p_filename, $v_perms, $v_uid, $v_gid,
+									$v_size, $v_mtime);
+        $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12",
+		                           $p_type, $v_linkname, $v_magic,
+								   $v_version, $v_uname, $v_gname,
+								   $v_devmajor, $v_devminor, $v_prefix, '');
+
+        // ----- Calculate the checksum
+        $v_checksum = 0;
+        // ..... First part of the header
+        for ($i=0; $i<148; $i++)
+            $v_checksum += ord(substr($v_binary_data_first,$i,1));
+        // ..... Ignore the checksum value and replace it by ' ' (space)
+        for ($i=148; $i<156; $i++)
+            $v_checksum += ord(' ');
+        // ..... Last part of the header
+        for ($i=156, $j=0; $i<512; $i++, $j++)
+            $v_checksum += ord(substr($v_binary_data_last,$j,1));
+
+        // ----- Write the first 148 bytes of the header in the archive
+        $this->_writeBlock($v_binary_data_first, 148);
+
+        // ----- Write the calculated checksum
+        $v_checksum = sprintf("%6s ", DecOct($v_checksum));
+        $v_binary_data = pack("a8", $v_checksum);
+        $this->_writeBlock($v_binary_data, 8);
+
+        // ----- Write the last 356 bytes of the header in the archive
+        $this->_writeBlock($v_binary_data_last, 356);
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _writeLongHeader()
+    function _writeLongHeader($p_filename)
+    {
+        $v_size = sprintf("%11s ", DecOct(strlen($p_filename)));
+
+        $v_typeflag = 'L';
+
+        $v_linkname = '';
+
+        $v_magic = '';
+
+        $v_version = '';
+
+        $v_uname = '';
+
+        $v_gname = '';
+
+        $v_devmajor = '';
+
+        $v_devminor = '';
+
+        $v_prefix = '';
+
+        $v_binary_data_first = pack("a100a8a8a8a12A12",
+		                            '././@LongLink', 0, 0, 0, $v_size, 0);
+        $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12",
+		                           $v_typeflag, $v_linkname, $v_magic,
+								   $v_version, $v_uname, $v_gname,
+								   $v_devmajor, $v_devminor, $v_prefix, '');
+
+        // ----- Calculate the checksum
+        $v_checksum = 0;
+        // ..... First part of the header
+        for ($i=0; $i<148; $i++)
+            $v_checksum += ord(substr($v_binary_data_first,$i,1));
+        // ..... Ignore the checksum value and replace it by ' ' (space)
+        for ($i=148; $i<156; $i++)
+            $v_checksum += ord(' ');
+        // ..... Last part of the header
+        for ($i=156, $j=0; $i<512; $i++, $j++)
+            $v_checksum += ord(substr($v_binary_data_last,$j,1));
+
+        // ----- Write the first 148 bytes of the header in the archive
+        $this->_writeBlock($v_binary_data_first, 148);
+
+        // ----- Write the calculated checksum
+        $v_checksum = sprintf("%6s ", DecOct($v_checksum));
+        $v_binary_data = pack("a8", $v_checksum);
+        $this->_writeBlock($v_binary_data, 8);
+
+        // ----- Write the last 356 bytes of the header in the archive
+        $this->_writeBlock($v_binary_data_last, 356);
+
+        // ----- Write the filename as content of the block
+        $i=0;
+        while (($v_buffer = substr($p_filename, (($i++)*512), 512)) != '') {
+            $v_binary_data = pack("a512", "$v_buffer");
+            $this->_writeBlock($v_binary_data);
+        }
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _readHeader()
+    function _readHeader($v_binary_data, &$v_header)
+    {
+        if (strlen($v_binary_data)==0) {
+            $v_header['filename'] = '';
+            return true;
+        }
+
+        if (strlen($v_binary_data) != 512) {
+            $v_header['filename'] = '';
+            $this->_error('Invalid block size : '.strlen($v_binary_data));
+            return false;
+        }
+
+        if (!is_array($v_header)) {
+            $v_header = array();
+        }
+        // ----- Calculate the checksum
+        $v_checksum = 0;
+        // ..... First part of the header
+        for ($i=0; $i<148; $i++)
+            $v_checksum+=ord(substr($v_binary_data,$i,1));
+        // ..... Ignore the checksum value and replace it by ' ' (space)
+        for ($i=148; $i<156; $i++)
+            $v_checksum += ord(' ');
+        // ..... Last part of the header
+        for ($i=156; $i<512; $i++)
+           $v_checksum+=ord(substr($v_binary_data,$i,1));
+
+        $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/"
+		                 ."a8checksum/a1typeflag/a100link/a6magic/a2version/"
+						 ."a32uname/a32gname/a8devmajor/a8devminor",
+						 $v_binary_data);
+
+        // ----- Extract the checksum
+        $v_header['checksum'] = OctDec(trim($v_data['checksum']));
+        if ($v_header['checksum'] != $v_checksum) {
+            $v_header['filename'] = '';
+
+            // ----- Look for last block (empty block)
+            if (($v_checksum == 256) && ($v_header['checksum'] == 0))
+                return true;
+
+            $this->_error('Invalid checksum for file "'.$v_data['filename']
+			              .'" : '.$v_checksum.' calculated, '
+						  .$v_header['checksum'].' expected');
+            return false;
+        }
+
+        // ----- Extract the properties
+        $v_header['filename'] = trim($v_data['filename']);
+        if ($this->_maliciousFilename($v_header['filename'])) {
+            $this->_error('Malicious .tar detected, file "' . $v_header['filename'] .
+                '" will not install in desired directory tree');
+            return false;
+        }
+        $v_header['mode'] = OctDec(trim($v_data['mode']));
+        $v_header['uid'] = OctDec(trim($v_data['uid']));
+        $v_header['gid'] = OctDec(trim($v_data['gid']));
+        $v_header['size'] = OctDec(trim($v_data['size']));
+        $v_header['mtime'] = OctDec(trim($v_data['mtime']));
+        if (($v_header['typeflag'] = $v_data['typeflag']) == "5") {
+          $v_header['size'] = 0;
+        }
+        $v_header['link'] = trim($v_data['link']);
+        /* ----- All these fields are removed form the header because
+		they do not carry interesting info
+        $v_header[magic] = trim($v_data[magic]);
+        $v_header[version] = trim($v_data[version]);
+        $v_header[uname] = trim($v_data[uname]);
+        $v_header[gname] = trim($v_data[gname]);
+        $v_header[devmajor] = trim($v_data[devmajor]);
+        $v_header[devminor] = trim($v_data[devminor]);
+        */
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _maliciousFilename()
+    /**
+     * Detect and report a malicious file name
+     *
+     * @param string $file
+     * @return bool
+     * @access private
+     */
+    function _maliciousFilename($file)
+    {
+        if (strpos($file, '/../') !== false) {
+            return true;
+        }
+        if (strpos($file, '../') === 0) {
+            return true;
+        }
+        return false;
+    }
+    // }}}
+
+    // {{{ _readLongHeader()
+    function _readLongHeader(&$v_header)
+    {
+      $v_filename = '';
+      $n = floor($v_header['size']/512);
+      for ($i=0; $i<$n; $i++) {
+        $v_content = $this->_readBlock();
+        $v_filename .= $v_content;
+      }
+      if (($v_header['size'] % 512) != 0) {
+        $v_content = $this->_readBlock();
+        $v_filename .= $v_content;
+      }
+
+      // ----- Read the next header
+      $v_binary_data = $this->_readBlock();
+
+      if (!$this->_readHeader($v_binary_data, $v_header))
+        return false;
+
+      $v_filename = trim($v_filename);
+      $v_header['filename'] = $v_filename;
+        if ($this->_maliciousFilename($v_filename)) {
+            $this->_error('Malicious .tar detected, file "' . $v_filename .
+                '" will not install in desired directory tree');
+            return false;
+      }
+
+      return true;
+    }
+    // }}}
+
+    // {{{ _extractInString()
+    /**
+    * This method extract from the archive one file identified by $p_filename.
+    * The return value is a string with the file content, or NULL on error.
+    * @param string $p_filename     The path of the file to extract in a string.
+    * @return                       a string with the file content or NULL.
+    * @access private
+    */
+    function _extractInString($p_filename)
+    {
+        $v_result_str = "";
+
+        While (strlen($v_binary_data = $this->_readBlock()) != 0)
+        {
+          if (!$this->_readHeader($v_binary_data, $v_header))
+            return NULL;
+
+          if ($v_header['filename'] == '')
+            continue;
+
+          // ----- Look for long filename
+          if ($v_header['typeflag'] == 'L') {
+            if (!$this->_readLongHeader($v_header))
+              return NULL;
+          }
+
+          if ($v_header['filename'] == $p_filename) {
+              if ($v_header['typeflag'] == "5") {
+                  $this->_error('Unable to extract in string a directory '
+				                .'entry {'.$v_header['filename'].'}');
+                  return NULL;
+              } else {
+                  $n = floor($v_header['size']/512);
+                  for ($i=0; $i<$n; $i++) {
+                      $v_result_str .= $this->_readBlock();
+                  }
+                  if (($v_header['size'] % 512) != 0) {
+                      $v_content = $this->_readBlock();
+                      $v_result_str .= substr($v_content, 0,
+					                          ($v_header['size'] % 512));
+                  }
+                  return $v_result_str;
+              }
+          } else {
+              $this->_jumpBlock(ceil(($v_header['size']/512)));
+          }
+        }
+
+        return NULL;
+    }
+    // }}}
+
+    // {{{ _extractList()
+    function _extractList($p_path, &$p_list_detail, $p_mode,
+	                      $p_file_list, $p_remove_path)
+    {
+    $v_result=true;
+    $v_nb = 0;
+    $v_extract_all = true;
+    $v_listing = false;
+
+    $p_path = $this->_translateWinPath($p_path, false);
+    if ($p_path == '' || (substr($p_path, 0, 1) != '/'
+	    && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':'))) {
+      $p_path = "./".$p_path;
+    }
+    $p_remove_path = $this->_translateWinPath($p_remove_path);
+
+    // ----- Look for path to remove format (should end by /)
+    if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/'))
+      $p_remove_path .= '/';
+    $p_remove_path_size = strlen($p_remove_path);
+
+    switch ($p_mode) {
+      case "complete" :
+        $v_extract_all = TRUE;
+        $v_listing = FALSE;
+      break;
+      case "partial" :
+          $v_extract_all = FALSE;
+          $v_listing = FALSE;
+      break;
+      case "list" :
+          $v_extract_all = FALSE;
+          $v_listing = TRUE;
+      break;
+      default :
+        $this->_error('Invalid extract mode ('.$p_mode.')');
+        return false;
+    }
+
+    clearstatcache();
+
+    while (strlen($v_binary_data = $this->_readBlock()) != 0)
+    {
+      $v_extract_file = FALSE;
+      $v_extraction_stopped = 0;
+
+      if (!$this->_readHeader($v_binary_data, $v_header))
+        return false;
+
+      if ($v_header['filename'] == '') {
+        continue;
+      }
+
+      // ----- Look for long filename
+      if ($v_header['typeflag'] == 'L') {
+        if (!$this->_readLongHeader($v_header))
+          return false;
+      }
+
+      if ((!$v_extract_all) && (is_array($p_file_list))) {
+        // ----- By default no unzip if the file is not found
+        $v_extract_file = false;
+
+        for ($i=0; $i<sizeof($p_file_list); $i++) {
+          // ----- Look if it is a directory
+          if (substr($p_file_list[$i], -1) == '/') {
+            // ----- Look if the directory is in the filename path
+            if ((strlen($v_header['filename']) > strlen($p_file_list[$i]))
+			    && (substr($v_header['filename'], 0, strlen($p_file_list[$i]))
+				    == $p_file_list[$i])) {
+              $v_extract_file = TRUE;
+              break;
+            }
+          }
+
+          // ----- It is a file, so compare the file names
+          elseif ($p_file_list[$i] == $v_header['filename']) {
+            $v_extract_file = TRUE;
+            break;
+          }
+        }
+      } else {
+        $v_extract_file = TRUE;
+      }
+
+      // ----- Look if this file need to be extracted
+      if (($v_extract_file) && (!$v_listing))
+      {
+        if (($p_remove_path != '')
+            && (substr($v_header['filename'], 0, $p_remove_path_size)
+			    == $p_remove_path))
+          $v_header['filename'] = substr($v_header['filename'],
+		                                 $p_remove_path_size);
+        if (($p_path != './') && ($p_path != '/')) {
+          while (substr($p_path, -1) == '/')
+            $p_path = substr($p_path, 0, strlen($p_path)-1);
+
+          if (substr($v_header['filename'], 0, 1) == '/')
+              $v_header['filename'] = $p_path.$v_header['filename'];
+          else
+            $v_header['filename'] = $p_path.'/'.$v_header['filename'];
+        }
+        if (file_exists($v_header['filename'])) {
+          if (   (@is_dir($v_header['filename']))
+		      && ($v_header['typeflag'] == '')) {
+            $this->_error('File '.$v_header['filename']
+			              .' already exists as a directory');
+            return false;
+          }
+          if (   ($this->_isArchive($v_header['filename']))
+		      && ($v_header['typeflag'] == "5")) {
+            $this->_error('Directory '.$v_header['filename']
+			              .' already exists as a file');
+            return false;
+          }
+          if (!is_writeable($v_header['filename'])) {
+            $this->_error('File '.$v_header['filename']
+			              .' already exists and is write protected');
+            return false;
+          }
+          if (filemtime($v_header['filename']) > $v_header['mtime']) {
+            // To be completed : An error or silent no replace ?
+          }
+        }
+
+        // ----- Check the directory availability and create it if necessary
+        elseif (($v_result
+		         = $this->_dirCheck(($v_header['typeflag'] == "5"
+				                    ?$v_header['filename']
+									:dirname($v_header['filename'])))) != 1) {
+            $this->_error('Unable to create path for '.$v_header['filename']);
+            return false;
+        }
+
+        if ($v_extract_file) {
+          if ($v_header['typeflag'] == "5") {
+            if (!@file_exists($v_header['filename'])) {
+                if (!@mkdir($v_header['filename'], 0777)) {
+                    $this->_error('Unable to create directory {'
+					              .$v_header['filename'].'}');
+                    return false;
+                }
+            }
+          } elseif ($v_header['typeflag'] == "2") {
+              if (@file_exists($v_header['filename'])) {
+                  @unlink($v_header['filename']);
+              }
+              if (!@symlink($v_header['link'], $v_header['filename'])) {
+                  $this->_error('Unable to extract symbolic link {'
+                                .$v_header['filename'].'}');
+                  return false;
+              }
+          } else {
+              if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) {
+                  $this->_error('Error while opening {'.$v_header['filename']
+				                .'} in write binary mode');
+                  return false;
+              } else {
+                  $n = floor($v_header['size']/512);
+                  for ($i=0; $i<$n; $i++) {
+                      $v_content = $this->_readBlock();
+                      fwrite($v_dest_file, $v_content, 512);
+                  }
+            if (($v_header['size'] % 512) != 0) {
+              $v_content = $this->_readBlock();
+              fwrite($v_dest_file, $v_content, ($v_header['size'] % 512));
+            }
+
+            @fclose($v_dest_file);
+
+            // ----- Change the file mode, mtime
+            @touch($v_header['filename'], $v_header['mtime']);
+            if ($v_header['mode'] & 0111) {
+                // make file executable, obey umask
+                $mode = fileperms($v_header['filename']) | (~umask() & 0111);
+                @chmod($v_header['filename'], $mode);
+            }
+          }
+
+          // ----- Check the file size
+          clearstatcache();
+          if (filesize($v_header['filename']) != $v_header['size']) {
+              $this->_error('Extracted file '.$v_header['filename']
+			                .' does not have the correct file size \''
+							.filesize($v_header['filename'])
+							.'\' ('.$v_header['size']
+							.' expected). Archive may be corrupted.');
+              return false;
+          }
+          }
+        } else {
+          $this->_jumpBlock(ceil(($v_header['size']/512)));
+        }
+      } else {
+          $this->_jumpBlock(ceil(($v_header['size']/512)));
+      }
+
+      /* TBC : Seems to be unused ...
+      if ($this->_compress)
+        $v_end_of_file = @gzeof($this->_file);
+      else
+        $v_end_of_file = @feof($this->_file);
+        */
+
+      if ($v_listing || $v_extract_file || $v_extraction_stopped) {
+        // ----- Log extracted files
+        if (($v_file_dir = dirname($v_header['filename']))
+		    == $v_header['filename'])
+          $v_file_dir = '';
+        if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == ''))
+          $v_file_dir = '/';
+
+        $p_list_detail[$v_nb++] = $v_header;
+        if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) {
+            return true;
+        }
+      }
+    }
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _openAppend()
+    function _openAppend()
+    {
+        if (filesize($this->_tarname) == 0)
+          return $this->_openWrite();
+
+        if ($this->_compress) {
+            $this->_close();
+
+            if (!@rename($this->_tarname, $this->_tarname.".tmp")) {
+                $this->_error('Error while renaming \''.$this->_tarname
+				              .'\' to temporary file \''.$this->_tarname
+							  .'.tmp\'');
+                return false;
+            }
+
+            if ($this->_compress_type == 'gz')
+                $v_temp_tar = @gzopen($this->_tarname.".tmp", "rb");
+            elseif ($this->_compress_type == 'bz2')
+                $v_temp_tar = @bzopen($this->_tarname.".tmp", "r");
+
+            if ($v_temp_tar == 0) {
+                $this->_error('Unable to open file \''.$this->_tarname
+				              .'.tmp\' in binary read mode');
+                @rename($this->_tarname.".tmp", $this->_tarname);
+                return false;
+            }
+
+            if (!$this->_openWrite()) {
+                @rename($this->_tarname.".tmp", $this->_tarname);
+                return false;
+            }
+
+            if ($this->_compress_type == 'gz') {
+                while (!@gzeof($v_temp_tar)) {
+                    $v_buffer = @gzread($v_temp_tar, 512);
+                    if ($v_buffer == ARCHIVE_TAR_END_BLOCK) {
+                        // do not copy end blocks, we will re-make them
+                        // after appending
+                        continue;
+                    }
+                    $v_binary_data = pack("a512", $v_buffer);
+                    $this->_writeBlock($v_binary_data);
+                }
+
+                @gzclose($v_temp_tar);
+            }
+            elseif ($this->_compress_type == 'bz2') {
+                while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) {
+                    if ($v_buffer == ARCHIVE_TAR_END_BLOCK) {
+                        continue;
+                    }
+                    $v_binary_data = pack("a512", $v_buffer);
+                    $this->_writeBlock($v_binary_data);
+                }
+
+                @bzclose($v_temp_tar);
+            }
+
+            if (!@unlink($this->_tarname.".tmp")) {
+                $this->_error('Error while deleting temporary file \''
+				              .$this->_tarname.'.tmp\'');
+            }
+
+        } else {
+            // ----- For not compressed tar, just add files before the last
+			//       one or two 512 bytes block
+            if (!$this->_openReadWrite())
+               return false;
+
+            clearstatcache();
+            $v_size = filesize($this->_tarname);
+
+            // We might have zero, one or two end blocks.
+            // The standard is two, but we should try to handle
+            // other cases.
+            fseek($this->_file, $v_size - 1024);
+            if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) {
+                fseek($this->_file, $v_size - 1024);
+            }
+            elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) {
+                fseek($this->_file, $v_size - 512);
+            }
+        }
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _append()
+    function _append($p_filelist, $p_add_dir='', $p_remove_dir='')
+    {
+        if (!$this->_openAppend())
+            return false;
+
+        if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir))
+           $this->_writeFooter();
+
+        $this->_close();
+
+        return true;
+    }
+    // }}}
+
+    // {{{ _dirCheck()
+
+    /**
+     * Check if a directory exists and create it (including parent
+     * dirs) if not.
+     *
+     * @param string $p_dir directory to check
+     *
+     * @return bool TRUE if the directory exists or was created
+     */
+    function _dirCheck($p_dir)
+    {
+        clearstatcache();
+        if ((@is_dir($p_dir)) || ($p_dir == ''))
+            return true;
+
+        $p_parent_dir = dirname($p_dir);
+
+        if (($p_parent_dir != $p_dir) &&
+            ($p_parent_dir != '') &&
+            (!$this->_dirCheck($p_parent_dir)))
+             return false;
+
+        if (!@mkdir($p_dir, 0777)) {
+            $this->_error("Unable to create directory '$p_dir'");
+            return false;
+        }
+
+        return true;
+    }
+
+    // }}}
+
+    // {{{ _pathReduction()
+
+    /**
+     * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar",
+     * rand emove double slashes.
+     *
+     * @param string $p_dir path to reduce
+     *
+     * @return string reduced path
+     *
+     * @access private
+     *
+     */
+    function _pathReduction($p_dir)
+    {
+        $v_result = '';
+
+        // ----- Look for not empty path
+        if ($p_dir != '') {
+            // ----- Explode path by directory names
+            $v_list = explode('/', $p_dir);
+
+            // ----- Study directories from last to first
+            for ($i=sizeof($v_list)-1; $i>=0; $i--) {
+                // ----- Look for current path
+                if ($v_list[$i] == ".") {
+                    // ----- Ignore this directory
+                    // Should be the first $i=0, but no check is done
+                }
+                else if ($v_list[$i] == "..") {
+                    // ----- Ignore it and ignore the $i-1
+                    $i--;
+                }
+                else if (   ($v_list[$i] == '')
+				         && ($i!=(sizeof($v_list)-1))
+						 && ($i!=0)) {
+                    // ----- Ignore only the double '//' in path,
+                    // but not the first and last /
+                } else {
+                    $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?'/'
+					            .$v_result:'');
+                }
+            }
+        }
+        $v_result = strtr($v_result, '\\', '/');
+        return $v_result;
+    }
+
+    // }}}
+
+    // {{{ _translateWinPath()
+    function _translateWinPath($p_path, $p_remove_disk_letter=true)
+    {
+      if (defined('OS_WINDOWS') && OS_WINDOWS) {
+          // ----- Look for potential disk letter
+          if (   ($p_remove_disk_letter)
+		      && (($v_position = strpos($p_path, ':')) != false)) {
+              $p_path = substr($p_path, $v_position+1);
+          }
+          // ----- Change potential windows directory separator
+          if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
+              $p_path = strtr($p_path, '\\', '/');
+          }
+      }
+      return $p_path;
+    }
+    // }}}
+
+}
+?>
diff --git a/lib/php/Cache/Lite.php b/lib/php/Cache/Lite.php
new file mode 100644
index 00000000..a691e2e4
--- /dev/null
+++ b/lib/php/Cache/Lite.php
@@ -0,0 +1,835 @@
+<?php
+
+/**
+* Fast, light and safe Cache Class
+*
+* Cache_Lite is a fast, light and safe cache system. It's optimized
+* for file containers. It is fast and safe (because it uses file
+* locking and/or anti-corruption tests).
+*
+* There are some examples in the 'docs/examples' file
+* Technical choices are described in the 'docs/technical' file
+*
+* Memory Caching is from an original idea of
+* Mike BENOIT <ipso@snappymail.ca>
+*
+* Nota : A chinese documentation (thanks to RainX <china_1982@163.com>) is
+* available at :
+* http://rainx.phpmore.com/manual/cache_lite.html
+*
+* @package Cache_Lite
+* @category Caching
+* @version $Id: Lite.php,v 1.54 2009/07/07 05:34:37 tacker Exp $
+* @author Fabien MARTY <fab@php.net>
+*/
+
+define('CACHE_LITE_ERROR_RETURN', 1);
+define('CACHE_LITE_ERROR_DIE', 8);
+
+class Cache_Lite
+{
+
+    // --- Private properties ---
+
+    /**
+    * Directory where to put the cache files
+    * (make sure to add a trailing slash)
+    *
+    * @var string $_cacheDir
+    */
+    var $_cacheDir = '/tmp/';
+
+    /**
+    * Enable / disable caching
+    *
+    * (can be very usefull for the debug of cached scripts)
+    *
+    * @var boolean $_caching
+    */
+    var $_caching = true;
+
+    /**
+    * Cache lifetime (in seconds)
+    *
+    * If null, the cache is valid forever.
+    *
+    * @var int $_lifeTime
+    */
+    var $_lifeTime = 3600;
+
+    /**
+    * Enable / disable fileLocking
+    *
+    * (can avoid cache corruption under bad circumstances)
+    *
+    * @var boolean $_fileLocking
+    */
+    var $_fileLocking = true;
+
+    /**
+    * Timestamp of the last valid cache
+    *
+    * @var int $_refreshTime
+    */
+    var $_refreshTime;
+
+    /**
+    * File name (with path)
+    *
+    * @var string $_file
+    */
+    var $_file;
+    
+    /**
+    * File name (without path)
+    *
+    * @var string $_fileName
+    */
+    var $_fileName;
+
+    /**
+    * Enable / disable write control (the cache is read just after writing to detect corrupt entries)
+    *
+    * Enable write control will lightly slow the cache writing but not the cache reading
+    * Write control can detect some corrupt cache files but maybe it's not a perfect control
+    *
+    * @var boolean $_writeControl
+    */
+    var $_writeControl = true;
+
+    /**
+    * Enable / disable read control
+    *
+    * If enabled, a control key is embeded in cache file and this key is compared with the one
+    * calculated after the reading.
+    *
+    * @var boolean $_writeControl
+    */
+    var $_readControl = true;
+
+    /**
+    * Type of read control (only if read control is enabled)
+    *
+    * Available values are :
+    * 'md5' for a md5 hash control (best but slowest)
+    * 'crc32' for a crc32 hash control (lightly less safe but faster, better choice)
+    * 'strlen' for a length only test (fastest)
+    *
+    * @var boolean $_readControlType
+    */
+    var $_readControlType = 'crc32';
+
+    /**
+    * Pear error mode (when raiseError is called)
+    *
+    * (see PEAR doc)
+    *
+    * @see setToDebug()
+    * @var int $_pearErrorMode
+    */
+    var $_pearErrorMode = CACHE_LITE_ERROR_RETURN;
+    
+    /**
+    * Current cache id
+    *
+    * @var string $_id
+    */
+    var $_id;
+
+    /**
+    * Current cache group
+    *
+    * @var string $_group
+    */
+    var $_group;
+
+    /**
+    * Enable / Disable "Memory Caching"
+    *
+    * NB : There is no lifetime for memory caching ! 
+    *
+    * @var boolean $_memoryCaching
+    */
+    var $_memoryCaching = false;
+
+    /**
+    * Enable / Disable "Only Memory Caching"
+    * (be carefull, memory caching is "beta quality")
+    *
+    * @var boolean $_onlyMemoryCaching
+    */
+    var $_onlyMemoryCaching = false;
+
+    /**
+    * Memory caching array
+    *
+    * @var array $_memoryCachingArray
+    */
+    var $_memoryCachingArray = array();
+
+    /**
+    * Memory caching counter
+    *
+    * @var int $memoryCachingCounter
+    */
+    var $_memoryCachingCounter = 0;
+
+    /**
+    * Memory caching limit
+    *
+    * @var int $memoryCachingLimit
+    */
+    var $_memoryCachingLimit = 1000;
+    
+    /**
+    * File Name protection
+    *
+    * if set to true, you can use any cache id or group name
+    * if set to false, it can be faster but cache ids and group names
+    * will be used directly in cache file names so be carefull with
+    * special characters...
+    *
+    * @var boolean $fileNameProtection
+    */
+    var $_fileNameProtection = true;
+    
+    /**
+    * Enable / disable automatic serialization
+    *
+    * it can be used to save directly datas which aren't strings
+    * (but it's slower)    
+    *
+    * @var boolean $_serialize
+    */
+    var $_automaticSerialization = false;
+    
+    /**
+    * Disable / Tune the automatic cleaning process
+    *
+    * The automatic cleaning process destroy too old (for the given life time)
+    * cache files when a new cache file is written.
+    * 0               => no automatic cache cleaning
+    * 1               => systematic cache cleaning
+    * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
+    *
+    * @var int $_automaticCleaning
+    */
+    var $_automaticCleaningFactor = 0;
+    
+    /**
+    * Nested directory level
+    *
+    * Set the hashed directory structure level. 0 means "no hashed directory 
+    * structure", 1 means "one level of directory", 2 means "two levels"... 
+    * This option can speed up Cache_Lite only when you have many thousands of 
+    * cache file. Only specific benchs can help you to choose the perfect value 
+    * for you. Maybe, 1 or 2 is a good start.
+    *
+    * @var int $_hashedDirectoryLevel
+    */
+    var $_hashedDirectoryLevel = 0;
+    
+    /**
+    * Umask for hashed directory structure
+    *
+    * @var int $_hashedDirectoryUmask
+    */
+    var $_hashedDirectoryUmask = 0700;
+    
+    /**
+     * API break for error handling in CACHE_LITE_ERROR_RETURN mode
+     * 
+     * In CACHE_LITE_ERROR_RETURN mode, error handling was not good because
+     * for example save() method always returned a boolean (a PEAR_Error object
+     * would be better in CACHE_LITE_ERROR_RETURN mode). To correct this without
+     * breaking the API, this option (false by default) can change this handling.
+     * 
+     * @var boolean
+     */
+    var $_errorHandlingAPIBreak = false;
+    
+    // --- Public methods ---
+
+    /**
+    * Constructor
+    *
+    * $options is an assoc. Available options are :
+    * $options = array(
+    *     'cacheDir' => directory where to put the cache files (string),
+    *     'caching' => enable / disable caching (boolean),
+    *     'lifeTime' => cache lifetime in seconds (int),
+    *     'fileLocking' => enable / disable fileLocking (boolean),
+    *     'writeControl' => enable / disable write control (boolean),
+    *     'readControl' => enable / disable read control (boolean),
+    *     'readControlType' => type of read control 'crc32', 'md5', 'strlen' (string),
+    *     'pearErrorMode' => pear error mode (when raiseError is called) (cf PEAR doc) (int),
+    *     'memoryCaching' => enable / disable memory caching (boolean),
+    *     'onlyMemoryCaching' => enable / disable only memory caching (boolean),
+    *     'memoryCachingLimit' => max nbr of records to store into memory caching (int),
+    *     'fileNameProtection' => enable / disable automatic file name protection (boolean),
+    *     'automaticSerialization' => enable / disable automatic serialization (boolean),
+    *     'automaticCleaningFactor' => distable / tune automatic cleaning process (int),
+    *     'hashedDirectoryLevel' => level of the hashed directory system (int),
+    *     'hashedDirectoryUmask' => umask for hashed directory structure (int),
+    *     'errorHandlingAPIBreak' => API break for better error handling ? (boolean)
+    * );
+    *
+    * @param array $options options
+    * @access public
+    */
+    function Cache_Lite($options = array(NULL))
+    {
+        foreach($options as $key => $value) {
+            $this->setOption($key, $value);
+        }
+    }
+    
+    /**
+    * Generic way to set a Cache_Lite option
+    *
+    * see Cache_Lite constructor for available options
+    *
+    * @var string $name name of the option
+    * @var mixed $value value of the option
+    * @access public
+    */
+    function setOption($name, $value) 
+    {
+        $availableOptions = array('errorHandlingAPIBreak', 'hashedDirectoryUmask', 'hashedDirectoryLevel', 'automaticCleaningFactor', 'automaticSerialization', 'fileNameProtection', 'memoryCaching', 'onlyMemoryCaching', 'memoryCachingLimit', 'cacheDir', 'caching', 'lifeTime', 'fileLocking', 'writeControl', 'readControl', 'readControlType', 'pearErrorMode');
+        if (in_array($name, $availableOptions)) {
+            $property = '_'.$name;
+            $this->$property = $value;
+        }
+    }
+    
+    /**
+    * Test if a cache is available and (if yes) return it
+    *
+    * @param string $id cache id
+    * @param string $group name of the cache group
+    * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
+    * @return string data of the cache (else : false)
+    * @access public
+    */
+    function get($id, $group = 'default', $doNotTestCacheValidity = false)
+    {
+        $this->_id = $id;
+        $this->_group = $group;
+        $data = false;
+        if ($this->_caching) {
+            $this->_setRefreshTime();
+            $this->_setFileName($id, $group);
+            clearstatcache();
+            if ($this->_memoryCaching) {
+                if (isset($this->_memoryCachingArray[$this->_file])) {
+                    if ($this->_automaticSerialization) {
+                        return unserialize($this->_memoryCachingArray[$this->_file]);
+                    }
+                    return $this->_memoryCachingArray[$this->_file];
+                }
+                if ($this->_onlyMemoryCaching) {
+                    return false;
+                }                
+            }
+            if (($doNotTestCacheValidity) || (is_null($this->_refreshTime))) {
+                if (file_exists($this->_file)) {
+                    $data = $this->_read();
+                }
+            } else {
+                if ((file_exists($this->_file)) && (@filemtime($this->_file) > $this->_refreshTime)) {
+                    $data = $this->_read();
+                }
+            }
+            if (($data) and ($this->_memoryCaching)) {
+                $this->_memoryCacheAdd($data);
+            }
+            if (($this->_automaticSerialization) and (is_string($data))) {
+                $data = unserialize($data);
+            }
+            return $data;
+        }
+        return false;
+    }
+    
+    /**
+    * Save some data in a cache file
+    *
+    * @param string $data data to put in cache (can be another type than strings if automaticSerialization is on)
+    * @param string $id cache id
+    * @param string $group name of the cache group
+    * @return boolean true if no problem (else : false or a PEAR_Error object)
+    * @access public
+    */
+    function save($data, $id = NULL, $group = 'default')
+    {
+        if ($this->_caching) {
+            if ($this->_automaticSerialization) {
+                $data = serialize($data);
+            }
+            if (isset($id)) {
+                $this->_setFileName($id, $group);
+            }
+            if ($this->_memoryCaching) {
+                $this->_memoryCacheAdd($data);
+                if ($this->_onlyMemoryCaching) {
+                    return true;
+                }
+            }
+            if ($this->_automaticCleaningFactor>0 && ($this->_automaticCleaningFactor==1 || mt_rand(1, $this->_automaticCleaningFactor)==1)) {
+				$this->clean(false, 'old');			
+			}
+            if ($this->_writeControl) {
+                $res = $this->_writeAndControl($data);
+                if (is_bool($res)) {
+                    if ($res) {
+                        return true;  
+                    }
+                    // if $res if false, we need to invalidate the cache
+                    @touch($this->_file, time() - 2*abs($this->_lifeTime));
+                    return false;
+                }            
+            } else {
+                $res = $this->_write($data);
+            }
+            if (is_object($res)) {
+                // $res is a PEAR_Error object 
+                if (!($this->_errorHandlingAPIBreak)) {   
+                    return false; // we return false (old API)
+                }
+            }
+            return $res;
+        }
+        return false;
+    }
+
+    /**
+    * Remove a cache file
+    *
+    * @param string $id cache id
+    * @param string $group name of the cache group
+    * @param boolean $checkbeforeunlink check if file exists before removing it
+    * @return boolean true if no problem
+    * @access public
+    */
+    function remove($id, $group = 'default', $checkbeforeunlink = false)
+    {
+        $this->_setFileName($id, $group);
+        if ($this->_memoryCaching) {
+            if (isset($this->_memoryCachingArray[$this->_file])) {
+                unset($this->_memoryCachingArray[$this->_file]);
+                $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1;
+            }
+            if ($this->_onlyMemoryCaching) {
+                return true;
+            }
+        }
+        if ( $checkbeforeunlink ) {
+            if (!file_exists($this->_file)) return true;
+        }
+        return $this->_unlink($this->_file);
+    }
+
+    /**
+    * Clean the cache
+    *
+    * if no group is specified all cache files will be destroyed
+    * else only cache files of the specified group will be destroyed
+    *
+    * @param string $group name of the cache group
+    * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup', 
+    *                                        'callback_myFunction'
+    * @return boolean true if no problem
+    * @access public
+    */
+    function clean($group = false, $mode = 'ingroup')
+    {
+        return $this->_cleanDir($this->_cacheDir, $group, $mode);
+    }
+       
+    /**
+    * Set to debug mode
+    *
+    * When an error is found, the script will stop and the message will be displayed
+    * (in debug mode only). 
+    *
+    * @access public
+    */
+    function setToDebug()
+    {
+        $this->setOption('pearErrorMode', CACHE_LITE_ERROR_DIE);
+    }
+
+    /**
+    * Set a new life time
+    *
+    * @param int $newLifeTime new life time (in seconds)
+    * @access public
+    */
+    function setLifeTime($newLifeTime)
+    {
+        $this->_lifeTime = $newLifeTime;
+        $this->_setRefreshTime();
+    }
+
+    /**
+    * Save the state of the caching memory array into a cache file cache
+    *
+    * @param string $id cache id
+    * @param string $group name of the cache group
+    * @access public
+    */
+    function saveMemoryCachingState($id, $group = 'default')
+    {
+        if ($this->_caching) {
+            $array = array(
+                'counter' => $this->_memoryCachingCounter,
+                'array' => $this->_memoryCachingArray
+            );
+            $data = serialize($array);
+            $this->save($data, $id, $group);
+        }
+    }
+
+    /**
+    * Load the state of the caching memory array from a given cache file cache
+    *
+    * @param string $id cache id
+    * @param string $group name of the cache group
+    * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
+    * @access public
+    */
+    function getMemoryCachingState($id, $group = 'default', $doNotTestCacheValidity = false)
+    {
+        if ($this->_caching) {
+            if ($data = $this->get($id, $group, $doNotTestCacheValidity)) {
+                $array = unserialize($data);
+                $this->_memoryCachingCounter = $array['counter'];
+                $this->_memoryCachingArray = $array['array'];
+            }
+        }
+    }
+    
+    /**
+    * Return the cache last modification time
+    *
+    * BE CAREFUL : THIS METHOD IS FOR HACKING ONLY !
+    *
+    * @return int last modification time
+    */
+    function lastModified() 
+    {
+        return @filemtime($this->_file);
+    }
+    
+    /**
+    * Trigger a PEAR error
+    *
+    * To improve performances, the PEAR.php file is included dynamically.
+    * The file is so included only when an error is triggered. So, in most
+    * cases, the file isn't included and perfs are much better.
+    *
+    * @param string $msg error message
+    * @param int $code error code
+    * @access public
+    */
+    function raiseError($msg, $code)
+    {
+        include_once('PEAR.php');
+        return PEAR::raiseError($msg, $code, $this->_pearErrorMode);
+    }
+    
+    /**
+     * Extend the life of a valid cache file
+     * 
+     * see http://pear.php.net/bugs/bug.php?id=6681
+     * 
+     * @access public
+     */
+    function extendLife()
+    {
+        @touch($this->_file);
+    }
+    
+    // --- Private methods ---
+    
+    /**
+    * Compute & set the refresh time
+    *
+    * @access private
+    */
+    function _setRefreshTime() 
+    {
+        if (is_null($this->_lifeTime)) {
+            $this->_refreshTime = null;
+        } else {
+            $this->_refreshTime = time() - $this->_lifeTime;
+        }
+    }
+    
+    /**
+    * Remove a file
+    * 
+    * @param string $file complete file path and name
+    * @return boolean true if no problem
+    * @access private
+    */
+    function _unlink($file)
+    {
+        if (!@unlink($file)) {
+            return $this->raiseError('Cache_Lite : Unable to remove cache !', -3);
+        }
+        return true;        
+    }
+
+    /**
+    * Recursive function for cleaning cache file in the given directory
+    *
+    * @param string $dir directory complete path (with a trailing slash)
+    * @param string $group name of the cache group
+    * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup',
+                                             'callback_myFunction'
+    * @return boolean true if no problem
+    * @access private
+    */
+    function _cleanDir($dir, $group = false, $mode = 'ingroup')     
+    {
+        if ($this->_fileNameProtection) {
+            $motif = ($group) ? 'cache_'.md5($group).'_' : 'cache_';
+        } else {
+            $motif = ($group) ? 'cache_'.$group.'_' : 'cache_';
+        }
+        if ($this->_memoryCaching) {
+	    foreach($this->_memoryCachingArray as $key => $v) {
+                if (strpos($key, $motif) !== false) {
+                    unset($this->_memoryCachingArray[$key]);
+                    $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1;
+                }
+            }
+            if ($this->_onlyMemoryCaching) {
+                return true;
+            }
+        }
+        if (!($dh = opendir($dir))) {
+            return $this->raiseError('Cache_Lite : Unable to open cache directory !', -4);
+        }
+        $result = true;
+        while ($file = readdir($dh)) {
+            if (($file != '.') && ($file != '..')) {
+                if (substr($file, 0, 6)=='cache_') {
+                    $file2 = $dir . $file;
+                    if (is_file($file2)) {
+                        switch (substr($mode, 0, 9)) {
+                            case 'old':
+                                // files older than lifeTime get deleted from cache
+                                if (!is_null($this->_lifeTime)) {
+                                    if ((time() - @filemtime($file2)) > $this->_lifeTime) {
+                                        $result = ($result and ($this->_unlink($file2)));
+                                    }
+                                }
+                                break;
+                            case 'notingrou':
+                                if (strpos($file2, $motif) === false) {
+                                    $result = ($result and ($this->_unlink($file2)));
+                                }
+                                break;
+                            case 'callback_':
+                                $func = substr($mode, 9, strlen($mode) - 9);
+                                if ($func($file2, $group)) {
+                                    $result = ($result and ($this->_unlink($file2)));
+                                }
+                                break;
+                            case 'ingroup':
+                            default:
+                                if (strpos($file2, $motif) !== false) {
+                                    $result = ($result and ($this->_unlink($file2)));
+                                }
+                                break;
+                        }
+                    }
+                    if ((is_dir($file2)) and ($this->_hashedDirectoryLevel>0)) {
+                        $result = ($result and ($this->_cleanDir($file2 . '/', $group, $mode)));
+                    }
+                }
+            }
+        }
+        return $result;
+    }
+      
+    /**
+    * Add some date in the memory caching array
+    *
+    * @param string $data data to cache
+    * @access private
+    */
+    function _memoryCacheAdd($data)
+    {
+        $this->_memoryCachingArray[$this->_file] = $data;
+        if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) {
+            list($key, ) = each($this->_memoryCachingArray);
+            unset($this->_memoryCachingArray[$key]);
+        } else {
+            $this->_memoryCachingCounter = $this->_memoryCachingCounter + 1;
+        }
+    }
+
+    /**
+    * Make a file name (with path)
+    *
+    * @param string $id cache id
+    * @param string $group name of the group
+    * @access private
+    */
+    function _setFileName($id, $group)
+    {
+        
+        if ($this->_fileNameProtection) {
+            $suffix = 'cache_'.md5($group).'_'.md5($id);
+        } else {
+            $suffix = 'cache_'.$group.'_'.$id;
+        }
+        $root = $this->_cacheDir;
+        if ($this->_hashedDirectoryLevel>0) {
+            $hash = md5($suffix);
+            for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
+                $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
+            }   
+        }
+        $this->_fileName = $suffix;
+        $this->_file = $root.$suffix;
+    }
+    
+    /**
+    * Read the cache file and return the content
+    *
+    * @return string content of the cache file (else : false or a PEAR_Error object)
+    * @access private
+    */
+    function _read()
+    {
+        $fp = @fopen($this->_file, "rb");
+        if ($this->_fileLocking) @flock($fp, LOCK_SH);
+        if ($fp) {
+            clearstatcache();
+            $length = @filesize($this->_file);
+            $mqr = get_magic_quotes_runtime();
+            if ($mqr) {
+                set_magic_quotes_runtime(0);
+            }
+            if ($this->_readControl) {
+                $hashControl = @fread($fp, 32);
+                $length = $length - 32;
+            } 
+            if ($length) {
+                $data = @fread($fp, $length);
+            } else {
+                $data = '';
+            }
+            if ($mqr) {
+                set_magic_quotes_runtime($mqr);
+            }
+            if ($this->_fileLocking) @flock($fp, LOCK_UN);
+            @fclose($fp);
+            if ($this->_readControl) {
+                $hashData = $this->_hash($data, $this->_readControlType);
+                if ($hashData != $hashControl) {
+                    if (!(is_null($this->_lifeTime))) {
+                        @touch($this->_file, time() - 2*abs($this->_lifeTime)); 
+                    } else {
+                        @unlink($this->_file);
+                    }
+                    return false;
+                }
+            }
+            return $data;
+        }
+        return $this->raiseError('Cache_Lite : Unable to read cache !', -2); 
+    }
+    
+    /**
+    * Write the given data in the cache file
+    *
+    * @param string $data data to put in cache
+    * @return boolean true if ok (a PEAR_Error object else)
+    * @access private
+    */
+    function _write($data)
+    {
+        if ($this->_hashedDirectoryLevel > 0) {
+            $hash = md5($this->_fileName);
+            $root = $this->_cacheDir;
+            for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
+                $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
+                if (!(@is_dir($root))) {
+                    @mkdir($root, $this->_hashedDirectoryUmask);
+                }
+            }
+        }
+        $fp = @fopen($this->_file, "wb");
+        if ($fp) {
+            if ($this->_fileLocking) @flock($fp, LOCK_EX);
+            if ($this->_readControl) {
+                @fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
+            }
+            $mqr = get_magic_quotes_runtime();
+            if ($mqr) {
+                set_magic_quotes_runtime(0);
+            }
+            @fwrite($fp, $data);
+            if ($mqr) {
+                set_magic_quotes_runtime($mqr);
+            }
+            if ($this->_fileLocking) @flock($fp, LOCK_UN);
+            @fclose($fp);
+            return true;
+        }      
+        return $this->raiseError('Cache_Lite : Unable to write cache file : '.$this->_file, -1);
+    }
+       
+    /**
+    * Write the given data in the cache file and control it just after to avoir corrupted cache entries
+    *
+    * @param string $data data to put in cache
+    * @return boolean true if the test is ok (else : false or a PEAR_Error object)
+    * @access private
+    */
+    function _writeAndControl($data)
+    {
+        $result = $this->_write($data);
+        if (is_object($result)) {
+            return $result; # We return the PEAR_Error object
+        }
+        $dataRead = $this->_read();
+        if (is_object($dataRead)) {
+            return $dataRead; # We return the PEAR_Error object
+        }
+        if ((is_bool($dataRead)) && (!$dataRead)) {
+            return false; 
+        }
+        return ($dataRead==$data);
+    }
+    
+    /**
+    * Make a control key with the string containing datas
+    *
+    * @param string $data data
+    * @param string $controlType type of control 'md5', 'crc32' or 'strlen'
+    * @return string control key
+    * @access private
+    */
+    function _hash($data, $controlType)
+    {
+        switch ($controlType) {
+        case 'md5':
+            return md5($data);
+        case 'crc32':
+            return sprintf('% 32d', crc32($data));
+        case 'strlen':
+            return sprintf('% 32d', strlen($data));
+        default:
+            return $this->raiseError('Unknown controlType ! (available values are only \'md5\', \'crc32\', \'strlen\')', -5);
+        }
+    }
+    
+} 
+
+?>
diff --git a/lib/php/Cache/Lite/File.php b/lib/php/Cache/Lite/File.php
new file mode 100644
index 00000000..e34da4ef
--- /dev/null
+++ b/lib/php/Cache/Lite/File.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+* This class extends Cache_Lite and offers a cache system driven by a master file
+*
+* With this class, cache validity is only dependent of a given file. Cache files
+* are valid only if they are older than the master file. It's a perfect way for
+* caching templates results (if the template file is newer than the cache, cache
+* must be rebuild...) or for config classes...
+* There are some examples in the 'docs/examples' file
+* Technical choices are described in the 'docs/technical' file
+*
+* @package Cache_Lite
+* @version $Id: File.php,v 1.4 2009/03/07 12:55:39 tacker Exp $
+* @author Fabien MARTY <fab@php.net>
+*/
+ 
+require_once('Cache/Lite.php');
+
+class Cache_Lite_File extends Cache_Lite
+{
+
+    // --- Private properties ---
+    
+    /**
+    * Complete path of the file used for controlling the cache lifetime
+    *
+    * @var string $_masterFile
+    */
+    var $_masterFile = '';
+    
+    /**
+    * Masterfile mtime
+    *
+    * @var int $_masterFile_mtime
+    */
+    var $_masterFile_mtime = 0;
+    
+    // --- Public methods ----
+    
+    /**
+    * Constructor
+    *
+    * $options is an assoc. To have a look at availables options,
+    * see the constructor of the Cache_Lite class in 'Cache_Lite.php'
+    *
+    * Comparing to Cache_Lite constructor, there is another option :
+    * $options = array(
+    *     (...) see Cache_Lite constructor
+    *     'masterFile' => complete path of the file used for controlling the cache lifetime(string)
+    * );
+    *
+    * @param array $options options
+    * @access public
+    */
+    function Cache_Lite_File($options = array(NULL))
+    {   
+        $options['lifetime'] = 0;
+        $this->Cache_Lite($options);
+        if (isset($options['masterFile'])) {
+            $this->_masterFile = $options['masterFile'];
+        } else {
+            return $this->raiseError('Cache_Lite_File : masterFile option must be set !');
+        }
+        if (!($this->_masterFile_mtime = @filemtime($this->_masterFile))) {
+            return $this->raiseError('Cache_Lite_File : Unable to read masterFile : '.$this->_masterFile, -3);
+        }
+    }
+    
+    /**
+    * Test if a cache is available and (if yes) return it
+    *
+    * @param string $id cache id
+    * @param string $group name of the cache group
+    * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
+    * @return string data of the cache (else : false)
+    * @access public
+    */
+    function get($id, $group = 'default', $doNotTestCacheValidity = false)
+    {
+        if ($data = parent::get($id, $group, true)) {
+            if ($filemtime = $this->lastModified()) {
+                if ($filemtime > $this->_masterFile_mtime) {
+                    return $data;
+                }
+            }
+        }
+        return false;
+    }
+
+}
+
+?>
diff --git a/lib/php/Cache/Lite/Function.php b/lib/php/Cache/Lite/Function.php
new file mode 100644
index 00000000..63a96d9e
--- /dev/null
+++ b/lib/php/Cache/Lite/Function.php
@@ -0,0 +1,211 @@
+<?php
+
+/**
+* This class extends Cache_Lite and can be used to cache the result and output of functions/methods
+*
+* This class is completly inspired from Sebastian Bergmann's
+* PEAR/Cache_Function class. This is only an adaptation to
+* Cache_Lite
+*
+* There are some examples in the 'docs/examples' file
+* Technical choices are described in the 'docs/technical' file
+*
+* @package Cache_Lite
+* @version $Id: Function.php,v 1.11 2006/12/14 12:59:43 cweiske Exp $
+* @author Sebastian BERGMANN <sb@sebastian-bergmann.de>
+* @author Fabien MARTY <fab@php.net>
+*/
+
+require_once('Cache/Lite.php');
+
+class Cache_Lite_Function extends Cache_Lite
+{
+
+    // --- Private properties ---
+
+    /**
+     * Default cache group for function caching
+     *
+     * @var string $_defaultGroup
+     */
+    var $_defaultGroup = 'Cache_Lite_Function';
+
+    /**
+     * Don't cache the method call when its output contains the string "NOCACHE"
+     *
+     * if set to true, the output of the method will never be displayed (because the output is used
+     * to control the cache)
+     *
+     * @var boolean $_dontCacheWhenTheOutputContainsNOCACHE
+     */
+    var $_dontCacheWhenTheOutputContainsNOCACHE = false;
+
+    /**
+     * Don't cache the method call when its result is false
+     *
+     * @var boolean $_dontCacheWhenTheResultIsFalse
+     */
+    var $_dontCacheWhenTheResultIsFalse = false;
+
+    /**
+     * Don't cache the method call when its result is null
+     *
+     * @var boolean $_dontCacheWhenTheResultIsNull
+     */
+    var $_dontCacheWhenTheResultIsNull = false;
+
+    /**
+     * Debug the Cache_Lite_Function caching process
+     *
+     * @var boolean $_debugCacheLiteFunction
+     */
+    var $_debugCacheLiteFunction = false;
+
+    // --- Public methods ----
+
+    /**
+    * Constructor
+    *
+    * $options is an assoc. To have a look at availables options,
+    * see the constructor of the Cache_Lite class in 'Cache_Lite.php'
+    *
+    * Comparing to Cache_Lite constructor, there is another option :
+    * $options = array(
+    *     (...) see Cache_Lite constructor
+    *     'debugCacheLiteFunction' => (bool) debug the caching process,
+    *     'defaultGroup' => default cache group for function caching (string),
+    *     'dontCacheWhenTheOutputContainsNOCACHE' => (bool) don't cache when the function output contains "NOCACHE",
+    *     'dontCacheWhenTheResultIsFalse' => (bool) don't cache when the function result is false,
+    *     'dontCacheWhenTheResultIsNull' => (bool don't cache when the function result is null
+    * );
+    *
+    * @param array $options options
+    * @access public
+    */
+    function Cache_Lite_Function($options = array(NULL))
+    {
+        $availableOptions = array('debugCacheLiteFunction', 'defaultGroup', 'dontCacheWhenTheOutputContainsNOCACHE', 'dontCacheWhenTheResultIsFalse', 'dontCacheWhenTheResultIsNull');
+        while (list($name, $value) = each($options)) {
+            if (in_array($name, $availableOptions)) {
+                $property = '_'.$name;
+                $this->$property = $value;
+            }
+        }
+        reset($options);
+        $this->Cache_Lite($options);
+    }
+
+    /**
+    * Calls a cacheable function or method (or not if there is already a cache for it)
+    *
+    * Arguments of this method are read with func_get_args. So it doesn't appear
+    * in the function definition. Synopsis :
+    * call('functionName', $arg1, $arg2, ...)
+    * (arg1, arg2... are arguments of 'functionName')
+    *
+    * @return mixed result of the function/method
+    * @access public
+    */
+    function call()
+    {
+        $arguments = func_get_args();
+        $id = $this->_makeId($arguments);
+        $data = $this->get($id, $this->_defaultGroup);
+        if ($data !== false) {
+            if ($this->_debugCacheLiteFunction) {
+                echo "Cache hit !\n";
+            }
+            $array = unserialize($data);
+            $output = $array['output'];
+            $result = $array['result'];
+        } else {
+            if ($this->_debugCacheLiteFunction) {
+                echo "Cache missed !\n";
+            }
+            ob_start();
+            ob_implicit_flush(false);
+            $target = array_shift($arguments);
+            if (is_array($target)) {
+                // in this case, $target is for example array($obj, 'method')
+                $object = $target[0];
+                $method = $target[1];
+                $result = call_user_func_array(array(&$object, $method), $arguments);
+            } else {
+                if (strstr($target, '::')) { // classname::staticMethod
+                    list($class, $method) = explode('::', $target);
+                    $result = call_user_func_array(array($class, $method), $arguments);
+                } else if (strstr($target, '->')) { // object->method
+                    // use a stupid name ($objet_123456789 because) of problems where the object
+                    // name is the same as this var name
+                    list($object_123456789, $method) = explode('->', $target);
+                    global $$object_123456789;
+                    $result = call_user_func_array(array($$object_123456789, $method), $arguments);
+                } else { // function
+                    $result = call_user_func_array($target, $arguments);
+                }
+            }
+            $output = ob_get_contents();
+            ob_end_clean();
+            if ($this->_dontCacheWhenTheResultIsFalse) {
+                if ((is_bool($result)) && (!($result))) {
+                    echo($output);
+                    return $result;
+                }
+            }
+            if ($this->_dontCacheWhenTheResultIsNull) {
+                if (is_null($result)) {
+                    echo($output);
+                    return $result;
+                }
+            }
+            if ($this->_dontCacheWhenTheOutputContainsNOCACHE) {
+                if (strpos($output, 'NOCACHE') > -1) {
+                    return $result;
+                }
+            }
+            $array['output'] = $output;
+            $array['result'] = $result;
+            $this->save(serialize($array), $id, $this->_defaultGroup);
+        }
+        echo($output);
+        return $result;
+    }
+
+    /**
+    * Drop a cache file
+    *
+    * Arguments of this method are read with func_get_args. So it doesn't appear
+    * in the function definition. Synopsis :
+    * remove('functionName', $arg1, $arg2, ...)
+    * (arg1, arg2... are arguments of 'functionName')
+    *
+    * @return boolean true if no problem
+    * @access public
+    */
+    function drop()
+    {
+        $id = $this->_makeId(func_get_args());
+        return $this->remove($id, $this->_defaultGroup);
+    }
+
+    /**
+    * Make an id for the cache
+    *
+    * @var array result of func_get_args for the call() or the remove() method
+    * @return string id
+    * @access private
+    */
+    function _makeId($arguments)
+    {
+        $id = serialize($arguments); // Generate a cache id
+        if (!$this->_fileNameProtection) {
+            $id = md5($id);
+            // if fileNameProtection is set to false, then the id has to be hashed
+            // because it's a very bad file name in most cases
+        }
+        return $id;
+    }
+
+}
+
+?>
diff --git a/lib/php/Cache/Lite/Output.php b/lib/php/Cache/Lite/Output.php
new file mode 100644
index 00000000..97322736
--- /dev/null
+++ b/lib/php/Cache/Lite/Output.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+* This class extends Cache_Lite and uses output buffering to get the data to cache.
+*
+* There are some examples in the 'docs/examples' file
+* Technical choices are described in the 'docs/technical' file
+*
+* @package Cache_Lite
+* @version $Id: Output.php,v 1.4 2006/01/29 00:22:07 fab Exp $
+* @author Fabien MARTY <fab@php.net>
+*/
+
+require_once('Cache/Lite.php');
+
+class Cache_Lite_Output extends Cache_Lite
+{
+
+    // --- Public methods ---
+
+    /**
+    * Constructor
+    *
+    * $options is an assoc. To have a look at availables options,
+    * see the constructor of the Cache_Lite class in 'Cache_Lite.php'
+    *
+    * @param array $options options
+    * @access public
+    */
+    function Cache_Lite_Output($options)
+    {
+        $this->Cache_Lite($options);
+    }
+
+    /**
+    * Start the cache
+    *
+    * @param string $id cache id
+    * @param string $group name of the cache group
+    * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
+    * @return boolean true if the cache is hit (false else)
+    * @access public
+    */
+    function start($id, $group = 'default', $doNotTestCacheValidity = false)
+    {
+        $data = $this->get($id, $group, $doNotTestCacheValidity);
+        if ($data !== false) {
+            echo($data);
+            return true;
+        }
+        ob_start();
+        ob_implicit_flush(false);
+        return false;
+    }
+
+    /**
+    * Stop the cache
+    *
+    * @access public
+    */
+    function end()
+    {
+        $data = ob_get_contents();
+        ob_end_clean();
+        $this->save($data, $this->_id, $this->_group);
+        echo($data);
+    }
+
+}
+
+
+?>
diff --git a/lib/php/Console/Getopt.php b/lib/php/Console/Getopt.php
new file mode 100644
index 00000000..bb9d69ca
--- /dev/null
+++ b/lib/php/Console/Getopt.php
@@ -0,0 +1,290 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP Version 5                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2004 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 3.0 of the PHP license,       |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available through the world-wide-web at the following url:           |
+// | http://www.php.net/license/3_0.txt.                                  |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Author: Andrei Zmievski <andrei@php.net>                             |
+// +----------------------------------------------------------------------+
+//
+// $Id: Getopt.php,v 1.4 2007/06/12 14:58:56 cellog Exp $
+
+require_once 'PEAR.php';
+
+/**
+ * Command-line options parsing class.
+ *
+ * @author Andrei Zmievski <andrei@php.net>
+ *
+ */
+class Console_Getopt {
+    /**
+     * Parses the command-line options.
+     *
+     * The first parameter to this function should be the list of command-line
+     * arguments without the leading reference to the running program.
+     *
+     * The second parameter is a string of allowed short options. Each of the
+     * option letters can be followed by a colon ':' to specify that the option
+     * requires an argument, or a double colon '::' to specify that the option
+     * takes an optional argument.
+     *
+     * The third argument is an optional array of allowed long options. The
+     * leading '--' should not be included in the option name. Options that
+     * require an argument should be followed by '=', and options that take an
+     * option argument should be followed by '=='.
+     *
+     * The return value is an array of two elements: the list of parsed
+     * options and the list of non-option command-line arguments. Each entry in
+     * the list of parsed options is a pair of elements - the first one
+     * specifies the option, and the second one specifies the option argument,
+     * if there was one.
+     *
+     * Long and short options can be mixed.
+     *
+     * Most of the semantics of this function are based on GNU getopt_long().
+     *
+     * @param array  $args           an array of command-line arguments
+     * @param string $short_options  specifies the list of allowed short options
+     * @param array  $long_options   specifies the list of allowed long options
+     *
+     * @return array two-element array containing the list of parsed options and
+     * the non-option arguments
+     *
+     * @access public
+     *
+     */
+    function getopt2($args, $short_options, $long_options = null)
+    {
+        return Console_Getopt::doGetopt(2, $args, $short_options, $long_options);
+    }
+
+    /**
+     * This function expects $args to start with the script name (POSIX-style).
+     * Preserved for backwards compatibility.
+     * @see getopt2()
+     */    
+    function getopt($args, $short_options, $long_options = null)
+    {
+        return Console_Getopt::doGetopt(1, $args, $short_options, $long_options);
+    }
+
+    /**
+     * The actual implementation of the argument parsing code.
+     */
+    function doGetopt($version, $args, $short_options, $long_options = null)
+    {
+        // in case you pass directly readPHPArgv() as the first arg
+        if (PEAR::isError($args)) {
+            return $args;
+        }
+        if (empty($args)) {
+            return array(array(), array());
+        }
+        $opts     = array();
+        $non_opts = array();
+
+        settype($args, 'array');
+
+        if ($long_options) {
+            sort($long_options);
+        }
+
+        /*
+         * Preserve backwards compatibility with callers that relied on
+         * erroneous POSIX fix.
+         */
+        if ($version < 2) {
+            if (isset($args[0]{0}) && $args[0]{0} != '-') {
+                array_shift($args);
+            }
+        }
+
+        reset($args);
+        while (list($i, $arg) = each($args)) {
+
+            /* The special element '--' means explicit end of
+               options. Treat the rest of the arguments as non-options
+               and end the loop. */
+            if ($arg == '--') {
+                $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
+                break;
+            }
+
+            if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {
+                $non_opts = array_merge($non_opts, array_slice($args, $i));
+                break;
+            } elseif (strlen($arg) > 1 && $arg{1} == '-') {
+                $error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args);
+                if (PEAR::isError($error))
+                    return $error;
+            } elseif ($arg == '-') {
+                // - is stdin
+                $non_opts = array_merge($non_opts, array_slice($args, $i));
+                break;
+            } else {
+                $error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args);
+                if (PEAR::isError($error))
+                    return $error;
+            }
+        }
+
+        return array($opts, $non_opts);
+    }
+
+    /**
+     * @access private
+     *
+     */
+    function _parseShortOption($arg, $short_options, &$opts, &$args)
+    {
+        for ($i = 0; $i < strlen($arg); $i++) {
+            $opt = $arg{$i};
+            $opt_arg = null;
+
+            /* Try to find the short option in the specifier string. */
+            if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':')
+            {
+                return PEAR::raiseError("Console_Getopt: unrecognized option -- $opt");
+            }
+
+            if (strlen($spec) > 1 && $spec{1} == ':') {
+                if (strlen($spec) > 2 && $spec{2} == ':') {
+                    if ($i + 1 < strlen($arg)) {
+                        /* Option takes an optional argument. Use the remainder of
+                           the arg string if there is anything left. */
+                        $opts[] = array($opt, substr($arg, $i + 1));
+                        break;
+                    }
+                } else {
+                    /* Option requires an argument. Use the remainder of the arg
+                       string if there is anything left. */
+                    if ($i + 1 < strlen($arg)) {
+                        $opts[] = array($opt,  substr($arg, $i + 1));
+                        break;
+                    } else if (list(, $opt_arg) = each($args)) {
+                        /* Else use the next argument. */;
+                        if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) {
+                            return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt");
+                        }
+                    } else {
+                        return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt");
+                    }
+                }
+            }
+
+            $opts[] = array($opt, $opt_arg);
+        }
+    }
+
+    /**
+     * @access private
+     *
+     */
+    function _isShortOpt($arg)
+    {
+        return strlen($arg) == 2 && $arg[0] == '-' && preg_match('/[a-zA-Z]/', $arg[1]);
+    }
+
+    /**
+     * @access private
+     *
+     */
+    function _isLongOpt($arg)
+    {
+        return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' &&
+            preg_match('/[a-zA-Z]+$/', substr($arg, 2));
+    }
+
+    /**
+     * @access private
+     *
+     */
+    function _parseLongOption($arg, $long_options, &$opts, &$args)
+    {
+        @list($opt, $opt_arg) = explode('=', $arg, 2);
+        $opt_len = strlen($opt);
+
+        for ($i = 0; $i < count($long_options); $i++) {
+            $long_opt  = $long_options[$i];
+            $opt_start = substr($long_opt, 0, $opt_len);
+            $long_opt_name = str_replace('=', '', $long_opt);
+
+            /* Option doesn't match. Go on to the next one. */
+            if ($long_opt_name != $opt) {
+                continue;
+            }
+
+            $opt_rest  = substr($long_opt, $opt_len);
+
+            /* Check that the options uniquely matches one of the allowed
+               options. */
+            if ($i + 1 < count($long_options)) {
+                $next_option_rest = substr($long_options[$i + 1], $opt_len);
+            } else {
+                $next_option_rest = '';
+            }
+            if ($opt_rest != '' && $opt{0} != '=' &&
+                $i + 1 < count($long_options) &&
+                $opt == substr($long_options[$i+1], 0, $opt_len) &&
+                $next_option_rest != '' &&
+                $next_option_rest{0} != '=') {
+                return PEAR::raiseError("Console_Getopt: option --$opt is ambiguous");
+            }
+
+            if (substr($long_opt, -1) == '=') {
+                if (substr($long_opt, -2) != '==') {
+                    /* Long option requires an argument.
+                       Take the next argument if one wasn't specified. */;
+                    if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {
+                        return PEAR::raiseError("Console_Getopt: option --$opt requires an argument");
+                    }
+                    if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) {
+                        return PEAR::raiseError("Console_Getopt: option requires an argument --$opt");
+                    }
+                }
+            } else if ($opt_arg) {
+                return PEAR::raiseError("Console_Getopt: option --$opt doesn't allow an argument");
+            }
+
+            $opts[] = array('--' . $opt, $opt_arg);
+            return;
+        }
+
+        return PEAR::raiseError("Console_Getopt: unrecognized option --$opt");
+    }
+
+    /**
+    * Safely read the $argv PHP array across different PHP configurations.
+    * Will take care on register_globals and register_argc_argv ini directives
+    *
+    * @access public
+    * @return mixed the $argv PHP array or PEAR error if not registered
+    */
+    function readPHPArgv()
+    {
+        global $argv;
+        if (!is_array($argv)) {
+            if (!@is_array($_SERVER['argv'])) {
+                if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
+                    return PEAR::raiseError("Console_Getopt: Could not read cmd args (register_argc_argv=Off?)");
+                }
+                return $GLOBALS['HTTP_SERVER_VARS']['argv'];
+            }
+            return $_SERVER['argv'];
+        }
+        return $argv;
+    }
+
+}
+
+?>
diff --git a/lib/php/HTTP/Request2.php b/lib/php/HTTP/Request2.php
new file mode 100644
index 00000000..19dfe66a
--- /dev/null
+++ b/lib/php/HTTP/Request2.php
@@ -0,0 +1,861 @@
+<?php
+/**
+ * Class representing a HTTP request message
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290921 2009-11-18 17:31:58Z 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: 0.5.1
+ * @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;
+
+
+   /**
+    * 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/0.5.1 ' .
+                         '(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_Exception
+    */
+    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_Exception('Parameter is not a valid HTTP URL');
+        }
+        // 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_Exception 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_Exception("Invalid request method '{$method}'");
+        }
+        $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_Exception 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_Exception(
+                    "Unknown configuration parameter '{$nameOrConfig}'"
+                );
+            }
+            $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_Exception 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_Exception(
+                "Unknown configuration parameter '{$name}'"
+            );
+        }
+        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|null     header value, header will be removed if null
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_Exception
+    */
+    public function setHeader($name, $value = null)
+    {
+        if (is_array($name)) {
+            foreach ($name as $k => $v) {
+                if (is_string($k)) {
+                    $this->setHeader($k, $v);
+                } else {
+                    $this->setHeader($v);
+                }
+            }
+        } 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_Exception("Invalid header name '{$name}'");
+            }
+            // Header names are case insensitive anyway
+            $name = strtolower($name);
+            if (null === $value) {
+                unset($this->headers[$name]);
+            } 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;
+    }
+
+   /**
+    * Appends a cookie to "Cookie:" header
+    *
+    * @param    string  cookie name
+    * @param    string  cookie value
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_Exception
+    */
+    public function addCookie($name, $value)
+    {
+        $cookie = $name . '=' . $value;
+        if (preg_match(self::REGEXP_INVALID_COOKIE, $cookie)) {
+            throw new HTTP_Request2_Exception("Invalid cookie: '{$cookie}'");
+        }
+        $cookies = empty($this->headers['cookie'])? '': $this->headers['cookie'] . '; ';
+        $this->setHeader('cookie', $cookies . $cookie);
+
+        return $this;
+    }
+
+   /**
+    * Sets the request body
+    *
+    * @param    string  Either a string with the body or filename containing body
+    * @param    bool    Whether first parameter is a filename
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_Exception
+    */
+    public function setBody($body, $isFilename = false)
+    {
+        if (!$isFilename) {
+            if (!$body instanceof HTTP_Request2_MultipartBody) {
+                $this->body = (string)$body;
+            } else {
+                $this->body = $body;
+            }
+        } else {
+            if (!($fp = @fopen($body, 'rb'))) {
+                throw new HTTP_Request2_Exception("Cannot open file {$body}");
+            }
+            $this->body = $fp;
+            if (empty($this->headers['content-type'])) {
+                $this->setHeader('content-type', self::detectMimeType($body));
+            }
+        }
+        $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 ('application/x-www-form-urlencoded' == $this->headers['content-type']) {
+                $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 ('multipart/form-data' == $this->headers['content-type']) {
+                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.
+    *
+    * @param    string  name of file-upload field
+    * @param    mixed   full name of local file
+    * @param    string  filename to send in the request
+    * @param    string  content-type of file being uploaded
+    * @return   HTTP_Request2
+    * @throws   HTTP_Request2_Exception
+    */
+    public function addUpload($fieldName, $filename, $sendFilename = null,
+                              $contentType = null)
+    {
+        if (!is_array($filename)) {
+            if (!($fp = @fopen($filename, 'rb'))) {
+                throw new HTTP_Request2_Exception("Cannot open file {$filename}");
+            }
+            $this->uploads[$fieldName] = array(
+                'fp'        => $fp,
+                'filename'  => empty($sendFilename)? basename($filename): $sendFilename,
+                'size'      => filesize($filename),
+                'type'      => empty($contentType)? self::detectMimeType($filename): $contentType
+            );
+        } else {
+            $fps = $names = $sizes = $types = array();
+            foreach ($filename as $f) {
+                if (!is_array($f)) {
+                    $f = array($f);
+                }
+                if (!($fp = @fopen($f[0], 'rb'))) {
+                    throw new HTTP_Request2_Exception("Cannot open file {$f[0]}");
+                }
+                $fps[]   = $fp;
+                $names[] = empty($f[1])? basename($f[0]): $f[1];
+                $sizes[] = filesize($f[0]);
+                $types[] = empty($f[2])? self::detectMimeType($f[0]): $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>'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_Exception
+    */
+    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_Exception("Class {$adapter} not found");
+                }
+            }
+            $adapter = new $adapter;
+        }
+        if (!$adapter instanceof HTTP_Request2_Adapter) {
+            throw new HTTP_Request2_Exception('Parameter is not a HTTP request adapter');
+        }
+        $this->adapter = $adapter;
+
+        return $this;
+    }
+
+   /**
+    * 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) {
+            throw new HTTP_Request2_Exception('No URL given');
+        } elseif (!$this->url->isAbsolute()) {
+            throw new HTTP_Request2_Exception('Absolute URL required');
+        } elseif (!in_array(strtolower($this->url->getScheme()), array('https', 'http'))) {
+            throw new HTTP_Request2_Exception('Not a HTTP URL');
+        }
+        if (empty($this->adapter)) {
+            $this->setAdapter($this->getConfig('adapter'));
+        }
+        // magic_quotes_runtime may break file uploads and chunked response
+        // processing; see bug #4543
+        if ($magicQuotes = ini_get('magic_quotes_runtime')) {
+            ini_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) {
+            ini_set('magic_quotes_runtime', true);
+        }
+        if (!empty($oldEncoding)) {
+            mb_internal_encoding($oldEncoding);
+        }
+        // rethrow the exception
+        if (!empty($e)) {
+            throw $e;
+        }
+        return $response;
+    }
+
+   /**
+    * 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 00000000..16ff131b
--- /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, 2009, 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 291118 2009-11-21 17:58:23Z 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: 0.5.1
+ */
+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 00000000..77ab6fae
--- /dev/null
+++ b/lib/php/HTTP/Request2/Adapter/Curl.php
@@ -0,0 +1,461 @@
+<?php
+/**
+ * Adapter for HTTP_Request2 wrapping around cURL extension
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 291118 2009-11-21 17:58:23Z 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: 0.5.1
+ */
+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
+   );
+
+   /**
+    * 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;
+
+   /**
+    * 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_Exception('cURL extension not available');
+        }
+
+        $this->request              = $request;
+        $this->response             = null;
+        $this->position             = 0;
+        $this->eventSentHeaders     = false;
+        $this->eventReceivedHeaders = false;
+
+        try {
+            if (false === curl_exec($ch = $this->createCurlHandle())) {
+                $errorMessage = 'Error sending request: #' . curl_errno($ch) .
+                                                       ' ' . curl_error($ch);
+            }
+        } catch (Exception $e) {
+        }
+        $this->lastInfo = curl_getinfo($ch);
+        curl_close($ch);
+
+        $response = $this->response;
+        unset($this->request, $this->requestBody, $this->response);
+
+        if (!empty($e)) {
+            throw $e;
+        } elseif (!empty($errorMessage)) {
+            throw new HTTP_Request2_Exception($errorMessage);
+        }
+
+        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_Exception
+    */
+    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 {
+            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+            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 sometime after 5.3.0, 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;
+            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_Exception('Proxy port not provided');
+            }
+            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'] = '';
+        }
+
+        // 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;
+            }
+            $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);
+        } 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);
+                }
+                // for versions lower than 5.2.10, check the redirection URL protocol
+                if ($this->request->getConfig('follow_redirects') && !defined('CURLOPT_REDIR_PROTOCOLS')
+                    && $this->response->isRedirect()
+                ) {
+                    $redirectUrl = new Net_URL2($this->response->getHeader('location'));
+                    if ($redirectUrl->isAbsolute()
+                        && !in_array($redirectUrl->getScheme(), array('http', 'https'))
+                    ) {
+                        return -1;
+                    }
+                }
+                $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_Exception("Malformed response: {$string}");
+        }
+        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 00000000..2812ce93
--- /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, 2009, 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 290192 2009-11-03 21:29:32Z 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: 0.5.1
+ */
+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 00000000..6d1788c7
--- /dev/null
+++ b/lib/php/HTTP/Request2/Adapter/Socket.php
@@ -0,0 +1,1046 @@
+<?php
+/**
+ * Socket-based adapter for HTTP_Request2
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290921 2009-11-18 17:31:58Z 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: 0.5.1
+ */
+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_Exception('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_Exception(
+                    'Request timed out after ' .
+                    $request->getConfig('timeout') . ' second(s)'
+                );
+            }
+
+            $response = $this->readResponse();
+
+            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)) {
+            throw $e;
+        }
+
+        if (!$request->getConfig('follow_redirects') || !$response->isRedirect()) {
+            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_Exception('Proxy port not provided');
+            }
+            $proxy = true;
+        } else {
+            $host  = $reqHost;
+            $port  = $reqPort;
+            $proxy = false;
+        }
+
+        if ($tunnel && !$proxy) {
+            throw new HTTP_Request2_Exception(
+                "Trying to perform CONNECT request without proxy"
+            );
+        }
+        if ($secure && !in_array('ssl', stream_get_transports())) {
+            throw new HTTP_Request2_Exception(
+                'Need OpenSSL support for https:// requests'
+            );
+        }
+
+        // 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_Exception(
+                        "Error setting SSL context option '{$name}'"
+                    );
+                }
+            }
+            $this->socket = @stream_socket_client(
+                $remote, $errno, $errstr,
+                $this->request->getConfig('connect_timeout'),
+                STREAM_CLIENT_CONNECT, $context
+            );
+            if (!$this->socket) {
+                throw new HTTP_Request2_Exception(
+                    "Unable to connect to {$remote}. Error #{$errno}: {$errstr}"
+                );
+            }
+            $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_Exception(
+                '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_Exception(
+            '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');
+        $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) {
+            // Copying cURL behaviour
+            throw new HTTP_Request2_Exception(
+                'Maximum (' . $request->getConfig('max_redirects') . ') redirects followed'
+            );
+        }
+        $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'))
+        ) {
+            throw new HTTP_Request2_Exception(
+                'Refusing to redirect to a non-HTTP URL ' . $redirectUrl->__toString()
+            );
+        }
+        // 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_Exception 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_Exception(
+                "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_Exception(
+                "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_Exception
+    */
+    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_Exception(
+                    "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_Exception
+    */
+    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_Exception(
+                    "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';
+        }
+
+        $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_Exception
+    */
+    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_Exception('Error writing request');
+            }
+            // Provide the length of written string to the observer, request #7630
+            $this->request->setLastEvent('sentBodyPart', strlen($str));
+            $position += strlen($str);
+        }
+    }
+
+   /**
+    * 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);
+            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_Exception     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_Exception("Request timed out {$reason}");
+            }
+            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_Exception     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_Exception("Request timed out {$reason}");
+        }
+        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_Exception
+    */
+    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_Exception(
+                    "Cannot decode chunked response, invalid chunk length '{$line}'"
+                );
+            } 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/Exception.php b/lib/php/HTTP/Request2/Exception.php
new file mode 100644
index 00000000..d86a1440
--- /dev/null
+++ b/lib/php/HTTP/Request2/Exception.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Exception class for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290192 2009-11-03 21:29:32Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Base class for exceptions in PEAR
+ */
+require_once 'PEAR/Exception.php';
+
+/**
+ * Exception class for HTTP_Request2 package
+ *
+ * Such a class is required by the Exception RFC:
+ * http://pear.php.net/pepr/pepr-proposal-show.php?id=132
+ *
+ * @category   HTTP
+ * @package    HTTP_Request2
+ * @version    Release: 0.5.1
+ */
+class HTTP_Request2_Exception extends PEAR_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 00000000..efc2e254
--- /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, 2009, 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 290192 2009-11-03 21:29:32Z 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: 0.5.1
+ * @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 00000000..e7a064b9
--- /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, 2009, 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 290743 2009-11-14 13:27:49Z 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: 0.5.1
+ * @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',
+        'sentBodyPart',
+        '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, 'w'))) {
+            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 'sentBodyPart':
+            $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 00000000..217fbdf6
--- /dev/null
+++ b/lib/php/HTTP/Request2/Response.php
@@ -0,0 +1,559 @@
+<?php
+/**
+ * Class representing a HTTP response
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290520 2009-11-11 20:09:42Z 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: 0.5.1
+ * @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;
+
+   /**
+    * 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
+    * @throws   HTTP_Request2_Exception if status line is invalid according to spec
+    */
+    public function __construct($statusLine, $bodyEncoded = true)
+    {
+        if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) {
+            throw new HTTP_Request2_Exception("Malformed response: {$statusLine}");
+        }
+        $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;
+    }
+
+   /**
+    * 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 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 (!$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_Exception
+    * @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_Exception('Unable to decode body: gzip extension not available');
+        }
+        $method = ord(substr($data, 2, 1));
+        if (8 != $method) {
+            throw new HTTP_Request2_Exception('Error parsing gzip header: unknown compression method');
+        }
+        $flags = ord(substr($data, 3, 1));
+        if ($flags & 224) {
+            throw new HTTP_Request2_Exception('Error parsing gzip header: reserved bits are set');
+        }
+
+        // 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_Exception('Error parsing gzip header: data too short');
+            }
+            $extraLength = unpack('v', substr($data, 10, 2));
+            if ($length - $headerLength - 2 - $extraLength[1] < 8) {
+                throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+            }
+            $headerLength += $extraLength[1] + 2;
+        }
+        // file name, need to skip that
+        if ($flags & 8) {
+            if ($length - $headerLength - 1 < 8) {
+                throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+            }
+            $filenameLength = strpos(substr($data, $headerLength), chr(0));
+            if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 8) {
+                throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+            }
+            $headerLength += $filenameLength + 1;
+        }
+        // comment, need to skip that also
+        if ($flags & 16) {
+            if ($length - $headerLength - 1 < 8) {
+                throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+            }
+            $commentLength = strpos(substr($data, $headerLength), chr(0));
+            if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 8) {
+                throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+            }
+            $headerLength += $commentLength + 1;
+        }
+        // have a CRC for header. let's check
+        if ($flags & 2) {
+            if ($length - $headerLength - 2 < 8) {
+                throw new HTTP_Request2_Exception('Error parsing gzip header: data too short');
+            }
+            $crcReal   = 0xffff & crc32(substr($data, 0, $headerLength));
+            $crcStored = unpack('v', substr($data, $headerLength, 2));
+            if ($crcReal != $crcStored[1]) {
+                throw new HTTP_Request2_Exception('Header CRC check failed');
+            }
+            $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_Exception('gzinflate() call failed');
+        } elseif ($dataSize != strlen($unpacked)) {
+            throw new HTTP_Request2_Exception('Data size check failed');
+        } elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) {
+            throw new HTTP_Request2_Exception('Data CRC check failed');
+        }
+        return $unpacked;
+    }
+
+   /**
+    * Decodes the message-body encoded by deflate
+    *
+    * @param    string  deflate-encoded data
+    * @return   string  decoded data
+    * @throws   HTTP_Request2_Exception
+    */
+    public static function decodeDeflate($data)
+    {
+        if (!function_exists('gzuncompress')) {
+            throw new HTTP_Request2_Exception('Unable to decode body: gzip extension not available');
+        }
+        // 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 00000000..bbc9f124
--- /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/OS/Guess.php b/lib/php/OS/Guess.php
new file mode 100644
index 00000000..98948e3f
--- /dev/null
+++ b/lib/php/OS/Guess.php
@@ -0,0 +1,338 @@
+<?php
+/**
+ * The OS_Guess class
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Gregory Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Guess.php 278521 2009-04-09 22:24:12Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since PEAR 0.1
+ */
+
+// {{{ uname examples
+
+// php_uname() without args returns the same as 'uname -a', or a PHP-custom
+// string for Windows.
+// PHP versions prior to 4.3 return the uname of the host where PHP was built,
+// as of 4.3 it returns the uname of the host running the PHP code.
+//
+// PC RedHat Linux 7.1:
+// Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
+//
+// PC Debian Potato:
+// Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown
+//
+// PC FreeBSD 3.3:
+// FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000     root@example.com:/usr/src/sys/compile/CONFIG  i386
+//
+// PC FreeBSD 4.3:
+// FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001     root@example.com:/usr/src/sys/compile/CONFIG  i386
+//
+// PC FreeBSD 4.5:
+// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb  6 23:59:23 CET 2002     root@example.com:/usr/src/sys/compile/CONFIG  i386
+//
+// PC FreeBSD 4.5 w/uname from GNU shellutils:
+// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb  i386 unknown
+//
+// HP 9000/712 HP-UX 10:
+// HP-UX iq B.10.10 A 9000/712 2008429113 two-user license
+//
+// HP 9000/712 HP-UX 10 w/uname from GNU shellutils:
+// HP-UX host B.10.10 A 9000/712 unknown
+//
+// IBM RS6000/550 AIX 4.3:
+// AIX host 3 4 000003531C00
+//
+// AIX 4.3 w/uname from GNU shellutils:
+// AIX host 3 4 000003531C00 unknown
+//
+// SGI Onyx IRIX 6.5 w/uname from GNU shellutils:
+// IRIX64 host 6.5 01091820 IP19 mips
+//
+// SGI Onyx IRIX 6.5:
+// IRIX64 host 6.5 01091820 IP19
+//
+// SparcStation 20 Solaris 8 w/uname from GNU shellutils:
+// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc
+//
+// SparcStation 20 Solaris 8:
+// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20
+//
+// Mac OS X (Darwin)
+// Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug  5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC  Power Macintosh
+//
+// Mac OS X early versions
+//
+
+// }}}
+
+/* TODO:
+ * - define endianness, to allow matchSignature("bigend") etc.
+ */
+
+/**
+ * Retrieves information about the current operating system
+ *
+ * This class uses php_uname() to grok information about the current OS
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Gregory Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class OS_Guess
+{
+    var $sysname;
+    var $nodename;
+    var $cpu;
+    var $release;
+    var $extra;
+
+    function OS_Guess($uname = null)
+    {
+        list($this->sysname,
+             $this->release,
+             $this->cpu,
+             $this->extra,
+             $this->nodename) = $this->parseSignature($uname);
+    }
+
+    function parseSignature($uname = null)
+    {
+        static $sysmap = array(
+            'HP-UX' => 'hpux',
+            'IRIX64' => 'irix',
+        );
+        static $cpumap = array(
+            'i586' => 'i386',
+            'i686' => 'i386',
+            'ppc' => 'powerpc',
+        );
+        if ($uname === null) {
+            $uname = php_uname();
+        }
+        $parts = preg_split('/\s+/', trim($uname));
+        $n = count($parts);
+
+        $release  = $machine = $cpu = '';
+        $sysname  = $parts[0];
+        $nodename = $parts[1];
+        $cpu      = $parts[$n-1];
+        $extra = '';
+        if ($cpu == 'unknown') {
+            $cpu = $parts[$n - 2];
+        }
+
+        switch ($sysname) {
+            case 'AIX' :
+                $release = "$parts[3].$parts[2]";
+                break;
+            case 'Windows' :
+                switch ($parts[1]) {
+                    case '95/98':
+                        $release = '9x';
+                        break;
+                    default:
+                        $release = $parts[1];
+                        break;
+                }
+                $cpu = 'i386';
+                break;
+            case 'Linux' :
+                $extra = $this->_detectGlibcVersion();
+                // use only the first two digits from the kernel version
+                $release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
+                break;
+            case 'Mac' :
+                $sysname = 'darwin';
+                $nodename = $parts[2];
+                $release = $parts[3];
+                if ($cpu == 'Macintosh') {
+                    if ($parts[$n - 2] == 'Power') {
+                        $cpu = 'powerpc';
+                    }
+                }
+                break;
+            case 'Darwin' :
+                if ($cpu == 'Macintosh') {
+                    if ($parts[$n - 2] == 'Power') {
+                        $cpu = 'powerpc';
+                    }
+                }
+                $release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
+                break;
+            default:
+                $release = preg_replace('/-.*/', '', $parts[2]);
+                break;
+        }
+
+        if (isset($sysmap[$sysname])) {
+            $sysname = $sysmap[$sysname];
+        } else {
+            $sysname = strtolower($sysname);
+        }
+        if (isset($cpumap[$cpu])) {
+            $cpu = $cpumap[$cpu];
+        }
+        return array($sysname, $release, $cpu, $extra, $nodename);
+    }
+
+    function _detectGlibcVersion()
+    {
+        static $glibc = false;
+        if ($glibc !== false) {
+            return $glibc; // no need to run this multiple times
+        }
+        $major = $minor = 0;
+        include_once "System.php";
+        // Use glibc's <features.h> header file to
+        // get major and minor version number:
+        if (@file_exists('/usr/include/features.h') &&
+              @is_readable('/usr/include/features.h')) {
+            if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) {
+                $features_file = fopen('/usr/include/features.h', 'rb');
+                while (!feof($features_file)) {
+                    $line = fgets($features_file, 8192);
+                    if (!$line || (strpos($line, '#define') === false)) {
+                        continue;
+                    }
+                    if (strpos($line, '__GLIBC__')) {
+                        // major version number #define __GLIBC__ version
+                        $line = preg_split('/\s+/', $line);
+                        $glibc_major = trim($line[2]);
+                        if (isset($glibc_minor)) {
+                            break;
+                        }
+                        continue;
+                    }
+
+                    if (strpos($line, '__GLIBC_MINOR__'))  {
+                        // got the minor version number
+                        // #define __GLIBC_MINOR__ version
+                        $line = preg_split('/\s+/', $line);
+                        $glibc_minor = trim($line[2]);
+                        if (isset($glibc_major)) {
+                            break;
+                        }
+                        continue;
+                    }
+                }
+                fclose($features_file);
+                if (!isset($glibc_major) || !isset($glibc_minor)) {
+                    return $glibc = '';
+                }
+                return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor) ;
+            } // no cpp
+
+            $tmpfile = System::mktemp("glibctest");
+            $fp = fopen($tmpfile, "w");
+            fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n");
+            fclose($fp);
+            $cpp = popen("/usr/bin/cpp $tmpfile", "r");
+            while ($line = fgets($cpp, 1024)) {
+                if ($line{0} == '#' || trim($line) == '') {
+                    continue;
+                }
+
+                if (list($major, $minor) = explode(' ', trim($line))) {
+                    break;
+                }
+            }
+            pclose($cpp);
+            unlink($tmpfile);
+        } // features.h
+
+        if (!($major && $minor) && @is_link('/lib/libc.so.6')) {
+            // Let's try reading the libc.so.6 symlink
+            if (preg_match('/^libc-(.*)\.so$/', basename(readlink('/lib/libc.so.6')), $matches)) {
+                list($major, $minor) = explode('.', $matches[1]);
+            }
+        }
+
+        if (!($major && $minor)) {
+            return $glibc = '';
+        }
+
+        return $glibc = "glibc{$major}.{$minor}";
+    }
+
+    function getSignature()
+    {
+        if (empty($this->extra)) {
+            return "{$this->sysname}-{$this->release}-{$this->cpu}";
+        }
+        return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}";
+    }
+
+    function getSysname()
+    {
+        return $this->sysname;
+    }
+
+    function getNodename()
+    {
+        return $this->nodename;
+    }
+
+    function getCpu()
+    {
+        return $this->cpu;
+    }
+
+    function getRelease()
+    {
+        return $this->release;
+    }
+
+    function getExtra()
+    {
+        return $this->extra;
+    }
+
+    function matchSignature($match)
+    {
+        $fragments = is_array($match) ? $match : explode('-', $match);
+        $n = count($fragments);
+        $matches = 0;
+        if ($n > 0) {
+            $matches += $this->_matchFragment($fragments[0], $this->sysname);
+        }
+        if ($n > 1) {
+            $matches += $this->_matchFragment($fragments[1], $this->release);
+        }
+        if ($n > 2) {
+            $matches += $this->_matchFragment($fragments[2], $this->cpu);
+        }
+        if ($n > 3) {
+            $matches += $this->_matchFragment($fragments[3], $this->extra);
+        }
+        return ($matches == $n);
+    }
+
+    function _matchFragment($fragment, $value)
+    {
+        if (strcspn($fragment, '*?') < strlen($fragment)) {
+            $reg = '/^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '\\z/';
+            return preg_match($reg, $value);
+        }
+        return ($fragment == '*' || !strcasecmp($fragment, $value));
+    }
+
+}
+/*
+ * Local Variables:
+ * indent-tabs-mode: nil
+ * c-basic-offset: 4
+ * End:
+ */
\ No newline at end of file
diff --git a/lib/php/PEAR.php b/lib/php/PEAR.php
new file mode 100644
index 00000000..d48ee828
--- /dev/null
+++ b/lib/php/PEAR.php
@@ -0,0 +1,1137 @@
+<?php
+/**
+ * PEAR, the PHP Extension and Application Repository
+ *
+ * PEAR class and PEAR_Error class
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Sterling Hughes <sterling@php.net>
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: PEAR.php 286670 2009-08-02 14:16:06Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**#@+
+ * ERROR constants
+ */
+define('PEAR_ERROR_RETURN',     1);
+define('PEAR_ERROR_PRINT',      2);
+define('PEAR_ERROR_TRIGGER',    4);
+define('PEAR_ERROR_DIE',        8);
+define('PEAR_ERROR_CALLBACK',  16);
+/**
+ * WARNING: obsolete
+ * @deprecated
+ */
+define('PEAR_ERROR_EXCEPTION', 32);
+/**#@-*/
+define('PEAR_ZE2', (function_exists('version_compare') &&
+                    version_compare(zend_version(), "2-dev", "ge")));
+
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+    define('OS_WINDOWS', true);
+    define('OS_UNIX',    false);
+    define('PEAR_OS',    'Windows');
+} else {
+    define('OS_WINDOWS', false);
+    define('OS_UNIX',    true);
+    define('PEAR_OS',    'Unix'); // blatant assumption
+}
+
+$GLOBALS['_PEAR_default_error_mode']     = PEAR_ERROR_RETURN;
+$GLOBALS['_PEAR_default_error_options']  = E_USER_NOTICE;
+$GLOBALS['_PEAR_destructor_object_list'] = array();
+$GLOBALS['_PEAR_shutdown_funcs']         = array();
+$GLOBALS['_PEAR_error_handler_stack']    = array();
+
+@ini_set('track_errors', true);
+
+/**
+ * Base class for other PEAR classes.  Provides rudimentary
+ * emulation of destructors.
+ *
+ * If you want a destructor in your class, inherit PEAR and make a
+ * destructor method called _yourclassname (same name as the
+ * constructor, but with a "_" prefix).  Also, in your constructor you
+ * have to call the PEAR constructor: $this->PEAR();.
+ * The destructor method will be called without parameters.  Note that
+ * at in some SAPI implementations (such as Apache), any output during
+ * the request shutdown (in which destructors are called) seems to be
+ * discarded.  If you need to get any debug information from your
+ * destructor, use error_log(), syslog() or something similar.
+ *
+ * IMPORTANT! To use the emulated destructors you need to create the
+ * objects by reference: $obj =& new PEAR_child;
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V.V. Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2006 The PHP Group
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @see        PEAR_Error
+ * @since      Class available since PHP 4.0.2
+ * @link        http://pear.php.net/manual/en/core.pear.php#core.pear.pear
+ */
+class PEAR
+{
+    // {{{ properties
+
+    /**
+     * Whether to enable internal debug messages.
+     *
+     * @var     bool
+     * @access  private
+     */
+    var $_debug = false;
+
+    /**
+     * Default error mode for this object.
+     *
+     * @var     int
+     * @access  private
+     */
+    var $_default_error_mode = null;
+
+    /**
+     * Default error options used for this object when error mode
+     * is PEAR_ERROR_TRIGGER.
+     *
+     * @var     int
+     * @access  private
+     */
+    var $_default_error_options = null;
+
+    /**
+     * Default error handler (callback) for this object, if error mode is
+     * PEAR_ERROR_CALLBACK.
+     *
+     * @var     string
+     * @access  private
+     */
+    var $_default_error_handler = '';
+
+    /**
+     * Which class to use for error objects.
+     *
+     * @var     string
+     * @access  private
+     */
+    var $_error_class = 'PEAR_Error';
+
+    /**
+     * An array of expected errors.
+     *
+     * @var     array
+     * @access  private
+     */
+    var $_expected_errors = array();
+
+    // }}}
+
+    // {{{ constructor
+
+    /**
+     * Constructor.  Registers this object in
+     * $_PEAR_destructor_object_list for destructor emulation if a
+     * destructor object exists.
+     *
+     * @param string $error_class  (optional) which class to use for
+     *        error objects, defaults to PEAR_Error.
+     * @access public
+     * @return void
+     */
+    function PEAR($error_class = null)
+    {
+        $classname = strtolower(get_class($this));
+        if ($this->_debug) {
+            print "PEAR constructor called, class=$classname\n";
+        }
+        if ($error_class !== null) {
+            $this->_error_class = $error_class;
+        }
+        while ($classname && strcasecmp($classname, "pear")) {
+            $destructor = "_$classname";
+            if (method_exists($this, $destructor)) {
+                global $_PEAR_destructor_object_list;
+                $_PEAR_destructor_object_list[] = &$this;
+                if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
+                    register_shutdown_function("_PEAR_call_destructors");
+                    $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
+                }
+                break;
+            } else {
+                $classname = get_parent_class($classname);
+            }
+        }
+    }
+
+    // }}}
+    // {{{ destructor
+
+    /**
+     * Destructor (the emulated type of...).  Does nothing right now,
+     * but is included for forward compatibility, so subclass
+     * destructors should always call it.
+     *
+     * See the note in the class desciption about output from
+     * destructors.
+     *
+     * @access public
+     * @return void
+     */
+    function _PEAR() {
+        if ($this->_debug) {
+            printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
+        }
+    }
+
+    // }}}
+    // {{{ getStaticProperty()
+
+    /**
+    * If you have a class that's mostly/entirely static, and you need static
+    * properties, you can use this method to simulate them. Eg. in your method(s)
+    * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
+    * You MUST use a reference, or they will not persist!
+    *
+    * @access public
+    * @param  string $class  The calling classname, to prevent clashes
+    * @param  string $var    The variable to retrieve.
+    * @return mixed   A reference to the variable. If not set it will be
+    *                 auto initialised to NULL.
+    */
+    function &getStaticProperty($class, $var)
+    {
+        static $properties;
+        if (!isset($properties[$class])) {
+            $properties[$class] = array();
+        }
+
+        if (!array_key_exists($var, $properties[$class])) {
+            $properties[$class][$var] = null;
+        }
+
+        return $properties[$class][$var];
+    }
+
+    // }}}
+    // {{{ registerShutdownFunc()
+
+    /**
+    * Use this function to register a shutdown method for static
+    * classes.
+    *
+    * @access public
+    * @param  mixed $func  The function name (or array of class/method) to call
+    * @param  mixed $args  The arguments to pass to the function
+    * @return void
+    */
+    function registerShutdownFunc($func, $args = array())
+    {
+        // if we are called statically, there is a potential
+        // that no shutdown func is registered.  Bug #6445
+        if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
+            register_shutdown_function("_PEAR_call_destructors");
+            $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
+        }
+        $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
+    }
+
+    // }}}
+    // {{{ isError()
+
+    /**
+     * Tell whether a value is a PEAR error.
+     *
+     * @param   mixed $data   the value to test
+     * @param   int   $code   if $data is an error object, return true
+     *                        only if $code is a string and
+     *                        $obj->getMessage() == $code or
+     *                        $code is an integer and $obj->getCode() == $code
+     * @access  public
+     * @return  bool    true if parameter is an error
+     */
+    function isError($data, $code = null)
+    {
+        if (!is_a($data, 'PEAR_Error')) {
+            return false;
+        }
+
+        if (is_null($code)) {
+            return true;
+        } elseif (is_string($code)) {
+            return $data->getMessage() == $code;
+        }
+
+        return $data->getCode() == $code;
+    }
+
+    // }}}
+    // {{{ setErrorHandling()
+
+    /**
+     * Sets how errors generated by this object should be handled.
+     * Can be invoked both in objects and statically.  If called
+     * statically, setErrorHandling sets the default behaviour for all
+     * PEAR objects.  If called in an object, setErrorHandling sets
+     * the default behaviour for that object.
+     *
+     * @param int $mode
+     *        One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
+     *        PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
+     *        PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
+     *
+     * @param mixed $options
+     *        When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
+     *        of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
+     *
+     *        When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
+     *        to be the callback function or method.  A callback
+     *        function is a string with the name of the function, a
+     *        callback method is an array of two elements: the element
+     *        at index 0 is the object, and the element at index 1 is
+     *        the name of the method to call in the object.
+     *
+     *        When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
+     *        a printf format string used when printing the error
+     *        message.
+     *
+     * @access public
+     * @return void
+     * @see PEAR_ERROR_RETURN
+     * @see PEAR_ERROR_PRINT
+     * @see PEAR_ERROR_TRIGGER
+     * @see PEAR_ERROR_DIE
+     * @see PEAR_ERROR_CALLBACK
+     * @see PEAR_ERROR_EXCEPTION
+     *
+     * @since PHP 4.0.5
+     */
+
+    function setErrorHandling($mode = null, $options = null)
+    {
+        if (isset($this) && is_a($this, 'PEAR')) {
+            $setmode     = &$this->_default_error_mode;
+            $setoptions  = &$this->_default_error_options;
+        } else {
+            $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
+            $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
+        }
+
+        switch ($mode) {
+            case PEAR_ERROR_EXCEPTION:
+            case PEAR_ERROR_RETURN:
+            case PEAR_ERROR_PRINT:
+            case PEAR_ERROR_TRIGGER:
+            case PEAR_ERROR_DIE:
+            case null:
+                $setmode = $mode;
+                $setoptions = $options;
+                break;
+
+            case PEAR_ERROR_CALLBACK:
+                $setmode = $mode;
+                // class/object method callback
+                if (is_callable($options)) {
+                    $setoptions = $options;
+                } else {
+                    trigger_error("invalid error callback", E_USER_WARNING);
+                }
+                break;
+
+            default:
+                trigger_error("invalid error mode", E_USER_WARNING);
+                break;
+        }
+    }
+
+    // }}}
+    // {{{ expectError()
+
+    /**
+     * This method is used to tell which errors you expect to get.
+     * Expected errors are always returned with error mode
+     * PEAR_ERROR_RETURN.  Expected error codes are stored in a stack,
+     * and this method pushes a new element onto it.  The list of
+     * expected errors are in effect until they are popped off the
+     * stack with the popExpect() method.
+     *
+     * Note that this method can not be called statically
+     *
+     * @param mixed $code a single error code or an array of error codes to expect
+     *
+     * @return int     the new depth of the "expected errors" stack
+     * @access public
+     */
+    function expectError($code = '*')
+    {
+        if (is_array($code)) {
+            array_push($this->_expected_errors, $code);
+        } else {
+            array_push($this->_expected_errors, array($code));
+        }
+        return sizeof($this->_expected_errors);
+    }
+
+    // }}}
+    // {{{ popExpect()
+
+    /**
+     * This method pops one element off the expected error codes
+     * stack.
+     *
+     * @return array   the list of error codes that were popped
+     */
+    function popExpect()
+    {
+        return array_pop($this->_expected_errors);
+    }
+
+    // }}}
+    // {{{ _checkDelExpect()
+
+    /**
+     * This method checks unsets an error code if available
+     *
+     * @param mixed error code
+     * @return bool true if the error code was unset, false otherwise
+     * @access private
+     * @since PHP 4.3.0
+     */
+    function _checkDelExpect($error_code)
+    {
+        $deleted = false;
+
+        foreach ($this->_expected_errors AS $key => $error_array) {
+            if (in_array($error_code, $error_array)) {
+                unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
+                $deleted = true;
+            }
+
+            // clean up empty arrays
+            if (0 == count($this->_expected_errors[$key])) {
+                unset($this->_expected_errors[$key]);
+            }
+        }
+        return $deleted;
+    }
+
+    // }}}
+    // {{{ delExpect()
+
+    /**
+     * This method deletes all occurences of the specified element from
+     * the expected error codes stack.
+     *
+     * @param  mixed $error_code error code that should be deleted
+     * @return mixed list of error codes that were deleted or error
+     * @access public
+     * @since PHP 4.3.0
+     */
+    function delExpect($error_code)
+    {
+        $deleted = false;
+        if ((is_array($error_code) && (0 != count($error_code)))) {
+            // $error_code is a non-empty array here;
+            // we walk through it trying to unset all
+            // values
+            foreach($error_code as $key => $error) {
+                if ($this->_checkDelExpect($error)) {
+                    $deleted =  true;
+                } else {
+                    $deleted = false;
+                }
+            }
+            return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
+        } elseif (!empty($error_code)) {
+            // $error_code comes alone, trying to unset it
+            if ($this->_checkDelExpect($error_code)) {
+                return true;
+            } else {
+                return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
+            }
+        }
+
+        // $error_code is empty
+        return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
+    }
+
+    // }}}
+    // {{{ raiseError()
+
+    /**
+     * This method is a wrapper that returns an instance of the
+     * configured error class with this object's default error
+     * handling applied.  If the $mode and $options parameters are not
+     * specified, the object's defaults are used.
+     *
+     * @param mixed $message a text error message or a PEAR error object
+     *
+     * @param int $code      a numeric error code (it is up to your class
+     *                  to define these if you want to use codes)
+     *
+     * @param int $mode      One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
+     *                  PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
+     *                  PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
+     *
+     * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
+     *                  specifies the PHP-internal error level (one of
+     *                  E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
+     *                  If $mode is PEAR_ERROR_CALLBACK, this
+     *                  parameter specifies the callback function or
+     *                  method.  In other error modes this parameter
+     *                  is ignored.
+     *
+     * @param string $userinfo If you need to pass along for example debug
+     *                  information, this parameter is meant for that.
+     *
+     * @param string $error_class The returned error object will be
+     *                  instantiated from this class, if specified.
+     *
+     * @param bool $skipmsg If true, raiseError will only pass error codes,
+     *                  the error message parameter will be dropped.
+     *
+     * @access public
+     * @return object   a PEAR error object
+     * @see PEAR::setErrorHandling
+     * @since PHP 4.0.5
+     */
+    function &raiseError($message = null,
+                         $code = null,
+                         $mode = null,
+                         $options = null,
+                         $userinfo = null,
+                         $error_class = null,
+                         $skipmsg = false)
+    {
+        // The error is yet a PEAR error object
+        if (is_object($message)) {
+            $code        = $message->getCode();
+            $userinfo    = $message->getUserInfo();
+            $error_class = $message->getType();
+            $message->error_message_prefix = '';
+            $message     = $message->getMessage();
+        }
+
+        if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
+            if ($exp[0] == "*" ||
+                (is_int(reset($exp)) && in_array($code, $exp)) ||
+                (is_string(reset($exp)) && in_array($message, $exp))) {
+                $mode = PEAR_ERROR_RETURN;
+            }
+        }
+
+        // No mode given, try global ones
+        if ($mode === null) {
+            // Class error handler
+            if (isset($this) && isset($this->_default_error_mode)) {
+                $mode    = $this->_default_error_mode;
+                $options = $this->_default_error_options;
+            // Global error handler
+            } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
+                $mode    = $GLOBALS['_PEAR_default_error_mode'];
+                $options = $GLOBALS['_PEAR_default_error_options'];
+            }
+        }
+
+        if ($error_class !== null) {
+            $ec = $error_class;
+        } elseif (isset($this) && isset($this->_error_class)) {
+            $ec = $this->_error_class;
+        } else {
+            $ec = 'PEAR_Error';
+        }
+
+        if (intval(PHP_VERSION) < 5) {
+            // little non-eval hack to fix bug #12147
+            include 'PEAR/FixPHP5PEARWarnings.php';
+            return $a;
+        }
+
+        if ($skipmsg) {
+            $a = new $ec($code, $mode, $options, $userinfo);
+        } else {
+            $a = new $ec($message, $code, $mode, $options, $userinfo);
+        }
+
+        return $a;
+    }
+
+    // }}}
+    // {{{ throwError()
+
+    /**
+     * Simpler form of raiseError with fewer options.  In most cases
+     * message, code and userinfo are enough.
+     *
+     * @param string $message
+     *
+     */
+    function &throwError($message = null,
+                         $code = null,
+                         $userinfo = null)
+    {
+        if (isset($this) && is_a($this, 'PEAR')) {
+            $a = &$this->raiseError($message, $code, null, null, $userinfo);
+            return $a;
+        }
+
+        $a = &PEAR::raiseError($message, $code, null, null, $userinfo);
+        return $a;
+    }
+
+    // }}}
+    function staticPushErrorHandling($mode, $options = null)
+    {
+        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
+        $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
+        $def_options = &$GLOBALS['_PEAR_default_error_options'];
+        $stack[] = array($def_mode, $def_options);
+        switch ($mode) {
+            case PEAR_ERROR_EXCEPTION:
+            case PEAR_ERROR_RETURN:
+            case PEAR_ERROR_PRINT:
+            case PEAR_ERROR_TRIGGER:
+            case PEAR_ERROR_DIE:
+            case null:
+                $def_mode = $mode;
+                $def_options = $options;
+                break;
+
+            case PEAR_ERROR_CALLBACK:
+                $def_mode = $mode;
+                // class/object method callback
+                if (is_callable($options)) {
+                    $def_options = $options;
+                } else {
+                    trigger_error("invalid error callback", E_USER_WARNING);
+                }
+                break;
+
+            default:
+                trigger_error("invalid error mode", E_USER_WARNING);
+                break;
+        }
+        $stack[] = array($mode, $options);
+        return true;
+    }
+
+    function staticPopErrorHandling()
+    {
+        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
+        $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
+        $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
+        array_pop($stack);
+        list($mode, $options) = $stack[sizeof($stack) - 1];
+        array_pop($stack);
+        switch ($mode) {
+            case PEAR_ERROR_EXCEPTION:
+            case PEAR_ERROR_RETURN:
+            case PEAR_ERROR_PRINT:
+            case PEAR_ERROR_TRIGGER:
+            case PEAR_ERROR_DIE:
+            case null:
+                $setmode = $mode;
+                $setoptions = $options;
+                break;
+
+            case PEAR_ERROR_CALLBACK:
+                $setmode = $mode;
+                // class/object method callback
+                if (is_callable($options)) {
+                    $setoptions = $options;
+                } else {
+                    trigger_error("invalid error callback", E_USER_WARNING);
+                }
+                break;
+
+            default:
+                trigger_error("invalid error mode", E_USER_WARNING);
+                break;
+        }
+        return true;
+    }
+
+    // {{{ pushErrorHandling()
+
+    /**
+     * Push a new error handler on top of the error handler options stack. With this
+     * you can easily override the actual error handler for some code and restore
+     * it later with popErrorHandling.
+     *
+     * @param mixed $mode (same as setErrorHandling)
+     * @param mixed $options (same as setErrorHandling)
+     *
+     * @return bool Always true
+     *
+     * @see PEAR::setErrorHandling
+     */
+    function pushErrorHandling($mode, $options = null)
+    {
+        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
+        if (isset($this) && is_a($this, 'PEAR')) {
+            $def_mode    = &$this->_default_error_mode;
+            $def_options = &$this->_default_error_options;
+        } else {
+            $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
+            $def_options = &$GLOBALS['_PEAR_default_error_options'];
+        }
+        $stack[] = array($def_mode, $def_options);
+
+        if (isset($this) && is_a($this, 'PEAR')) {
+            $this->setErrorHandling($mode, $options);
+        } else {
+            PEAR::setErrorHandling($mode, $options);
+        }
+        $stack[] = array($mode, $options);
+        return true;
+    }
+
+    // }}}
+    // {{{ popErrorHandling()
+
+    /**
+    * Pop the last error handler used
+    *
+    * @return bool Always true
+    *
+    * @see PEAR::pushErrorHandling
+    */
+    function popErrorHandling()
+    {
+        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
+        array_pop($stack);
+        list($mode, $options) = $stack[sizeof($stack) - 1];
+        array_pop($stack);
+        if (isset($this) && is_a($this, 'PEAR')) {
+            $this->setErrorHandling($mode, $options);
+        } else {
+            PEAR::setErrorHandling($mode, $options);
+        }
+        return true;
+    }
+
+    // }}}
+    // {{{ loadExtension()
+
+    /**
+    * OS independant PHP extension load. Remember to take care
+    * on the correct extension name for case sensitive OSes.
+    *
+    * @param string $ext The extension name
+    * @return bool Success or not on the dl() call
+    */
+    function loadExtension($ext)
+    {
+        if (!extension_loaded($ext)) {
+            // if either returns true dl() will produce a FATAL error, stop that
+            if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
+                return false;
+            }
+
+            if (OS_WINDOWS) {
+                $suffix = '.dll';
+            } elseif (PHP_OS == 'HP-UX') {
+                $suffix = '.sl';
+            } elseif (PHP_OS == 'AIX') {
+                $suffix = '.a';
+            } elseif (PHP_OS == 'OSX') {
+                $suffix = '.bundle';
+            } else {
+                $suffix = '.so';
+            }
+
+            return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
+        }
+
+        return true;
+    }
+
+    // }}}
+}
+
+if (PEAR_ZE2) {
+    include_once 'PEAR5.php';
+}
+
+// {{{ _PEAR_call_destructors()
+
+function _PEAR_call_destructors()
+{
+    global $_PEAR_destructor_object_list;
+    if (is_array($_PEAR_destructor_object_list) &&
+        sizeof($_PEAR_destructor_object_list))
+    {
+        reset($_PEAR_destructor_object_list);
+        if (PEAR_ZE2) {
+            $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo');
+        } else {
+            $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
+        }
+
+        if ($destructLifoExists) {
+            $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
+        }
+
+        while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
+            $classname = get_class($objref);
+            while ($classname) {
+                $destructor = "_$classname";
+                if (method_exists($objref, $destructor)) {
+                    $objref->$destructor();
+                    break;
+                } else {
+                    $classname = get_parent_class($classname);
+                }
+            }
+        }
+        // Empty the object list to ensure that destructors are
+        // not called more than once.
+        $_PEAR_destructor_object_list = array();
+    }
+
+    // Now call the shutdown functions
+    if (isset($GLOBALS['_PEAR_shutdown_funcs']) AND is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
+        foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
+            call_user_func_array($value[0], $value[1]);
+        }
+    }
+}
+
+// }}}
+/**
+ * Standard PEAR error class for PHP 4
+ *
+ * This class is supserseded by {@link PEAR_Exception} in PHP 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V.V. Cox <cox@idecnet.com>
+ * @author     Gregory Beaver <cellog@php.net>
+ * @copyright  1997-2006 The PHP Group
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/manual/en/core.pear.pear-error.php
+ * @see        PEAR::raiseError(), PEAR::throwError()
+ * @since      Class available since PHP 4.0.2
+ */
+class PEAR_Error
+{
+    // {{{ properties
+
+    var $error_message_prefix = '';
+    var $mode                 = PEAR_ERROR_RETURN;
+    var $level                = E_USER_NOTICE;
+    var $code                 = -1;
+    var $message              = '';
+    var $userinfo             = '';
+    var $backtrace            = null;
+
+    // }}}
+    // {{{ constructor
+
+    /**
+     * PEAR_Error constructor
+     *
+     * @param string $message  message
+     *
+     * @param int $code     (optional) error code
+     *
+     * @param int $mode     (optional) error mode, one of: PEAR_ERROR_RETURN,
+     * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
+     * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
+     *
+     * @param mixed $options   (optional) error level, _OR_ in the case of
+     * PEAR_ERROR_CALLBACK, the callback function or object/method
+     * tuple.
+     *
+     * @param string $userinfo (optional) additional user/debug info
+     *
+     * @access public
+     *
+     */
+    function PEAR_Error($message = 'unknown error', $code = null,
+                        $mode = null, $options = null, $userinfo = null)
+    {
+        if ($mode === null) {
+            $mode = PEAR_ERROR_RETURN;
+        }
+        $this->message   = $message;
+        $this->code      = $code;
+        $this->mode      = $mode;
+        $this->userinfo  = $userinfo;
+
+        if (PEAR_ZE2) {
+            $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace');
+        } else {
+            $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
+        }
+
+        if (!$skiptrace) {
+            $this->backtrace = debug_backtrace();
+            if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
+                unset($this->backtrace[0]['object']);
+            }
+        }
+
+        if ($mode & PEAR_ERROR_CALLBACK) {
+            $this->level = E_USER_NOTICE;
+            $this->callback = $options;
+        } else {
+            if ($options === null) {
+                $options = E_USER_NOTICE;
+            }
+
+            $this->level = $options;
+            $this->callback = null;
+        }
+
+        if ($this->mode & PEAR_ERROR_PRINT) {
+            if (is_null($options) || is_int($options)) {
+                $format = "%s";
+            } else {
+                $format = $options;
+            }
+
+            printf($format, $this->getMessage());
+        }
+
+        if ($this->mode & PEAR_ERROR_TRIGGER) {
+            trigger_error($this->getMessage(), $this->level);
+        }
+
+        if ($this->mode & PEAR_ERROR_DIE) {
+            $msg = $this->getMessage();
+            if (is_null($options) || is_int($options)) {
+                $format = "%s";
+                if (substr($msg, -1) != "\n") {
+                    $msg .= "\n";
+                }
+            } else {
+                $format = $options;
+            }
+            die(sprintf($format, $msg));
+        }
+
+        if ($this->mode & PEAR_ERROR_CALLBACK) {
+            if (is_callable($this->callback)) {
+                call_user_func($this->callback, $this);
+            }
+        }
+
+        if ($this->mode & PEAR_ERROR_EXCEPTION) {
+            trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
+            eval('$e = new Exception($this->message, $this->code);throw($e);');
+        }
+    }
+
+    // }}}
+    // {{{ getMode()
+
+    /**
+     * Get the error mode from an error object.
+     *
+     * @return int error mode
+     * @access public
+     */
+    function getMode() {
+        return $this->mode;
+    }
+
+    // }}}
+    // {{{ getCallback()
+
+    /**
+     * Get the callback function/method from an error object.
+     *
+     * @return mixed callback function or object/method array
+     * @access public
+     */
+    function getCallback() {
+        return $this->callback;
+    }
+
+    // }}}
+    // {{{ getMessage()
+
+
+    /**
+     * Get the error message from an error object.
+     *
+     * @return  string  full error message
+     * @access public
+     */
+    function getMessage()
+    {
+        return ($this->error_message_prefix . $this->message);
+    }
+
+
+    // }}}
+    // {{{ getCode()
+
+    /**
+     * Get error code from an error object
+     *
+     * @return int error code
+     * @access public
+     */
+     function getCode()
+     {
+        return $this->code;
+     }
+
+    // }}}
+    // {{{ getType()
+
+    /**
+     * Get the name of this error/exception.
+     *
+     * @return string error/exception name (type)
+     * @access public
+     */
+    function getType()
+    {
+        return get_class($this);
+    }
+
+    // }}}
+    // {{{ getUserInfo()
+
+    /**
+     * Get additional user-supplied information.
+     *
+     * @return string user-supplied information
+     * @access public
+     */
+    function getUserInfo()
+    {
+        return $this->userinfo;
+    }
+
+    // }}}
+    // {{{ getDebugInfo()
+
+    /**
+     * Get additional debug information supplied by the application.
+     *
+     * @return string debug information
+     * @access public
+     */
+    function getDebugInfo()
+    {
+        return $this->getUserInfo();
+    }
+
+    // }}}
+    // {{{ getBacktrace()
+
+    /**
+     * Get the call backtrace from where the error was generated.
+     * Supported with PHP 4.3.0 or newer.
+     *
+     * @param int $frame (optional) what frame to fetch
+     * @return array Backtrace, or NULL if not available.
+     * @access public
+     */
+    function getBacktrace($frame = null)
+    {
+        if (defined('PEAR_IGNORE_BACKTRACE')) {
+            return null;
+        }
+        if ($frame === null) {
+            return $this->backtrace;
+        }
+        return $this->backtrace[$frame];
+    }
+
+    // }}}
+    // {{{ addUserInfo()
+
+    function addUserInfo($info)
+    {
+        if (empty($this->userinfo)) {
+            $this->userinfo = $info;
+        } else {
+            $this->userinfo .= " ** $info";
+        }
+    }
+
+    // }}}
+    // {{{ toString()
+    function __toString()
+    {
+        return $this->getMessage();
+    }
+    // }}}
+    // {{{ toString()
+
+    /**
+     * Make a string representation of this object.
+     *
+     * @return string a string with an object summary
+     * @access public
+     */
+    function toString() {
+        $modes = array();
+        $levels = array(E_USER_NOTICE  => 'notice',
+                        E_USER_WARNING => 'warning',
+                        E_USER_ERROR   => 'error');
+        if ($this->mode & PEAR_ERROR_CALLBACK) {
+            if (is_array($this->callback)) {
+                $callback = (is_object($this->callback[0]) ?
+                    strtolower(get_class($this->callback[0])) :
+                    $this->callback[0]) . '::' .
+                    $this->callback[1];
+            } else {
+                $callback = $this->callback;
+            }
+            return sprintf('[%s: message="%s" code=%d mode=callback '.
+                           'callback=%s prefix="%s" info="%s"]',
+                           strtolower(get_class($this)), $this->message, $this->code,
+                           $callback, $this->error_message_prefix,
+                           $this->userinfo);
+        }
+        if ($this->mode & PEAR_ERROR_PRINT) {
+            $modes[] = 'print';
+        }
+        if ($this->mode & PEAR_ERROR_TRIGGER) {
+            $modes[] = 'trigger';
+        }
+        if ($this->mode & PEAR_ERROR_DIE) {
+            $modes[] = 'die';
+        }
+        if ($this->mode & PEAR_ERROR_RETURN) {
+            $modes[] = 'return';
+        }
+        return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
+                       'prefix="%s" info="%s"]',
+                       strtolower(get_class($this)), $this->message, $this->code,
+                       implode("|", $modes), $levels[$this->level],
+                       $this->error_message_prefix,
+                       $this->userinfo);
+    }
+
+    // }}}
+}
+
+/*
+ * Local Variables:
+ * mode: php
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/lib/php/PEAR/Autoloader.php b/lib/php/PEAR/Autoloader.php
new file mode 100644
index 00000000..69d933a0
--- /dev/null
+++ b/lib/php/PEAR/Autoloader.php
@@ -0,0 +1,218 @@
+<?php
+/**
+ * Class auto-loader
+ *
+ * PHP versions 4
+
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Autoloader.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
+ * @since      File available since Release 0.1
+ * @deprecated File deprecated in Release 1.4.0a1
+ */
+
+// /* vim: set expandtab tabstop=4 shiftwidth=4: */
+
+if (!extension_loaded("overload")) {
+    // die hard without ext/overload
+    die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader");
+}
+
+/**
+ * Include for PEAR_Error and PEAR classes
+ */
+require_once "PEAR.php";
+
+/**
+ * This class is for objects where you want to separate the code for
+ * some methods into separate classes.  This is useful if you have a
+ * class with not-frequently-used methods that contain lots of code
+ * that you would like to avoid always parsing.
+ *
+ * The PEAR_Autoloader class provides autoloading and aggregation.
+ * The autoloading lets you set up in which classes the separated
+ * methods are found.  Aggregation is the technique used to import new
+ * methods, an instance of each class providing separated methods is
+ * stored and called every time the aggregated method is called.
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author Stig Bakken <ssb@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
+ * @since      File available since Release 0.1
+ * @deprecated File deprecated in Release 1.4.0a1
+ */
+class PEAR_Autoloader extends PEAR
+{
+    // {{{ properties
+
+    /**
+     * Map of methods and classes where they are defined
+     *
+     * @var array
+     *
+     * @access private
+     */
+    var $_autoload_map = array();
+
+    /**
+     * Map of methods and aggregate objects
+     *
+     * @var array
+     *
+     * @access private
+     */
+    var $_method_map = array();
+
+    // }}}
+    // {{{ addAutoload()
+
+    /**
+     * Add one or more autoload entries.
+     *
+     * @param string $method     which method to autoload
+     *
+     * @param string $classname  (optional) which class to find the method in.
+     *                           If the $method parameter is an array, this
+     *                           parameter may be omitted (and will be ignored
+     *                           if not), and the $method parameter will be
+     *                           treated as an associative array with method
+     *                           names as keys and class names as values.
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function addAutoload($method, $classname = null)
+    {
+        if (is_array($method)) {
+            array_walk($method, create_function('$a,&$b', '$b = strtolower($b);'));
+            $this->_autoload_map = array_merge($this->_autoload_map, $method);
+        } else {
+            $this->_autoload_map[strtolower($method)] = $classname;
+        }
+    }
+
+    // }}}
+    // {{{ removeAutoload()
+
+    /**
+     * Remove an autoload entry.
+     *
+     * @param string $method  which method to remove the autoload entry for
+     *
+     * @return bool TRUE if an entry was removed, FALSE if not
+     *
+     * @access public
+     */
+    function removeAutoload($method)
+    {
+        $method = strtolower($method);
+        $ok = isset($this->_autoload_map[$method]);
+        unset($this->_autoload_map[$method]);
+        return $ok;
+    }
+
+    // }}}
+    // {{{ addAggregateObject()
+
+    /**
+     * Add an aggregate object to this object.  If the specified class
+     * is not defined, loading it will be attempted following PEAR's
+     * file naming scheme.  All the methods in the class will be
+     * aggregated, except private ones (name starting with an
+     * underscore) and constructors.
+     *
+     * @param string $classname  what class to instantiate for the object.
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function addAggregateObject($classname)
+    {
+        $classname = strtolower($classname);
+        if (!class_exists($classname)) {
+            $include_file = preg_replace('/[^a-z0-9]/i', '_', $classname);
+            include_once $include_file;
+        }
+        $obj =& new $classname;
+        $methods = get_class_methods($classname);
+        foreach ($methods as $method) {
+            // don't import priviate methods and constructors
+            if ($method{0} != '_' && $method != $classname) {
+                $this->_method_map[$method] = $obj;
+            }
+        }
+    }
+
+    // }}}
+    // {{{ removeAggregateObject()
+
+    /**
+     * Remove an aggregate object.
+     *
+     * @param string $classname  the class of the object to remove
+     *
+     * @return bool  TRUE if an object was removed, FALSE if not
+     *
+     * @access public
+     */
+    function removeAggregateObject($classname)
+    {
+        $ok = false;
+        $classname = strtolower($classname);
+        reset($this->_method_map);
+        while (list($method, $obj) = each($this->_method_map)) {
+            if (is_a($obj, $classname)) {
+                unset($this->_method_map[$method]);
+                $ok = true;
+            }
+        }
+        return $ok;
+    }
+
+    // }}}
+    // {{{ __call()
+
+    /**
+     * Overloaded object call handler, called each time an
+     * undefined/aggregated method is invoked.  This method repeats
+     * the call in the right aggregate object and passes on the return
+     * value.
+     *
+     * @param string $method  which method that was called
+     *
+     * @param string $args    An array of the parameters passed in the
+     *                        original call
+     *
+     * @return mixed  The return value from the aggregated method, or a PEAR
+     *                error if the called method was unknown.
+     */
+    function __call($method, $args, &$retval)
+    {
+        $method = strtolower($method);
+        if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) {
+            $this->addAggregateObject($this->_autoload_map[$method]);
+        }
+        if (isset($this->_method_map[$method])) {
+            $retval = call_user_func_array(array($this->_method_map[$method], $method), $args);
+            return true;
+        }
+        return false;
+    }
+
+    // }}}
+}
+
+overload("PEAR_Autoloader");
+
+?>
diff --git a/lib/php/PEAR/Builder.php b/lib/php/PEAR/Builder.php
new file mode 100644
index 00000000..49352cba
--- /dev/null
+++ b/lib/php/PEAR/Builder.php
@@ -0,0 +1,474 @@
+<?php
+/**
+ * PEAR_Builder for building PHP extensions (PECL packages)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Builder.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ *
+ * TODO: log output parameters in PECL command line
+ * TODO: msdev path in configuration
+ */
+
+/**
+ * Needed for extending PEAR_Builder
+ */
+require_once 'PEAR/Common.php';
+require_once 'PEAR/PackageFile.php';
+
+/**
+ * Class to handle building (compiling) extensions.
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since PHP 4.0.2
+ * @see        http://pear.php.net/manual/en/core.ppm.pear-builder.php
+ */
+class PEAR_Builder extends PEAR_Common
+{
+    var $php_api_version = 0;
+    var $zend_module_api_no = 0;
+    var $zend_extension_api_no = 0;
+
+    var $extensions_built = array();
+
+    /**
+     * @var string Used for reporting when it is not possible to pass function
+     *             via extra parameter, e.g. log, msdevCallback
+     */
+    var $current_callback = null;
+
+    // used for msdev builds
+    var $_lastline = null;
+    var $_firstline = null;
+
+    /**
+     * PEAR_Builder constructor.
+     *
+     * @param object $ui user interface object (instance of PEAR_Frontend_*)
+     *
+     * @access public
+     */
+    function PEAR_Builder(&$ui)
+    {
+        parent::PEAR_Common();
+        $this->setFrontendObject($ui);
+    }
+
+    /**
+     * Build an extension from source on windows.
+     * requires msdev
+     */
+    function _build_win32($descfile, $callback = null)
+    {
+        if (is_object($descfile)) {
+            $pkg = $descfile;
+            $descfile = $pkg->getPackageFile();
+        } else {
+            $pf = &new PEAR_PackageFile($this->config, $this->debug);
+            $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
+            if (PEAR::isError($pkg)) {
+                return $pkg;
+            }
+        }
+        $dir = dirname($descfile);
+        $old_cwd = getcwd();
+
+        if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
+            return $this->raiseError("could not chdir to $dir");
+        }
+
+        // packages that were in a .tar have the packagefile in this directory
+        $vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
+        if (file_exists($dir) && is_dir($vdir)) {
+            if (!chdir($vdir)) {
+                return $this->raiseError("could not chdir to " . realpath($vdir));
+            }
+
+            $dir = getcwd();
+        }
+
+        $this->log(2, "building in $dir");
+
+        $dsp = $pkg->getPackage().'.dsp';
+        if (!file_exists("$dir/$dsp")) {
+            return $this->raiseError("The DSP $dsp does not exist.");
+        }
+        // XXX TODO: make release build type configurable
+        $command = 'msdev '.$dsp.' /MAKE "'.$pkg->getPackage(). ' - Release"';
+
+        $err = $this->_runCommand($command, array(&$this, 'msdevCallback'));
+        if (PEAR::isError($err)) {
+            return $err;
+        }
+
+        // figure out the build platform and type
+        $platform = 'Win32';
+        $buildtype = 'Release';
+        if (preg_match('/.*?'.$pkg->getPackage().'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) {
+            $platform = $matches[1];
+            $buildtype = $matches[2];
+        }
+
+        if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/', $this->_lastline, $matches)) {
+            if ($matches[2]) {
+                // there were errors in the build
+                return $this->raiseError("There were errors during compilation.");
+            }
+            $out = $matches[1];
+        } else {
+            return $this->raiseError("Did not understand the completion status returned from msdev.exe.");
+        }
+
+        // msdev doesn't tell us the output directory :/
+        // open the dsp, find /out and use that directory
+        $dsptext = join(file($dsp),'');
+
+        // this regex depends on the build platform and type having been
+        // correctly identified above.
+        $regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'.
+                    $pkg->getPackage().'\s-\s'.
+                    $platform.'\s'.
+                    $buildtype.'").*?'.
+                    '\/out:"(.*?)"/is';
+
+        if ($dsptext && preg_match($regex, $dsptext, $matches)) {
+            // what we get back is a relative path to the output file itself.
+            $outfile = realpath($matches[2]);
+        } else {
+            return $this->raiseError("Could not retrieve output information from $dsp.");
+        }
+        // realpath returns false if the file doesn't exist
+        if ($outfile && copy($outfile, "$dir/$out")) {
+            $outfile = "$dir/$out";
+        }
+
+        $built_files[] = array(
+            'file' => "$outfile",
+            'php_api' => $this->php_api_version,
+            'zend_mod_api' => $this->zend_module_api_no,
+            'zend_ext_api' => $this->zend_extension_api_no,
+            );
+
+        return $built_files;
+    }
+    // }}}
+
+    // {{{ msdevCallback()
+    function msdevCallback($what, $data)
+    {
+        if (!$this->_firstline)
+            $this->_firstline = $data;
+        $this->_lastline = $data;
+        call_user_func($this->current_callback, $what, $data);
+    }
+
+    /**
+     * @param string
+     * @param string
+     * @param array
+     * @access private
+     */
+    function _harvestInstDir($dest_prefix, $dirname, &$built_files)
+    {
+        $d = opendir($dirname);
+        if (!$d)
+            return false;
+
+        $ret = true;
+        while (($ent = readdir($d)) !== false) {
+            if ($ent{0} == '.')
+                continue;
+
+            $full = $dirname . DIRECTORY_SEPARATOR . $ent;
+            if (is_dir($full)) {
+                if (!$this->_harvestInstDir(
+                        $dest_prefix . DIRECTORY_SEPARATOR . $ent,
+                        $full, $built_files)) {
+                    $ret = false;
+                    break;
+                }
+            } else {
+                $dest = $dest_prefix . DIRECTORY_SEPARATOR . $ent;
+                $built_files[] = array(
+                        'file' => $full,
+                        'dest' => $dest,
+                        'php_api' => $this->php_api_version,
+                        'zend_mod_api' => $this->zend_module_api_no,
+                        'zend_ext_api' => $this->zend_extension_api_no,
+                        );
+            }
+        }
+        closedir($d);
+        return $ret;
+    }
+
+    /**
+     * Build an extension from source.  Runs "phpize" in the source
+     * directory, but compiles in a temporary directory
+     * (/var/tmp/pear-build-USER/PACKAGE-VERSION).
+     *
+     * @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or
+     *               a PEAR_PackageFile object
+     *
+     * @param mixed $callback callback function used to report output,
+     * see PEAR_Builder::_runCommand for details
+     *
+     * @return array an array of associative arrays with built files,
+     * format:
+     * array( array( 'file' => '/path/to/ext.so',
+     *               'php_api' => YYYYMMDD,
+     *               'zend_mod_api' => YYYYMMDD,
+     *               'zend_ext_api' => YYYYMMDD ),
+     *        ... )
+     *
+     * @access public
+     *
+     * @see PEAR_Builder::_runCommand
+     */
+    function build($descfile, $callback = null)
+    {
+        if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php(.+)?$/',
+                       $this->config->get('php_bin'), $matches)) {
+            if (isset($matches[2]) && strlen($matches[2]) &&
+                trim($matches[2]) != trim($this->config->get('php_prefix'))) {
+                $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
+                           ' appears to have a prefix ' . $matches[2] . ', but' .
+                           ' config variable php_prefix does not match');
+            }
+            if (isset($matches[3]) && strlen($matches[3]) &&
+                trim($matches[3]) != trim($this->config->get('php_suffix'))) {
+                $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
+                           ' appears to have a suffix ' . $matches[3] . ', but' .
+                           ' config variable php_suffix does not match');
+            }
+        }
+
+
+        $this->current_callback = $callback;
+        if (PEAR_OS == "Windows") {
+            return $this->_build_win32($descfile, $callback);
+        }
+        if (PEAR_OS != 'Unix') {
+            return $this->raiseError("building extensions not supported on this platform");
+        }
+        if (is_object($descfile)) {
+            $pkg = $descfile;
+            $descfile = $pkg->getPackageFile();
+            if (is_a($pkg, 'PEAR_PackageFile_v1')) {
+                $dir = dirname($descfile);
+            } else {
+                $dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName();
+                // automatically delete at session end
+                $this->addTempFile($dir);
+            }
+        } else {
+            $pf = &new PEAR_PackageFile($this->config);
+            $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
+            if (PEAR::isError($pkg)) {
+                return $pkg;
+            }
+            $dir = dirname($descfile);
+        }
+        $old_cwd = getcwd();
+        if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
+            return $this->raiseError("could not chdir to $dir");
+        }
+        $vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
+        if (is_dir($vdir)) {
+            chdir($vdir);
+        }
+        $dir = getcwd();
+        $this->log(2, "building in $dir");
+        putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH'));
+        $err = $this->_runCommand($this->config->get('php_prefix')
+                                . "phpize" .
+                                $this->config->get('php_suffix'),
+                                array(&$this, 'phpizeCallback'));
+        if (PEAR::isError($err)) {
+            return $err;
+        }
+        if (!$err) {
+            return $this->raiseError("`phpize' failed");
+        }
+
+        // {{{ start of interactive part
+        $configure_command = "$dir/configure";
+        $configure_options = $pkg->getConfigureOptions();
+        if ($configure_options) {
+            foreach ($configure_options as $o) {
+                $default = array_key_exists('default', $o) ? $o['default'] : null;
+                list($r) = $this->ui->userDialog('build',
+                                                 array($o['prompt']),
+                                                 array('text'),
+                                                 array($default));
+                if (substr($o['name'], 0, 5) == 'with-' &&
+                    ($r == 'yes' || $r == 'autodetect')) {
+                    $configure_command .= " --$o[name]";
+                } else {
+                    $configure_command .= " --$o[name]=".trim($r);
+                }
+            }
+        }
+        // }}} end of interactive part
+
+        // FIXME make configurable
+        if(!$user=getenv('USER')){
+            $user='defaultuser';
+        }
+        $build_basedir = "/var/tmp/pear-build-$user";
+        $build_dir = "$build_basedir/$vdir";
+        $inst_dir = "$build_basedir/install-$vdir";
+        $this->log(1, "building in $build_dir");
+        if (is_dir($build_dir)) {
+            System::rm(array('-rf', $build_dir));
+        }
+        if (!System::mkDir(array('-p', $build_dir))) {
+            return $this->raiseError("could not create build dir: $build_dir");
+        }
+        $this->addTempFile($build_dir);
+        if (!System::mkDir(array('-p', $inst_dir))) {
+            return $this->raiseError("could not create temporary install dir: $inst_dir");
+        }
+        $this->addTempFile($inst_dir);
+
+        if (getenv('MAKE')) {
+            $make_command = getenv('MAKE');
+        } else {
+            $make_command = 'make';
+        }
+        $to_run = array(
+            $configure_command,
+            $make_command,
+            "$make_command INSTALL_ROOT=\"$inst_dir\" install",
+            "find \"$inst_dir\" | xargs ls -dils"
+            );
+        if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) {
+            return $this->raiseError("could not chdir to $build_dir");
+        }
+        putenv('PHP_PEAR_VERSION=1.9.0');
+        foreach ($to_run as $cmd) {
+            $err = $this->_runCommand($cmd, $callback);
+            if (PEAR::isError($err)) {
+                chdir($old_cwd);
+                return $err;
+            }
+            if (!$err) {
+                chdir($old_cwd);
+                return $this->raiseError("`$cmd' failed");
+            }
+        }
+        if (!($dp = opendir("modules"))) {
+            chdir($old_cwd);
+            return $this->raiseError("no `modules' directory found");
+        }
+        $built_files = array();
+        $prefix = exec($this->config->get('php_prefix')
+                        . "php-config" .
+                       $this->config->get('php_suffix') . " --prefix");
+        $this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files);
+        chdir($old_cwd);
+        return $built_files;
+    }
+
+    /**
+     * Message callback function used when running the "phpize"
+     * program.  Extracts the API numbers used.  Ignores other message
+     * types than "cmdoutput".
+     *
+     * @param string $what the type of message
+     * @param mixed $data the message
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function phpizeCallback($what, $data)
+    {
+        if ($what != 'cmdoutput') {
+            return;
+        }
+        $this->log(1, rtrim($data));
+        if (preg_match('/You should update your .aclocal.m4/', $data)) {
+            return;
+        }
+        $matches = array();
+        if (preg_match('/^\s+(\S[^:]+):\s+(\d{8})/', $data, $matches)) {
+            $member = preg_replace('/[^a-z]/', '_', strtolower($matches[1]));
+            $apino = (int)$matches[2];
+            if (isset($this->$member)) {
+                $this->$member = $apino;
+                //$msg = sprintf("%-22s : %d", $matches[1], $apino);
+                //$this->log(1, $msg);
+            }
+        }
+    }
+
+    /**
+     * Run an external command, using a message callback to report
+     * output.  The command will be run through popen and output is
+     * reported for every line with a "cmdoutput" message with the
+     * line string, including newlines, as payload.
+     *
+     * @param string $command the command to run
+     *
+     * @param mixed $callback (optional) function to use as message
+     * callback
+     *
+     * @return bool whether the command was successful (exit code 0
+     * means success, any other means failure)
+     *
+     * @access private
+     */
+    function _runCommand($command, $callback = null)
+    {
+        $this->log(1, "running: $command");
+        $pp = popen("$command 2>&1", "r");
+        if (!$pp) {
+            return $this->raiseError("failed to run `$command'");
+        }
+        if ($callback && $callback[0]->debug == 1) {
+            $olddbg = $callback[0]->debug;
+            $callback[0]->debug = 2;
+        }
+
+        while ($line = fgets($pp, 1024)) {
+            if ($callback) {
+                call_user_func($callback, 'cmdoutput', $line);
+            } else {
+                $this->log(2, rtrim($line));
+            }
+        }
+        if ($callback && isset($olddbg)) {
+            $callback[0]->debug = $olddbg;
+        }
+
+        $exitcode = is_resource($pp) ? pclose($pp) : -1;
+        return ($exitcode == 0);
+    }
+
+    function log($level, $msg)
+    {
+        if ($this->current_callback) {
+            if ($this->debug >= $level) {
+                call_user_func($this->current_callback, 'output', $msg);
+            }
+            return;
+        }
+        return PEAR_Common::log($level, $msg);
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/ChannelFile.php b/lib/php/PEAR/ChannelFile.php
new file mode 100644
index 00000000..6c864d1a
--- /dev/null
+++ b/lib/php/PEAR/ChannelFile.php
@@ -0,0 +1,1559 @@
+<?php
+/**
+ * PEAR_ChannelFile, the channel handling class
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: ChannelFile.php 286951 2009-08-09 14:41:22Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * Needed for error handling
+ */
+require_once 'PEAR/ErrorStack.php';
+require_once 'PEAR/XMLParser.php';
+require_once 'PEAR/Common.php';
+
+/**
+ * Error code if the channel.xml <channel> tag does not contain a valid version
+ */
+define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1);
+/**
+ * Error code if the channel.xml <channel> tag version is not supported (version 1.0 is the only supported version,
+ * currently
+ */
+define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2);
+
+/**
+ * Error code if parsing is attempted with no xml extension
+ */
+define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3);
+
+/**
+ * Error code if creating the xml parser resource fails
+ */
+define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4);
+
+/**
+ * Error code used for all sax xml parsing errors
+ */
+define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5);
+
+/**#@+
+ * Validation errors
+ */
+/**
+ * Error code when channel name is missing
+ */
+define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6);
+/**
+ * Error code when channel name is invalid
+ */
+define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7);
+/**
+ * Error code when channel summary is missing
+ */
+define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8);
+/**
+ * Error code when channel summary is multi-line
+ */
+define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9);
+/**
+ * Error code when channel server is missing for protocol
+ */
+define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10);
+/**
+ * Error code when channel server is invalid for protocol
+ */
+define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11);
+/**
+ * Error code when a mirror name is invalid
+ */
+define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21);
+/**
+ * Error code when a mirror type is invalid
+ */
+define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22);
+/**
+ * Error code when an attempt is made to generate xml, but the parsed content is invalid
+ */
+define('PEAR_CHANNELFILE_ERROR_INVALID', 23);
+/**
+ * Error code when an empty package name validate regex is passed in
+ */
+define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24);
+/**
+ * Error code when a <function> tag has no version
+ */
+define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25);
+/**
+ * Error code when a <function> tag has no name
+ */
+define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26);
+/**
+ * Error code when a <validatepackage> tag has no name
+ */
+define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27);
+/**
+ * Error code when a <validatepackage> tag has no version attribute
+ */
+define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28);
+/**
+ * Error code when a mirror does not exist but is called for in one of the set*
+ * methods.
+ */
+define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32);
+/**
+ * Error code when a server port is not numeric
+ */
+define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33);
+/**
+ * Error code when <static> contains no version attribute
+ */
+define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34);
+/**
+ * Error code when <baseurl> contains no type attribute in a <rest> protocol definition
+ */
+define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35);
+/**
+ * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel
+ */
+define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36);
+/**
+ * Error code when ssl attribute is present and is not "yes"
+ */
+define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37);
+/**#@-*/
+
+/**
+ * Mirror types allowed.  Currently only internet servers are recognized.
+ */
+$GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] =  array('server');
+
+
+/**
+ * The Channel handling class
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_ChannelFile
+{
+    /**
+     * @access private
+     * @var PEAR_ErrorStack
+     * @access private
+     */
+    var $_stack;
+
+    /**
+     * Supported channel.xml versions, for parsing
+     * @var array
+     * @access private
+     */
+    var $_supportedVersions = array('1.0');
+
+    /**
+     * Parsed channel information
+     * @var array
+     * @access private
+     */
+    var $_channelInfo;
+
+    /**
+     * index into the subchannels array, used for parsing xml
+     * @var int
+     * @access private
+     */
+    var $_subchannelIndex;
+
+    /**
+     * index into the mirrors array, used for parsing xml
+     * @var int
+     * @access private
+     */
+    var $_mirrorIndex;
+
+    /**
+     * Flag used to determine the validity of parsed content
+     * @var boolean
+     * @access private
+     */
+    var $_isValid = false;
+
+    function PEAR_ChannelFile()
+    {
+        $this->_stack = &new PEAR_ErrorStack('PEAR_ChannelFile');
+        $this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
+        $this->_isValid = false;
+    }
+
+    /**
+     * @return array
+     * @access protected
+     */
+    function _getErrorMessage()
+    {
+        return
+            array(
+                PEAR_CHANNELFILE_ERROR_INVALID_VERSION =>
+                    'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%',
+                PEAR_CHANNELFILE_ERROR_NO_VERSION =>
+                    'No version number found in <channel> tag',
+                PEAR_CHANNELFILE_ERROR_NO_XML_EXT =>
+                    '%error%',
+                PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER =>
+                    'Unable to create XML parser',
+                PEAR_CHANNELFILE_ERROR_PARSER_ERROR =>
+                    '%error%',
+                PEAR_CHANNELFILE_ERROR_NO_NAME =>
+                    'Missing channel name',
+                PEAR_CHANNELFILE_ERROR_INVALID_NAME =>
+                    'Invalid channel %tag% "%name%"',
+                PEAR_CHANNELFILE_ERROR_NO_SUMMARY =>
+                    'Missing channel summary',
+                PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY =>
+                    'Channel summary should be on one line, but is multi-line',
+                PEAR_CHANNELFILE_ERROR_NO_HOST =>
+                    'Missing channel server for %type% server',
+                PEAR_CHANNELFILE_ERROR_INVALID_HOST =>
+                    'Server name "%server%" is invalid for %type% server',
+                PEAR_CHANNELFILE_ERROR_INVALID_MIRROR =>
+                    'Invalid mirror name "%name%", mirror type %type%',
+                PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE =>
+                    'Invalid mirror type "%type%"',
+                PEAR_CHANNELFILE_ERROR_INVALID =>
+                    'Cannot generate xml, contents are invalid',
+                PEAR_CHANNELFILE_ERROR_EMPTY_REGEX =>
+                    'packagenameregex cannot be empty',
+                PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION =>
+                    '%parent% %protocol% function has no version',
+                PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME =>
+                    '%parent% %protocol% function has no name',
+                PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE =>
+                    '%parent% rest baseurl has no type',
+                PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME =>
+                    'Validation package has no name in <validatepackage> tag',
+                PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION =>
+                    'Validation package "%package%" has no version',
+                PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND =>
+                    'Mirror "%mirror%" does not exist',
+                PEAR_CHANNELFILE_ERROR_INVALID_PORT =>
+                    'Port "%port%" must be numeric',
+                PEAR_CHANNELFILE_ERROR_NO_STATICVERSION =>
+                    '<static> tag must contain version attribute',
+                PEAR_CHANNELFILE_URI_CANT_MIRROR =>
+                    'The __uri pseudo-channel cannot have mirrors',
+                PEAR_CHANNELFILE_ERROR_INVALID_SSL =>
+                    '%server% has invalid ssl attribute "%ssl%" can only be yes or not present',
+            );
+    }
+
+    /**
+     * @param string contents of package.xml file
+     * @return bool success of parsing
+     */
+    function fromXmlString($data)
+    {
+        if (preg_match('/<channel\s+version="([0-9]+\.[0-9]+)"/', $data, $channelversion)) {
+            if (!in_array($channelversion[1], $this->_supportedVersions)) {
+                $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error',
+                    array('version' => $channelversion[1]));
+                return false;
+            }
+            $parser = new PEAR_XMLParser;
+            $result = $parser->parse($data);
+            if ($result !== true) {
+                if ($result->getCode() == 1) {
+                    $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error',
+                        array('error' => $result->getMessage()));
+                } else {
+                    $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error');
+                }
+                return false;
+            }
+            $this->_channelInfo = $parser->getData();
+            return true;
+        } else {
+            $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data));
+            return false;
+        }
+    }
+
+    /**
+     * @return array
+     */
+    function toArray()
+    {
+        if (!$this->_isValid && !$this->validate()) {
+            return false;
+        }
+        return $this->_channelInfo;
+    }
+
+    /**
+     * @param array
+     * @static
+     * @return PEAR_ChannelFile|false false if invalid
+     */
+    function &fromArray($data, $compatibility = false, $stackClass = 'PEAR_ErrorStack')
+    {
+        $a = new PEAR_ChannelFile($compatibility, $stackClass);
+        $a->_fromArray($data);
+        if (!$a->validate()) {
+            $a = false;
+            return $a;
+        }
+        return $a;
+    }
+
+    /**
+     * Unlike {@link fromArray()} this does not do any validation
+     * @param array
+     * @static
+     * @return PEAR_ChannelFile
+     */
+    function &fromArrayWithErrors($data, $compatibility = false,
+                                  $stackClass = 'PEAR_ErrorStack')
+    {
+        $a = new PEAR_ChannelFile($compatibility, $stackClass);
+        $a->_fromArray($data);
+        return $a;
+    }
+
+    /**
+     * @param array
+     * @access private
+     */
+    function _fromArray($data)
+    {
+        $this->_channelInfo = $data;
+    }
+
+    /**
+     * Wrapper to {@link PEAR_ErrorStack::getErrors()}
+     * @param boolean determines whether to purge the error stack after retrieving
+     * @return array
+     */
+    function getErrors($purge = false)
+    {
+        return $this->_stack->getErrors($purge);
+    }
+
+    /**
+     * Unindent given string (?)
+     *
+     * @param string $str The string that has to be unindented.
+     * @return string
+     * @access private
+     */
+    function _unIndent($str)
+    {
+        // remove leading newlines
+        $str = preg_replace('/^[\r\n]+/', '', $str);
+        // find whitespace at the beginning of the first line
+        $indent_len = strspn($str, " \t");
+        $indent = substr($str, 0, $indent_len);
+        $data = '';
+        // remove the same amount of whitespace from following lines
+        foreach (explode("\n", $str) as $line) {
+            if (substr($line, 0, $indent_len) == $indent) {
+                $data .= substr($line, $indent_len) . "\n";
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * Parse a channel.xml file.  Expects the name of
+     * a channel xml file as input.
+     *
+     * @param string  $descfile  name of channel xml file
+     * @return bool success of parsing
+     */
+    function fromXmlFile($descfile)
+    {
+        if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) ||
+             (!$fp = fopen($descfile, 'r'))) {
+            require_once 'PEAR.php';
+            return PEAR::raiseError("Unable to open $descfile");
+        }
+
+        // read the whole thing so we only get one cdata callback
+        // for each block of cdata
+        fclose($fp);
+        $data = file_get_contents($descfile);
+        return $this->fromXmlString($data);
+    }
+
+    /**
+     * Parse channel information from different sources
+     *
+     * This method is able to extract information about a channel
+     * from an .xml file or a string
+     *
+     * @access public
+     * @param  string Filename of the source or the source itself
+     * @return bool
+     */
+    function fromAny($info)
+    {
+        if (is_string($info) && file_exists($info) && strlen($info) < 255) {
+            $tmp = substr($info, -4);
+            if ($tmp == '.xml') {
+                $info = $this->fromXmlFile($info);
+            } else {
+                $fp = fopen($info, "r");
+                $test = fread($fp, 5);
+                fclose($fp);
+                if ($test == "<?xml") {
+                    $info = $this->fromXmlFile($info);
+                }
+            }
+            if (PEAR::isError($info)) {
+                require_once 'PEAR.php';
+                return PEAR::raiseError($info);
+            }
+        }
+        if (is_string($info)) {
+            $info = $this->fromXmlString($info);
+        }
+        return $info;
+    }
+
+    /**
+     * Return an XML document based on previous parsing and modifications
+     *
+     * @return string XML data
+     *
+     * @access public
+     */
+    function toXml()
+    {
+        if (!$this->_isValid && !$this->validate()) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID);
+            return false;
+        }
+        if (!isset($this->_channelInfo['attribs']['version'])) {
+            $this->_channelInfo['attribs']['version'] = '1.0';
+        }
+        $channelInfo = $this->_channelInfo;
+        $ret = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n";
+        $ret .= "<channel version=\"" .
+            $channelInfo['attribs']['version'] . "\" xmlns=\"http://pear.php.net/channel-1.0\"
+  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
+  xsi:schemaLocation=\"http://pear.php.net/dtd/channel-"
+            . $channelInfo['attribs']['version'] . " http://pear.php.net/dtd/channel-" .
+            $channelInfo['attribs']['version'] . ".xsd\">
+ <name>$channelInfo[name]</name>
+ <summary>" . htmlspecialchars($channelInfo['summary'])."</summary>
+";
+        if (isset($channelInfo['suggestedalias'])) {
+            $ret .= ' <suggestedalias>' . $channelInfo['suggestedalias'] . "</suggestedalias>\n";
+        }
+        if (isset($channelInfo['validatepackage'])) {
+            $ret .= ' <validatepackage version="' .
+                $channelInfo['validatepackage']['attribs']['version']. '">' .
+                htmlspecialchars($channelInfo['validatepackage']['_content']) .
+                "</validatepackage>\n";
+        }
+        $ret .= " <servers>\n";
+        $ret .= '  <primary';
+        if (isset($channelInfo['servers']['primary']['attribs']['ssl'])) {
+            $ret .= ' ssl="' . $channelInfo['servers']['primary']['attribs']['ssl'] . '"';
+        }
+        if (isset($channelInfo['servers']['primary']['attribs']['port'])) {
+            $ret .= ' port="' . $channelInfo['servers']['primary']['attribs']['port'] . '"';
+        }
+        $ret .= ">\n";
+        if (isset($channelInfo['servers']['primary']['rest'])) {
+            $ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], '   ');
+        }
+        $ret .= "  </primary>\n";
+        if (isset($channelInfo['servers']['mirror'])) {
+            $ret .= $this->_makeMirrorsXml($channelInfo);
+        }
+        $ret .= " </servers>\n";
+        $ret .= "</channel>";
+        return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret));
+    }
+
+    /**
+     * Generate the <rest> tag
+     * @access private
+     */
+    function _makeRestXml($info, $indent)
+    {
+        $ret = $indent . "<rest>\n";
+        if (isset($info['baseurl']) && !isset($info['baseurl'][0])) {
+            $info['baseurl'] = array($info['baseurl']);
+        }
+
+        if (isset($info['baseurl'])) {
+            foreach ($info['baseurl'] as $url) {
+                $ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\"";
+                $ret .= ">" . $url['_content'] . "</baseurl>\n";
+            }
+        }
+        $ret .= $indent . "</rest>\n";
+        return $ret;
+    }
+
+    /**
+     * Generate the <mirrors> tag
+     * @access private
+     */
+    function _makeMirrorsXml($channelInfo)
+    {
+        $ret = "";
+        if (!isset($channelInfo['servers']['mirror'][0])) {
+            $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']);
+        }
+        foreach ($channelInfo['servers']['mirror'] as $mirror) {
+            $ret .= '  <mirror host="' . $mirror['attribs']['host'] . '"';
+            if (isset($mirror['attribs']['port'])) {
+                $ret .= ' port="' . $mirror['attribs']['port'] . '"';
+            }
+            if (isset($mirror['attribs']['ssl'])) {
+                $ret .= ' ssl="' . $mirror['attribs']['ssl'] . '"';
+            }
+            $ret .= ">\n";
+            if (isset($mirror['rest'])) {
+                if (isset($mirror['rest'])) {
+                    $ret .= $this->_makeRestXml($mirror['rest'], '   ');
+                }
+                $ret .= "  </mirror>\n";
+            } else {
+                $ret .= "/>\n";
+            }
+        }
+        return $ret;
+    }
+
+    /**
+     * Generate the <functions> tag
+     * @access private
+     */
+    function _makeFunctionsXml($functions, $indent, $rest = false)
+    {
+        $ret = '';
+        if (!isset($functions[0])) {
+            $functions = array($functions);
+        }
+        foreach ($functions as $function) {
+            $ret .= "$indent<function version=\"" . $function['attribs']['version'] . "\"";
+            if ($rest) {
+                $ret .= ' uri="' . $function['attribs']['uri'] . '"';
+            }
+            $ret .= ">" . $function['_content'] . "</function>\n";
+        }
+        return $ret;
+    }
+
+    /**
+     * Validation error.  Also marks the object contents as invalid
+     * @param error code
+     * @param array error information
+     * @access private
+     */
+    function _validateError($code, $params = array())
+    {
+        $this->_stack->push($code, 'error', $params);
+        $this->_isValid = false;
+    }
+
+    /**
+     * Validation warning.  Does not mark the object contents invalid.
+     * @param error code
+     * @param array error information
+     * @access private
+     */
+    function _validateWarning($code, $params = array())
+    {
+        $this->_stack->push($code, 'warning', $params);
+    }
+
+    /**
+     * Validate parsed file.
+     *
+     * @access public
+     * @return boolean
+     */
+    function validate()
+    {
+        $this->_isValid = true;
+        $info = $this->_channelInfo;
+        if (empty($info['name'])) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME);
+        } elseif (!$this->validChannelServer($info['name'])) {
+            if ($info['name'] != '__uri') {
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name',
+                    'name' => $info['name']));
+            }
+        }
+        if (empty($info['summary'])) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
+        } elseif (strpos(trim($info['summary']), "\n") !== false) {
+            $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
+                array('summary' => $info['summary']));
+        }
+        if (isset($info['suggestedalias'])) {
+            if (!$this->validChannelServer($info['suggestedalias'])) {
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
+                    array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias']));
+            }
+        }
+        if (isset($info['localalias'])) {
+            if (!$this->validChannelServer($info['localalias'])) {
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
+                    array('tag' => 'localalias', 'name' =>$info['localalias']));
+            }
+        }
+        if (isset($info['validatepackage'])) {
+            if (!isset($info['validatepackage']['_content'])) {
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME);
+            }
+            if (!isset($info['validatepackage']['attribs']['version'])) {
+                $content = isset($info['validatepackage']['_content']) ?
+                    $info['validatepackage']['_content'] :
+                    null;
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION,
+                    array('package' => $content));
+            }
+        }
+
+        if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['port']) &&
+              !is_numeric($info['servers']['primary']['attribs']['port'])) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT,
+                array('port' => $info['servers']['primary']['attribs']['port']));
+        }
+
+        if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['ssl']) &&
+              $info['servers']['primary']['attribs']['ssl'] != 'yes') {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
+                array('ssl' => $info['servers']['primary']['attribs']['ssl'],
+                    'server' => $info['name']));
+        }
+
+        if (isset($info['servers']['primary']['rest']) &&
+              isset($info['servers']['primary']['rest']['baseurl'])) {
+            $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']);
+        }
+        if (isset($info['servers']['mirror'])) {
+            if ($this->_channelInfo['name'] == '__uri') {
+                $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR);
+            }
+            if (!isset($info['servers']['mirror'][0])) {
+                $info['servers']['mirror'] = array($info['servers']['mirror']);
+            }
+            foreach ($info['servers']['mirror'] as $mirror) {
+                if (!isset($mirror['attribs']['host'])) {
+                    $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST,
+                      array('type' => 'mirror'));
+                } elseif (!$this->validChannelServer($mirror['attribs']['host'])) {
+                    $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST,
+                        array('server' => $mirror['attribs']['host'], 'type' => 'mirror'));
+                }
+                if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') {
+                    $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
+                        array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host']));
+                }
+                if (isset($mirror['rest'])) {
+                    $this->_validateFunctions('rest', $mirror['rest']['baseurl'],
+                        $mirror['attribs']['host']);
+                }
+            }
+        }
+        return $this->_isValid;
+    }
+
+    /**
+     * @param string  rest - protocol name this function applies to
+     * @param array the functions
+     * @param string the name of the parent element (mirror name, for instance)
+     */
+    function _validateFunctions($protocol, $functions, $parent = '')
+    {
+        if (!isset($functions[0])) {
+            $functions = array($functions);
+        }
+
+        foreach ($functions as $function) {
+            if (!isset($function['_content']) || empty($function['_content'])) {
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME,
+                    array('parent' => $parent, 'protocol' => $protocol));
+            }
+
+            if ($protocol == 'rest') {
+                if (!isset($function['attribs']['type']) ||
+                      empty($function['attribs']['type'])) {
+                    $this->_validateError(PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE,
+                        array('parent' => $parent, 'protocol' => $protocol));
+                }
+            } else {
+                if (!isset($function['attribs']['version']) ||
+                      empty($function['attribs']['version'])) {
+                    $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION,
+                        array('parent' => $parent, 'protocol' => $protocol));
+                }
+            }
+        }
+    }
+
+    /**
+     * Test whether a string contains a valid channel server.
+     * @param string $ver the package version to test
+     * @return bool
+     */
+    function validChannelServer($server)
+    {
+        if ($server == '__uri') {
+            return true;
+        }
+        return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server);
+    }
+
+    /**
+     * @return string|false
+     */
+    function getName()
+    {
+        if (isset($this->_channelInfo['name'])) {
+            return $this->_channelInfo['name'];
+        }
+
+        return false;
+    }
+
+    /**
+     * @return string|false
+     */
+    function getServer()
+    {
+        if (isset($this->_channelInfo['name'])) {
+            return $this->_channelInfo['name'];
+        }
+
+        return false;
+    }
+
+    /**
+     * @return int|80 port number to connect to
+     */
+    function getPort($mirror = false)
+    {
+        if ($mirror) {
+            if ($mir = $this->getMirror($mirror)) {
+                if (isset($mir['attribs']['port'])) {
+                    return $mir['attribs']['port'];
+                }
+
+                if ($this->getSSL($mirror)) {
+                    return 443;
+                }
+
+                return 80;
+            }
+
+            return false;
+        }
+
+        if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) {
+            return $this->_channelInfo['servers']['primary']['attribs']['port'];
+        }
+
+        if ($this->getSSL()) {
+            return 443;
+        }
+
+        return 80;
+    }
+
+    /**
+     * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel
+     */
+    function getSSL($mirror = false)
+    {
+        if ($mirror) {
+            if ($mir = $this->getMirror($mirror)) {
+                if (isset($mir['attribs']['ssl'])) {
+                    return true;
+                }
+
+                return false;
+            }
+
+            return false;
+        }
+
+        if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @return string|false
+     */
+    function getSummary()
+    {
+        if (isset($this->_channelInfo['summary'])) {
+            return $this->_channelInfo['summary'];
+        }
+
+        return false;
+    }
+
+    /**
+     * @param string protocol type
+     * @param string Mirror name
+     * @return array|false
+     */
+    function getFunctions($protocol, $mirror = false)
+    {
+        if ($this->getName() == '__uri') {
+            return false;
+        }
+
+        $function = $protocol == 'rest' ? 'baseurl' : 'function';
+        if ($mirror) {
+            if ($mir = $this->getMirror($mirror)) {
+                if (isset($mir[$protocol][$function])) {
+                    return $mir[$protocol][$function];
+                }
+            }
+
+            return false;
+        }
+
+        if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) {
+            return $this->_channelInfo['servers']['primary'][$protocol][$function];
+        }
+
+        return false;
+    }
+
+    /**
+     * @param string Protocol type
+     * @param string Function name (null to return the
+     *               first protocol of the type requested)
+     * @param string Mirror name, if any
+     * @return array
+     */
+     function getFunction($type, $name = null, $mirror = false)
+     {
+        $protocols = $this->getFunctions($type, $mirror);
+        if (!$protocols) {
+            return false;
+        }
+
+        foreach ($protocols as $protocol) {
+            if ($name === null) {
+                return $protocol;
+            }
+
+            if ($protocol['_content'] != $name) {
+                continue;
+            }
+
+            return $protocol;
+        }
+
+        return false;
+     }
+
+    /**
+     * @param string protocol type
+     * @param string protocol name
+     * @param string version
+     * @param string mirror name
+     * @return boolean
+     */
+    function supports($type, $name = null, $mirror = false, $version = '1.0')
+    {
+        $protocols = $this->getFunctions($type, $mirror);
+        if (!$protocols) {
+            return false;
+        }
+
+        foreach ($protocols as $protocol) {
+            if ($protocol['attribs']['version'] != $version) {
+                continue;
+            }
+
+            if ($name === null) {
+                return true;
+            }
+
+            if ($protocol['_content'] != $name) {
+                continue;
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Determines whether a channel supports Representational State Transfer (REST) protocols
+     * for retrieving channel information
+     * @param string
+     * @return bool
+     */
+    function supportsREST($mirror = false)
+    {
+        if ($mirror == $this->_channelInfo['name']) {
+            $mirror = false;
+        }
+
+        if ($mirror) {
+            if ($mir = $this->getMirror($mirror)) {
+                return isset($mir['rest']);
+            }
+
+            return false;
+        }
+
+        return isset($this->_channelInfo['servers']['primary']['rest']);
+    }
+
+    /**
+     * Get the URL to access a base resource.
+     *
+     * Hyperlinks in the returned xml will be used to retrieve the proper information
+     * needed.  This allows extreme extensibility and flexibility in implementation
+     * @param string Resource Type to retrieve
+     */
+    function getBaseURL($resourceType, $mirror = false)
+    {
+        if ($mirror == $this->_channelInfo['name']) {
+            $mirror = false;
+        }
+
+        if ($mirror) {
+            $mir = $this->getMirror($mirror);
+            if (!$mir) {
+                return false;
+            }
+
+            $rest = $mir['rest'];
+        } else {
+            $rest = $this->_channelInfo['servers']['primary']['rest'];
+        }
+
+        if (!isset($rest['baseurl'][0])) {
+            $rest['baseurl'] = array($rest['baseurl']);
+        }
+
+        foreach ($rest['baseurl'] as $baseurl) {
+            if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) {
+                return $baseurl['_content'];
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Since REST does not implement RPC, provide this as a logical wrapper around
+     * resetFunctions for REST
+     * @param string|false mirror name, if any
+     */
+    function resetREST($mirror = false)
+    {
+        return $this->resetFunctions('rest', $mirror);
+    }
+
+    /**
+     * Empty all protocol definitions
+     * @param string protocol type
+     * @param string|false mirror name, if any
+     */
+    function resetFunctions($type, $mirror = false)
+    {
+        if ($mirror) {
+            if (isset($this->_channelInfo['servers']['mirror'])) {
+                $mirrors = $this->_channelInfo['servers']['mirror'];
+                if (!isset($mirrors[0])) {
+                    $mirrors = array($mirrors);
+                }
+
+                foreach ($mirrors as $i => $mir) {
+                    if ($mir['attribs']['host'] == $mirror) {
+                        if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) {
+                            unset($this->_channelInfo['servers']['mirror'][$i][$type]);
+                        }
+
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+
+            return false;
+        }
+
+        if (isset($this->_channelInfo['servers']['primary'][$type])) {
+            unset($this->_channelInfo['servers']['primary'][$type]);
+        }
+
+        return true;
+    }
+
+    /**
+     * Set a channel's protocols to the protocols supported by pearweb
+     */
+    function setDefaultPEARProtocols($version = '1.0', $mirror = false)
+    {
+        switch ($version) {
+            case '1.0' :
+                $this->resetREST($mirror);
+
+                if (!isset($this->_channelInfo['servers'])) {
+                    $this->_channelInfo['servers'] = array('primary' =>
+                        array('rest' => array()));
+                } elseif (!isset($this->_channelInfo['servers']['primary'])) {
+                    $this->_channelInfo['servers']['primary'] = array('rest' => array());
+                }
+
+                return true;
+            break;
+            default :
+                return false;
+            break;
+        }
+    }
+
+    /**
+     * @return array
+     */
+    function getMirrors()
+    {
+        if (isset($this->_channelInfo['servers']['mirror'])) {
+            $mirrors = $this->_channelInfo['servers']['mirror'];
+            if (!isset($mirrors[0])) {
+                $mirrors = array($mirrors);
+            }
+
+            return $mirrors;
+        }
+
+        return array();
+    }
+
+    /**
+     * Get the unserialized XML representing a mirror
+     * @return array|false
+     */
+    function getMirror($server)
+    {
+        foreach ($this->getMirrors() as $mirror) {
+            if ($mirror['attribs']['host'] == $server) {
+                return $mirror;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @param string
+     * @return string|false
+     * @error PEAR_CHANNELFILE_ERROR_NO_NAME
+     * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME
+     */
+    function setName($name)
+    {
+        return $this->setServer($name);
+    }
+
+    /**
+     * Set the socket number (port) that is used to connect to this channel
+     * @param integer
+     * @param string|false name of the mirror server, or false for the primary
+     */
+    function setPort($port, $mirror = false)
+    {
+        if ($mirror) {
+            if (!isset($this->_channelInfo['servers']['mirror'])) {
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
+                    array('mirror' => $mirror));
+                return false;
+            }
+
+            if (isset($this->_channelInfo['servers']['mirror'][0])) {
+                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
+                    if ($mirror == $mir['attribs']['host']) {
+                        $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port;
+                        return true;
+                    }
+                }
+
+                return false;
+            } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
+                $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port;
+                $this->_isValid = false;
+                return true;
+            }
+        }
+
+        $this->_channelInfo['servers']['primary']['attribs']['port'] = $port;
+        $this->_isValid = false;
+        return true;
+    }
+
+    /**
+     * Set the socket number (port) that is used to connect to this channel
+     * @param bool Determines whether to turn on SSL support or turn it off
+     * @param string|false name of the mirror server, or false for the primary
+     */
+    function setSSL($ssl = true, $mirror = false)
+    {
+        if ($mirror) {
+            if (!isset($this->_channelInfo['servers']['mirror'])) {
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
+                    array('mirror' => $mirror));
+                return false;
+            }
+
+            if (isset($this->_channelInfo['servers']['mirror'][0])) {
+                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
+                    if ($mirror == $mir['attribs']['host']) {
+                        if (!$ssl) {
+                            if (isset($this->_channelInfo['servers']['mirror'][$i]
+                                  ['attribs']['ssl'])) {
+                                unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']);
+                            }
+                        } else {
+                            $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes';
+                        }
+
+                        return true;
+                    }
+                }
+
+                return false;
+            } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
+                if (!$ssl) {
+                    if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) {
+                        unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']);
+                    }
+                } else {
+                    $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes';
+                }
+
+                $this->_isValid = false;
+                return true;
+            }
+        }
+
+        if ($ssl) {
+            $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes';
+        } else {
+            if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
+                unset($this->_channelInfo['servers']['primary']['attribs']['ssl']);
+            }
+        }
+
+        $this->_isValid = false;
+        return true;
+    }
+
+    /**
+     * @param string
+     * @return string|false
+     * @error PEAR_CHANNELFILE_ERROR_NO_SERVER
+     * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER
+     */
+    function setServer($server, $mirror = false)
+    {
+        if (empty($server)) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER);
+            return false;
+        } elseif (!$this->validChannelServer($server)) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
+                array('tag' => 'name', 'name' => $server));
+            return false;
+        }
+
+        if ($mirror) {
+            $found = false;
+            foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
+                if ($mirror == $mir['attribs']['host']) {
+                    $found = true;
+                    break;
+                }
+            }
+
+            if (!$found) {
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
+                    array('mirror' => $mirror));
+                return false;
+            }
+
+            $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server;
+            return true;
+        }
+
+        $this->_channelInfo['name'] = $server;
+        return true;
+    }
+
+    /**
+     * @param string
+     * @return boolean success
+     * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY
+     * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY
+     */
+    function setSummary($summary)
+    {
+        if (empty($summary)) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY);
+            return false;
+        } elseif (strpos(trim($summary), "\n") !== false) {
+            $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
+                array('summary' => $summary));
+        }
+
+        $this->_channelInfo['summary'] = $summary;
+        return true;
+    }
+
+    /**
+     * @param string
+     * @param boolean determines whether the alias is in channel.xml or local
+     * @return boolean success
+     */
+    function setAlias($alias, $local = false)
+    {
+        if (!$this->validChannelServer($alias)) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME,
+                array('tag' => 'suggestedalias', 'name' => $alias));
+            return false;
+        }
+
+        if ($local) {
+            $this->_channelInfo['localalias'] = $alias;
+        } else {
+            $this->_channelInfo['suggestedalias'] = $alias;
+        }
+
+        return true;
+    }
+
+    /**
+     * @return string
+     */
+    function getAlias()
+    {
+        if (isset($this->_channelInfo['localalias'])) {
+            return $this->_channelInfo['localalias'];
+        }
+        if (isset($this->_channelInfo['suggestedalias'])) {
+            return $this->_channelInfo['suggestedalias'];
+        }
+        if (isset($this->_channelInfo['name'])) {
+            return $this->_channelInfo['name'];
+        }
+        return '';
+    }
+
+    /**
+     * Set the package validation object if it differs from PEAR's default
+     * The class must be includeable via changing _ in the classname to path separator,
+     * but no checking of this is made.
+     * @param string|false pass in false to reset to the default packagename regex
+     * @return boolean success
+     */
+    function setValidationPackage($validateclass, $version)
+    {
+        if (empty($validateclass)) {
+            unset($this->_channelInfo['validatepackage']);
+        }
+        $this->_channelInfo['validatepackage'] = array('_content' => $validateclass);
+        $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version);
+    }
+
+    /**
+     * Add a protocol to the provides section
+     * @param string protocol type
+     * @param string protocol version
+     * @param string protocol name, if any
+     * @param string mirror name, if this is a mirror's protocol
+     * @return bool
+     */
+    function addFunction($type, $version, $name = '', $mirror = false)
+    {
+        if ($mirror) {
+            return $this->addMirrorFunction($mirror, $type, $version, $name);
+        }
+
+        $set = array('attribs' => array('version' => $version), '_content' => $name);
+        if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) {
+            if (!isset($this->_channelInfo['servers'])) {
+                $this->_channelInfo['servers'] = array('primary' =>
+                    array($type => array()));
+            } elseif (!isset($this->_channelInfo['servers']['primary'])) {
+                $this->_channelInfo['servers']['primary'] = array($type => array());
+            }
+
+            $this->_channelInfo['servers']['primary'][$type]['function'] = $set;
+            $this->_isValid = false;
+            return true;
+        } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) {
+            $this->_channelInfo['servers']['primary'][$type]['function'] = array(
+                $this->_channelInfo['servers']['primary'][$type]['function']);
+        }
+
+        $this->_channelInfo['servers']['primary'][$type]['function'][] = $set;
+        return true;
+    }
+    /**
+     * Add a protocol to a mirror's provides section
+     * @param string mirror name (server)
+     * @param string protocol type
+     * @param string protocol version
+     * @param string protocol name, if any
+     */
+    function addMirrorFunction($mirror, $type, $version, $name = '')
+    {
+        if (!isset($this->_channelInfo['servers']['mirror'])) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
+                array('mirror' => $mirror));
+            return false;
+        }
+
+        $setmirror = false;
+        if (isset($this->_channelInfo['servers']['mirror'][0])) {
+            foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
+                if ($mirror == $mir['attribs']['host']) {
+                    $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
+                    break;
+                }
+            }
+        } else {
+            if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
+                $setmirror = &$this->_channelInfo['servers']['mirror'];
+            }
+        }
+
+        if (!$setmirror) {
+            $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
+                array('mirror' => $mirror));
+            return false;
+        }
+
+        $set = array('attribs' => array('version' => $version), '_content' => $name);
+        if (!isset($setmirror[$type]['function'])) {
+            $setmirror[$type]['function'] = $set;
+            $this->_isValid = false;
+            return true;
+        } elseif (!isset($setmirror[$type]['function'][0])) {
+            $setmirror[$type]['function'] = array($setmirror[$type]['function']);
+        }
+
+        $setmirror[$type]['function'][] = $set;
+        $this->_isValid = false;
+        return true;
+    }
+
+    /**
+     * @param string Resource Type this url links to
+     * @param string URL
+     * @param string|false mirror name, if this is not a primary server REST base URL
+     */
+    function setBaseURL($resourceType, $url, $mirror = false)
+    {
+        if ($mirror) {
+            if (!isset($this->_channelInfo['servers']['mirror'])) {
+                $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
+                    array('mirror' => $mirror));
+                return false;
+            }
+
+            $setmirror = false;
+            if (isset($this->_channelInfo['servers']['mirror'][0])) {
+                foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
+                    if ($mirror == $mir['attribs']['host']) {
+                        $setmirror = &$this->_channelInfo['servers']['mirror'][$i];
+                        break;
+                    }
+                }
+            } else {
+                if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
+                    $setmirror = &$this->_channelInfo['servers']['mirror'];
+                }
+            }
+        } else {
+            $setmirror = &$this->_channelInfo['servers']['primary'];
+        }
+
+        $set = array('attribs' => array('type' => $resourceType), '_content' => $url);
+        if (!isset($setmirror['rest'])) {
+            $setmirror['rest'] = array();
+        }
+
+        if (!isset($setmirror['rest']['baseurl'])) {
+            $setmirror['rest']['baseurl'] = $set;
+            $this->_isValid = false;
+            return true;
+        } elseif (!isset($setmirror['rest']['baseurl'][0])) {
+            $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']);
+        }
+
+        foreach ($setmirror['rest']['baseurl'] as $i => $url) {
+            if ($url['attribs']['type'] == $resourceType) {
+                $this->_isValid = false;
+                $setmirror['rest']['baseurl'][$i] = $set;
+                return true;
+            }
+        }
+
+        $setmirror['rest']['baseurl'][] = $set;
+        $this->_isValid = false;
+        return true;
+    }
+
+    /**
+     * @param string mirror server
+     * @param int mirror http port
+     * @return boolean
+     */
+    function addMirror($server, $port = null)
+    {
+        if ($this->_channelInfo['name'] == '__uri') {
+            return false; // the __uri channel cannot have mirrors by definition
+        }
+
+        $set = array('attribs' => array('host' => $server));
+        if (is_numeric($port)) {
+            $set['attribs']['port'] = $port;
+        }
+
+        if (!isset($this->_channelInfo['servers']['mirror'])) {
+            $this->_channelInfo['servers']['mirror'] = $set;
+            return true;
+        }
+
+        if (!isset($this->_channelInfo['servers']['mirror'][0])) {
+            $this->_channelInfo['servers']['mirror'] =
+                array($this->_channelInfo['servers']['mirror']);
+        }
+
+        $this->_channelInfo['servers']['mirror'][] = $set;
+        return true;
+    }
+
+    /**
+     * Retrieve the name of the validation package for this channel
+     * @return string|false
+     */
+    function getValidationPackage()
+    {
+        if (!$this->_isValid && !$this->validate()) {
+            return false;
+        }
+
+        if (!isset($this->_channelInfo['validatepackage'])) {
+            return array('attribs' => array('version' => 'default'),
+                '_content' => 'PEAR_Validate');
+        }
+
+        return $this->_channelInfo['validatepackage'];
+    }
+
+    /**
+     * Retrieve the object that can be used for custom validation
+     * @param string|false the name of the package to validate.  If the package is
+     *                     the channel validation package, PEAR_Validate is returned
+     * @return PEAR_Validate|false false is returned if the validation package
+     *         cannot be located
+     */
+    function &getValidationObject($package = false)
+    {
+        if (!class_exists('PEAR_Validate')) {
+            require_once 'PEAR/Validate.php';
+        }
+
+        if (!$this->_isValid) {
+            if (!$this->validate()) {
+                $a = false;
+                return $a;
+            }
+        }
+
+        if (isset($this->_channelInfo['validatepackage'])) {
+            if ($package == $this->_channelInfo['validatepackage']) {
+                // channel validation packages are always validated by PEAR_Validate
+                $val = &new PEAR_Validate;
+                return $val;
+            }
+
+            if (!class_exists(str_replace('.', '_',
+                  $this->_channelInfo['validatepackage']['_content']))) {
+                if ($this->isIncludeable(str_replace('_', '/',
+                      $this->_channelInfo['validatepackage']['_content']) . '.php')) {
+                    include_once str_replace('_', '/',
+                        $this->_channelInfo['validatepackage']['_content']) . '.php';
+                    $vclass = str_replace('.', '_',
+                        $this->_channelInfo['validatepackage']['_content']);
+                    $val = &new $vclass;
+                } else {
+                    $a = false;
+                    return $a;
+                }
+            } else {
+                $vclass = str_replace('.', '_',
+                    $this->_channelInfo['validatepackage']['_content']);
+                $val = &new $vclass;
+            }
+        } else {
+            $val = &new PEAR_Validate;
+        }
+
+        return $val;
+    }
+
+    function isIncludeable($path)
+    {
+        $possibilities = explode(PATH_SEPARATOR, ini_get('include_path'));
+        foreach ($possibilities as $dir) {
+            if (file_exists($dir . DIRECTORY_SEPARATOR . $path)
+                  && is_readable($dir . DIRECTORY_SEPARATOR . $path)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * This function is used by the channel updater and retrieves a value set by
+     * the registry, or the current time if it has not been set
+     * @return string
+     */
+    function lastModified()
+    {
+        if (isset($this->_channelInfo['_lastmodified'])) {
+            return $this->_channelInfo['_lastmodified'];
+        }
+
+        return time();
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/ChannelFile/Parser.php b/lib/php/PEAR/ChannelFile/Parser.php
new file mode 100644
index 00000000..a97493d4
--- /dev/null
+++ b/lib/php/PEAR/ChannelFile/Parser.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * PEAR_ChannelFile_Parser for parsing channel.xml
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Parser.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * base xml parser class
+ */
+require_once 'PEAR/XMLParser.php';
+require_once 'PEAR/ChannelFile.php';
+/**
+ * Parser for channel.xml
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_ChannelFile_Parser extends PEAR_XMLParser
+{
+    var $_config;
+    var $_logger;
+    var $_registry;
+
+    function setConfig(&$c)
+    {
+        $this->_config = &$c;
+        $this->_registry = &$c->getRegistry();
+    }
+
+    function setLogger(&$l)
+    {
+        $this->_logger = &$l;
+    }
+
+    function parse($data, $file)
+    {
+        if (PEAR::isError($err = parent::parse($data, $file))) {
+            return $err;
+        }
+
+        $ret = new PEAR_ChannelFile;
+        $ret->setConfig($this->_config);
+        if (isset($this->_logger)) {
+            $ret->setLogger($this->_logger);
+        }
+
+        $ret->fromArray($this->_unserializedData);
+        // make sure the filelist is in the easy to read format needed
+        $ret->flattenFilelist();
+        $ret->setPackagefile($file, $archive);
+        return $ret;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command.php b/lib/php/PEAR/Command.php
new file mode 100644
index 00000000..2bd6cb6f
--- /dev/null
+++ b/lib/php/PEAR/Command.php
@@ -0,0 +1,414 @@
+<?php
+/**
+ * PEAR_Command, command pattern class
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Command.php 286494 2009-07-29 06:57:11Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * Needed for error handling
+ */
+require_once 'PEAR.php';
+require_once 'PEAR/Frontend.php';
+require_once 'PEAR/XMLParser.php';
+
+/**
+ * List of commands and what classes they are implemented in.
+ * @var array command => implementing class
+ */
+$GLOBALS['_PEAR_Command_commandlist'] = array();
+
+/**
+ * List of commands and their descriptions
+ * @var array command => description
+ */
+$GLOBALS['_PEAR_Command_commanddesc'] = array();
+
+/**
+ * List of shortcuts to common commands.
+ * @var array shortcut => command
+ */
+$GLOBALS['_PEAR_Command_shortcuts'] = array();
+
+/**
+ * Array of command objects
+ * @var array class => object
+ */
+$GLOBALS['_PEAR_Command_objects'] = array();
+
+/**
+ * PEAR command class, a simple factory class for administrative
+ * commands.
+ *
+ * How to implement command classes:
+ *
+ * - The class must be called PEAR_Command_Nnn, installed in the
+ *   "PEAR/Common" subdir, with a method called getCommands() that
+ *   returns an array of the commands implemented by the class (see
+ *   PEAR/Command/Install.php for an example).
+ *
+ * - The class must implement a run() function that is called with three
+ *   params:
+ *
+ *    (string) command name
+ *    (array)  assoc array with options, freely defined by each
+ *             command, for example:
+ *             array('force' => true)
+ *    (array)  list of the other parameters
+ *
+ *   The run() function returns a PEAR_CommandResponse object.  Use
+ *   these methods to get information:
+ *
+ *    int getStatus()   Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL)
+ *                      *_PARTIAL means that you need to issue at least
+ *                      one more command to complete the operation
+ *                      (used for example for validation steps).
+ *
+ *    string getMessage()  Returns a message for the user.  Remember,
+ *                         no HTML or other interface-specific markup.
+ *
+ *   If something unexpected happens, run() returns a PEAR error.
+ *
+ * - DON'T OUTPUT ANYTHING! Return text for output instead.
+ *
+ * - DON'T USE HTML! The text you return will be used from both Gtk,
+ *   web and command-line interfaces, so for now, keep everything to
+ *   plain text.
+ *
+ * - DON'T USE EXIT OR DIE! Always use pear errors.  From static
+ *   classes do PEAR::raiseError(), from other classes do
+ *   $this->raiseError().
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Command
+{
+    // {{{ factory()
+
+    /**
+     * Get the right object for executing a command.
+     *
+     * @param string $command The name of the command
+     * @param object $config  Instance of PEAR_Config object
+     *
+     * @return object the command object or a PEAR error
+     *
+     * @access public
+     * @static
+     */
+    function &factory($command, &$config)
+    {
+        if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
+            PEAR_Command::registerCommands();
+        }
+        if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
+            $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
+        }
+        if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
+            $a = PEAR::raiseError("unknown command `$command'");
+            return $a;
+        }
+        $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
+        if (!class_exists($class)) {
+            require_once $GLOBALS['_PEAR_Command_objects'][$class];
+        }
+        if (!class_exists($class)) {
+            $a = PEAR::raiseError("unknown command `$command'");
+            return $a;
+        }
+        $ui =& PEAR_Command::getFrontendObject();
+        $obj = &new $class($ui, $config);
+        return $obj;
+    }
+
+    // }}}
+    // {{{ & getObject()
+    function &getObject($command)
+    {
+        $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
+        if (!class_exists($class)) {
+            require_once $GLOBALS['_PEAR_Command_objects'][$class];
+        }
+        if (!class_exists($class)) {
+            return PEAR::raiseError("unknown command `$command'");
+        }
+        $ui =& PEAR_Command::getFrontendObject();
+        $config = &PEAR_Config::singleton();
+        $obj = &new $class($ui, $config);
+        return $obj;
+    }
+
+    // }}}
+    // {{{ & getFrontendObject()
+
+    /**
+     * Get instance of frontend object.
+     *
+     * @return object|PEAR_Error
+     * @static
+     */
+    function &getFrontendObject()
+    {
+        $a = &PEAR_Frontend::singleton();
+        return $a;
+    }
+
+    // }}}
+    // {{{ & setFrontendClass()
+
+    /**
+     * Load current frontend class.
+     *
+     * @param string $uiclass Name of class implementing the frontend
+     *
+     * @return object the frontend object, or a PEAR error
+     * @static
+     */
+    function &setFrontendClass($uiclass)
+    {
+        $a = &PEAR_Frontend::setFrontendClass($uiclass);
+        return $a;
+    }
+
+    // }}}
+    // {{{ setFrontendType()
+
+    /**
+     * Set current frontend.
+     *
+     * @param string $uitype Name of the frontend type (for example "CLI")
+     *
+     * @return object the frontend object, or a PEAR error
+     * @static
+     */
+    function setFrontendType($uitype)
+    {
+        $uiclass = 'PEAR_Frontend_' . $uitype;
+        return PEAR_Command::setFrontendClass($uiclass);
+    }
+
+    // }}}
+    // {{{ registerCommands()
+
+    /**
+     * Scan through the Command directory looking for classes
+     * and see what commands they implement.
+     *
+     * @param bool   (optional) if FALSE (default), the new list of
+     *               commands should replace the current one.  If TRUE,
+     *               new entries will be merged with old.
+     *
+     * @param string (optional) where (what directory) to look for
+     *               classes, defaults to the Command subdirectory of
+     *               the directory from where this file (__FILE__) is
+     *               included.
+     *
+     * @return bool TRUE on success, a PEAR error on failure
+     *
+     * @access public
+     * @static
+     */
+    function registerCommands($merge = false, $dir = null)
+    {
+        $parser = new PEAR_XMLParser;
+        if ($dir === null) {
+            $dir = dirname(__FILE__) . '/Command';
+        }
+        if (!is_dir($dir)) {
+            return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory");
+        }
+        $dp = @opendir($dir);
+        if (empty($dp)) {
+            return PEAR::raiseError("registerCommands: opendir($dir) failed");
+        }
+        if (!$merge) {
+            $GLOBALS['_PEAR_Command_commandlist'] = array();
+        }
+
+        while ($file = readdir($dp)) {
+            if ($file{0} == '.' || substr($file, -4) != '.xml') {
+                continue;
+            }
+
+            $f = substr($file, 0, -4);
+            $class = "PEAR_Command_" . $f;
+            // List of commands
+            if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
+                $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php';
+            }
+
+            $parser->parse(file_get_contents("$dir/$file"));
+            $implements = $parser->getData();
+            foreach ($implements as $command => $desc) {
+                if ($command == 'attribs') {
+                    continue;
+                }
+
+                if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
+                    return PEAR::raiseError('Command "' . $command . '" already registered in ' .
+                        'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
+                }
+
+                $GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
+                $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary'];
+                if (isset($desc['shortcut'])) {
+                    $shortcut = $desc['shortcut'];
+                    if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) {
+                        return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' .
+                            'registered to command "' . $command . '" in class "' .
+                            $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
+                    }
+                    $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
+                }
+
+                if (isset($desc['options']) && $desc['options']) {
+                    foreach ($desc['options'] as $oname => $option) {
+                        if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) {
+                            return PEAR::raiseError('Option "' . $oname . '" short option "' .
+                                $option['shortopt'] . '" must be ' .
+                                'only 1 character in Command "' . $command . '" in class "' .
+                                $class . '"');
+                        }
+                    }
+                }
+            }
+        }
+
+        ksort($GLOBALS['_PEAR_Command_shortcuts']);
+        ksort($GLOBALS['_PEAR_Command_commandlist']);
+        @closedir($dp);
+        return true;
+    }
+
+    // }}}
+    // {{{ getCommands()
+
+    /**
+     * Get the list of currently supported commands, and what
+     * classes implement them.
+     *
+     * @return array command => implementing class
+     *
+     * @access public
+     * @static
+     */
+    function getCommands()
+    {
+        if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
+            PEAR_Command::registerCommands();
+        }
+        return $GLOBALS['_PEAR_Command_commandlist'];
+    }
+
+    // }}}
+    // {{{ getShortcuts()
+
+    /**
+     * Get the list of command shortcuts.
+     *
+     * @return array shortcut => command
+     *
+     * @access public
+     * @static
+     */
+    function getShortcuts()
+    {
+        if (empty($GLOBALS['_PEAR_Command_shortcuts'])) {
+            PEAR_Command::registerCommands();
+        }
+        return $GLOBALS['_PEAR_Command_shortcuts'];
+    }
+
+    // }}}
+    // {{{ getGetoptArgs()
+
+    /**
+     * Compiles arguments for getopt.
+     *
+     * @param string $command     command to get optstring for
+     * @param string $short_args  (reference) short getopt format
+     * @param array  $long_args   (reference) long getopt format
+     *
+     * @return void
+     *
+     * @access public
+     * @static
+     */
+    function getGetoptArgs($command, &$short_args, &$long_args)
+    {
+        if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
+            PEAR_Command::registerCommands();
+        }
+        if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
+            $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
+        }
+        if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
+            return null;
+        }
+        $obj = &PEAR_Command::getObject($command);
+        return $obj->getGetoptArgs($command, $short_args, $long_args);
+    }
+
+    // }}}
+    // {{{ getDescription()
+
+    /**
+     * Get description for a command.
+     *
+     * @param  string $command Name of the command
+     *
+     * @return string command description
+     *
+     * @access public
+     * @static
+     */
+    function getDescription($command)
+    {
+        if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) {
+            return null;
+        }
+        return $GLOBALS['_PEAR_Command_commanddesc'][$command];
+    }
+
+    // }}}
+    // {{{ getHelp()
+
+    /**
+     * Get help for command.
+     *
+     * @param string $command Name of the command to return help for
+     *
+     * @access public
+     * @static
+     */
+    function getHelp($command)
+    {
+        $cmds = PEAR_Command::getCommands();
+        if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
+            $command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
+        }
+        if (isset($cmds[$command])) {
+            $obj = &PEAR_Command::getObject($command);
+            return $obj->getHelp($command);
+        }
+        return false;
+    }
+    // }}}
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Auth.php b/lib/php/PEAR/Command/Auth.php
new file mode 100644
index 00000000..9eaeeab5
--- /dev/null
+++ b/lib/php/PEAR/Command/Auth.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * PEAR_Command_Auth (login, logout commands)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Auth.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ * @deprecated since 1.8.0alpha1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Channels.php';
+
+/**
+ * PEAR commands for login/logout
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ * @deprecated since 1.8.0alpha1
+ */
+class PEAR_Command_Auth extends PEAR_Command_Channels
+{
+    var $commands = array(
+        'login' => array(
+            'summary' => 'Connects and authenticates to remote server [Deprecated in favor of channel-login]',
+            'shortcut' => 'li',
+            'function' => 'doLogin',
+            'options' => array(),
+            'doc' => '<channel name>
+WARNING: This function is deprecated in favor of using channel-login
+
+Log in to a remote channel server.  If <channel name> is not supplied,
+the default channel is used. To use remote functions in the installer
+that require any kind of privileges, you need to log in first.  The
+username and password you enter here will be stored in your per-user
+PEAR configuration (~/.pearrc on Unix-like systems).  After logging
+in, your username and password will be sent along in subsequent
+operations on the remote server.',
+            ),
+        'logout' => array(
+            'summary' => 'Logs out from the remote server [Deprecated in favor of channel-logout]',
+            'shortcut' => 'lo',
+            'function' => 'doLogout',
+            'options' => array(),
+            'doc' => '
+WARNING: This function is deprecated in favor of using channel-logout
+
+Logs out from the remote server.  This command does not actually
+connect to the remote server, it only deletes the stored username and
+password from your user configuration.',
+            )
+
+        );
+
+    /**
+     * PEAR_Command_Auth constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Auth(&$ui, &$config)
+    {
+        parent::PEAR_Command_Channels($ui, $config);
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Auth.xml b/lib/php/PEAR/Command/Auth.xml
new file mode 100644
index 00000000..590193d1
--- /dev/null
+++ b/lib/php/PEAR/Command/Auth.xml
@@ -0,0 +1,30 @@
+<commands version="1.0">
+ <login>
+  <summary>Connects and authenticates to remote server [Deprecated in favor of channel-login]</summary>
+  <function>doLogin</function>
+  <shortcut>li</shortcut>
+  <options />
+  <doc>&lt;channel name&gt;
+WARNING: This function is deprecated in favor of using channel-login
+
+Log in to a remote channel server.  If &lt;channel name&gt; is not supplied,
+the default channel is used. To use remote functions in the installer
+that require any kind of privileges, you need to log in first.  The
+username and password you enter here will be stored in your per-user
+PEAR configuration (~/.pearrc on Unix-like systems).  After logging
+in, your username and password will be sent along in subsequent
+operations on the remote server.</doc>
+ </login>
+ <logout>
+  <summary>Logs out from the remote server [Deprecated in favor of channel-logout]</summary>
+  <function>doLogout</function>
+  <shortcut>lo</shortcut>
+  <options />
+  <doc>
+WARNING: This function is deprecated in favor of using channel-logout
+
+Logs out from the remote server.  This command does not actually
+connect to the remote server, it only deletes the stored username and
+password from your user configuration.</doc>
+ </logout>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Build.php b/lib/php/PEAR/Command/Build.php
new file mode 100644
index 00000000..e4821eee
--- /dev/null
+++ b/lib/php/PEAR/Command/Build.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * PEAR_Command_Auth (build command)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Build.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+
+/**
+ * PEAR commands for building extensions.
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Command_Build extends PEAR_Command_Common
+{
+    var $commands = array(
+        'build' => array(
+            'summary' => 'Build an Extension From C Source',
+            'function' => 'doBuild',
+            'shortcut' => 'b',
+            'options' => array(),
+            'doc' => '[package.xml]
+Builds one or more extensions contained in a package.'
+            ),
+        );
+
+    /**
+     * PEAR_Command_Build constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Build(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    function doBuild($command, $options, $params)
+    {
+        require_once 'PEAR/Builder.php';
+        if (sizeof($params) < 1) {
+            $params[0] = 'package.xml';
+        }
+
+        $builder = &new PEAR_Builder($this->ui);
+        $this->debug = $this->config->get('verbose');
+        $err = $builder->build($params[0], array(&$this, 'buildCallback'));
+        if (PEAR::isError($err)) {
+            return $err;
+        }
+
+        return true;
+    }
+
+    function buildCallback($what, $data)
+    {
+        if (($what == 'cmdoutput' && $this->debug > 1) ||
+            ($what == 'output' && $this->debug > 0)) {
+            $this->ui->outputData(rtrim($data), 'build');
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Build.xml b/lib/php/PEAR/Command/Build.xml
new file mode 100644
index 00000000..ec4e6f55
--- /dev/null
+++ b/lib/php/PEAR/Command/Build.xml
@@ -0,0 +1,10 @@
+<commands version="1.0">
+ <build>
+  <summary>Build an Extension From C Source</summary>
+  <function>doBuild</function>
+  <shortcut>b</shortcut>
+  <options />
+  <doc>[package.xml]
+Builds one or more extensions contained in a package.</doc>
+ </build>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Channels.php b/lib/php/PEAR/Command/Channels.php
new file mode 100644
index 00000000..f267d183
--- /dev/null
+++ b/lib/php/PEAR/Command/Channels.php
@@ -0,0 +1,883 @@
+<?php
+// /* vim: set expandtab tabstop=4 shiftwidth=4: */
+/**
+ * PEAR_Command_Channels (list-channels, update-channels, channel-delete, channel-add,
+ * channel-update, channel-info, channel-alias, channel-discover commands)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Channels.php 287561 2009-08-21 22:42:58Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+
+define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS', -500);
+
+/**
+ * PEAR commands for managing channels.
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Command_Channels extends PEAR_Command_Common
+{
+    var $commands = array(
+        'list-channels' => array(
+            'summary' => 'List Available Channels',
+            'function' => 'doList',
+            'shortcut' => 'lc',
+            'options' => array(),
+            'doc' => '
+List all available channels for installation.
+',
+            ),
+        'update-channels' => array(
+            'summary' => 'Update the Channel List',
+            'function' => 'doUpdateAll',
+            'shortcut' => 'uc',
+            'options' => array(),
+            'doc' => '
+List all installed packages in all channels.
+'
+            ),
+        'channel-delete' => array(
+            'summary' => 'Remove a Channel From the List',
+            'function' => 'doDelete',
+            'shortcut' => 'cde',
+            'options' => array(),
+            'doc' => '<channel name>
+Delete a channel from the registry.  You may not
+remove any channel that has installed packages.
+'
+            ),
+        'channel-add' => array(
+            'summary' => 'Add a Channel',
+            'function' => 'doAdd',
+            'shortcut' => 'ca',
+            'options' => array(),
+            'doc' => '<channel.xml>
+Add a private channel to the channel list.  Note that all
+public channels should be synced using "update-channels".
+Parameter may be either a local file or remote URL to a
+channel.xml.
+'
+            ),
+        'channel-update' => array(
+            'summary' => 'Update an Existing Channel',
+            'function' => 'doUpdate',
+            'shortcut' => 'cu',
+            'options' => array(
+                'force' => array(
+                    'shortopt' => 'f',
+                    'doc' => 'will force download of new channel.xml if an existing channel name is used',
+                    ),
+                'channel' => array(
+                    'shortopt' => 'c',
+                    'arg' => 'CHANNEL',
+                    'doc' => 'will force download of new channel.xml if an existing channel name is used',
+                    ),
+),
+            'doc' => '[<channel.xml>|<channel name>]
+Update a channel in the channel list directly.  Note that all
+public channels can be synced using "update-channels".
+Parameter may be a local or remote channel.xml, or the name of
+an existing channel.
+'
+            ),
+        'channel-info' => array(
+            'summary' => 'Retrieve Information on a Channel',
+            'function' => 'doInfo',
+            'shortcut' => 'ci',
+            'options' => array(),
+            'doc' => '<package>
+List the files in an installed package.
+'
+            ),
+        'channel-alias' => array(
+            'summary' => 'Specify an alias to a channel name',
+            'function' => 'doAlias',
+            'shortcut' => 'cha',
+            'options' => array(),
+            'doc' => '<channel> <alias>
+Specify a specific alias to use for a channel name.
+The alias may not be an existing channel name or
+alias.
+'
+            ),
+        'channel-discover' => array(
+            'summary' => 'Initialize a Channel from its server',
+            'function' => 'doDiscover',
+            'shortcut' => 'di',
+            'options' => array(),
+            'doc' => '[<channel.xml>|<channel name>]
+Initialize a channel from its server and create a local channel.xml.
+If <channel name> is in the format "<username>:<password>@<channel>" then
+<username> and <password> will be set as the login username/password for
+<channel>. Use caution when passing the username/password in this way, as
+it may allow other users on your computer to briefly view your username/
+password via the system\'s process list.
+'
+            ),
+        'channel-login' => array(
+            'summary' => 'Connects and authenticates to remote channel server',
+            'shortcut' => 'cli',
+            'function' => 'doLogin',
+            'options' => array(),
+            'doc' => '<channel name>
+Log in to a remote channel server.  If <channel name> is not supplied,
+the default channel is used. To use remote functions in the installer
+that require any kind of privileges, you need to log in first.  The
+username and password you enter here will be stored in your per-user
+PEAR configuration (~/.pearrc on Unix-like systems).  After logging
+in, your username and password will be sent along in subsequent
+operations on the remote server.',
+            ),
+        'channel-logout' => array(
+            'summary' => 'Logs out from the remote channel server',
+            'shortcut' => 'clo',
+            'function' => 'doLogout',
+            'options' => array(),
+            'doc' => '<channel name>
+Logs out from a remote channel server.  If <channel name> is not supplied,
+the default channel is used. This command does not actually connect to the
+remote server, it only deletes the stored username and password from your user
+configuration.',
+            ),
+        );
+
+    /**
+     * PEAR_Command_Registry constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Channels(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    function _sortChannels($a, $b)
+    {
+        return strnatcasecmp($a->getName(), $b->getName());
+    }
+
+    function doList($command, $options, $params)
+    {
+        $reg = &$this->config->getRegistry();
+        $registered = $reg->getChannels();
+        usort($registered, array(&$this, '_sortchannels'));
+        $i = $j = 0;
+        $data = array(
+            'caption' => 'Registered Channels:',
+            'border' => true,
+            'headline' => array('Channel', 'Alias', 'Summary')
+            );
+        foreach ($registered as $channel) {
+            $data['data'][] = array($channel->getName(),
+                                    $channel->getAlias(),
+                                    $channel->getSummary());
+        }
+
+        if (count($registered) === 0) {
+            $data = '(no registered channels)';
+        }
+        $this->ui->outputData($data, $command);
+        return true;
+    }
+
+    function doUpdateAll($command, $options, $params)
+    {
+        $reg = &$this->config->getRegistry();
+        $channels = $reg->getChannels();
+
+        $success = true;
+        foreach ($channels as $channel) {
+            if ($channel->getName() != '__uri') {
+                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                $err = $this->doUpdate('channel-update',
+                                          $options,
+                                          array($channel->getName()));
+                if (PEAR::isError($err)) {
+                    $this->ui->outputData($err->getMessage(), $command);
+                    $success = false;
+                } else {
+                    $success &= $err;
+                }
+            }
+        }
+        return $success;
+    }
+
+    function doInfo($command, $options, $params)
+    {
+        if (count($params) !== 1) {
+            return $this->raiseError("No channel specified");
+        }
+
+        $reg     = &$this->config->getRegistry();
+        $channel = strtolower($params[0]);
+        if ($reg->channelExists($channel)) {
+            $chan = $reg->getChannel($channel);
+            if (PEAR::isError($chan)) {
+                return $this->raiseError($chan);
+            }
+        } else {
+            if (strpos($channel, '://')) {
+                $downloader = &$this->getDownloader();
+                $tmpdir = $this->config->get('temp_dir');
+                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                $loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir);
+                PEAR::staticPopErrorHandling();
+                if (PEAR::isError($loc)) {
+                    return $this->raiseError('Cannot open "' . $channel .
+                        '" (' . $loc->getMessage() . ')');
+                } else {
+                    $contents = implode('', file($loc));
+                }
+            } else {
+                if (!file_exists($params[0])) {
+                    return $this->raiseError('Unknown channel "' . $channel . '"');
+                }
+
+                $fp = fopen($params[0], 'r');
+                if (!$fp) {
+                    return $this->raiseError('Cannot open "' . $params[0] . '"');
+                }
+
+                $contents = '';
+                while (!feof($fp)) {
+                    $contents .= fread($fp, 1024);
+                }
+                fclose($fp);
+            }
+
+            if (!class_exists('PEAR_ChannelFile')) {
+                require_once 'PEAR/ChannelFile.php';
+            }
+
+            $chan = new PEAR_ChannelFile;
+            $chan->fromXmlString($contents);
+            $chan->validate();
+            if ($errs = $chan->getErrors(true)) {
+                foreach ($errs as $err) {
+                    $this->ui->outputData($err['level'] . ': ' . $err['message']);
+                }
+                return $this->raiseError('Channel file "' . $params[0] . '" is not valid');
+            }
+        }
+
+        if (!$chan) {
+            return $this->raiseError('Serious error: Channel "' . $params[0] .
+                '" has a corrupted registry entry');
+        }
+
+        $channel = $chan->getName();
+        $caption = 'Channel ' . $channel . ' Information:';
+        $data1 = array(
+            'caption' => $caption,
+            'border' => true);
+        $data1['data']['server'] = array('Name and Server', $chan->getName());
+        if ($chan->getAlias() != $chan->getName()) {
+            $data1['data']['alias'] = array('Alias', $chan->getAlias());
+        }
+
+        $data1['data']['summary'] = array('Summary', $chan->getSummary());
+        $validate = $chan->getValidationPackage();
+        $data1['data']['vpackage'] = array('Validation Package Name', $validate['_content']);
+        $data1['data']['vpackageversion'] =
+            array('Validation Package Version', $validate['attribs']['version']);
+        $d = array();
+        $d['main'] = $data1;
+
+        $data['data'] = array();
+        $data['caption'] = 'Server Capabilities';
+        $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
+        if ($chan->supportsREST()) {
+            if ($chan->supportsREST()) {
+                $funcs = $chan->getFunctions('rest');
+                if (!isset($funcs[0])) {
+                    $funcs = array($funcs);
+                }
+                foreach ($funcs as $protocol) {
+                    $data['data'][] = array('rest', $protocol['attribs']['type'],
+                        $protocol['_content']);
+                }
+            }
+        } else {
+            $data['data'][] = array('No supported protocols');
+        }
+
+        $d['protocols'] = $data;
+        $data['data'] = array();
+        $mirrors = $chan->getMirrors();
+        if ($mirrors) {
+            $data['caption'] = 'Channel ' . $channel . ' Mirrors:';
+            unset($data['headline']);
+            foreach ($mirrors as $mirror) {
+                $data['data'][] = array($mirror['attribs']['host']);
+                $d['mirrors'] = $data;
+            }
+
+            foreach ($mirrors as $i => $mirror) {
+                $data['data'] = array();
+                $data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities';
+                $data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
+                if ($chan->supportsREST($mirror['attribs']['host'])) {
+                    if ($chan->supportsREST($mirror['attribs']['host'])) {
+                        $funcs = $chan->getFunctions('rest', $mirror['attribs']['host']);
+                        if (!isset($funcs[0])) {
+                            $funcs = array($funcs);
+                        }
+
+                        foreach ($funcs as $protocol) {
+                            $data['data'][] = array('rest', $protocol['attribs']['type'],
+                                $protocol['_content']);
+                        }
+                    }
+                } else {
+                    $data['data'][] = array('No supported protocols');
+                }
+                $d['mirrorprotocols' . $i] = $data;
+            }
+        }
+        $this->ui->outputData($d, 'channel-info');
+    }
+
+    // }}}
+
+    function doDelete($command, $options, $params)
+    {
+        if (count($params) !== 1) {
+            return $this->raiseError('channel-delete: no channel specified');
+        }
+
+        $reg = &$this->config->getRegistry();
+        if (!$reg->channelExists($params[0])) {
+            return $this->raiseError('channel-delete: channel "' . $params[0] . '" does not exist');
+        }
+
+        $channel = $reg->channelName($params[0]);
+        if ($channel == 'pear.php.net') {
+            return $this->raiseError('Cannot delete the pear.php.net channel');
+        }
+
+        if ($channel == 'pecl.php.net') {
+            return $this->raiseError('Cannot delete the pecl.php.net channel');
+        }
+
+        if ($channel == 'doc.php.net') {
+            return $this->raiseError('Cannot delete the doc.php.net channel');
+        }
+
+        if ($channel == '__uri') {
+            return $this->raiseError('Cannot delete the __uri pseudo-channel');
+        }
+
+        if (PEAR::isError($err = $reg->listPackages($channel))) {
+            return $err;
+        }
+
+        if (count($err)) {
+            return $this->raiseError('Channel "' . $channel .
+                '" has installed packages, cannot delete');
+        }
+
+        if (!$reg->deleteChannel($channel)) {
+            return $this->raiseError('Channel "' . $channel . '" deletion failed');
+        } else {
+            $this->config->deleteChannel($channel);
+            $this->ui->outputData('Channel "' . $channel . '" deleted', $command);
+        }
+    }
+
+    function doAdd($command, $options, $params)
+    {
+        if (count($params) !== 1) {
+            return $this->raiseError('channel-add: no channel file specified');
+        }
+
+        if (strpos($params[0], '://')) {
+            $downloader = &$this->getDownloader();
+            $tmpdir = $this->config->get('temp_dir');
+            if (!file_exists($tmpdir)) {
+                require_once 'System.php';
+                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                $err = System::mkdir(array('-p', $tmpdir));
+                PEAR::staticPopErrorHandling();
+                if (PEAR::isError($err)) {
+                    return $this->raiseError('channel-add: temp_dir does not exist: "' .
+                        $tmpdir .
+                        '" - You can change this location with "pear config-set temp_dir"');
+                }
+            }
+
+            if (!is_writable($tmpdir)) {
+                return $this->raiseError('channel-add: temp_dir is not writable: "' .
+                    $tmpdir .
+                    '" - You can change this location with "pear config-set temp_dir"');
+            }
+
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $loc = $downloader->downloadHttp($params[0], $this->ui, $tmpdir, null, false);
+            PEAR::staticPopErrorHandling();
+            if (PEAR::isError($loc)) {
+                return $this->raiseError('channel-add: Cannot open "' . $params[0] .
+                    '" (' . $loc->getMessage() . ')');
+            }
+
+            list($loc, $lastmodified) = $loc;
+            $contents = implode('', file($loc));
+        } else {
+            $lastmodified = $fp = false;
+            if (file_exists($params[0])) {
+                $fp = fopen($params[0], 'r');
+            }
+
+            if (!$fp) {
+                return $this->raiseError('channel-add: cannot open "' . $params[0] . '"');
+            }
+
+            $contents = '';
+            while (!feof($fp)) {
+                $contents .= fread($fp, 1024);
+            }
+            fclose($fp);
+        }
+
+        if (!class_exists('PEAR_ChannelFile')) {
+            require_once 'PEAR/ChannelFile.php';
+        }
+
+        $channel = new PEAR_ChannelFile;
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $result = $channel->fromXmlString($contents);
+        PEAR::staticPopErrorHandling();
+        if (!$result) {
+            $exit = false;
+            if (count($errors = $channel->getErrors(true))) {
+                foreach ($errors as $error) {
+                    $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message']));
+                    if (!$exit) {
+                        $exit = $error['level'] == 'error' ? true : false;
+                    }
+                }
+                if ($exit) {
+                    return $this->raiseError('channel-add: invalid channel.xml file');
+                }
+            }
+        }
+
+        $reg = &$this->config->getRegistry();
+        if ($reg->channelExists($channel->getName())) {
+            return $this->raiseError('channel-add: Channel "' . $channel->getName() .
+                '" exists, use channel-update to update entry', PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
+        }
+
+        $ret = $reg->addChannel($channel, $lastmodified);
+        if (PEAR::isError($ret)) {
+            return $ret;
+        }
+
+        if (!$ret) {
+            return $this->raiseError('channel-add: adding Channel "' . $channel->getName() .
+                '" to registry failed');
+        }
+
+        $this->config->setChannels($reg->listChannels());
+        $this->config->writeConfigFile();
+        $this->ui->outputData('Adding Channel "' . $channel->getName() . '" succeeded', $command);
+    }
+
+    function doUpdate($command, $options, $params)
+    {
+        if (count($params) !== 1) {
+            return $this->raiseError("No channel file specified");
+        }
+
+        $tmpdir = $this->config->get('temp_dir');
+        if (!file_exists($tmpdir)) {
+            require_once 'System.php';
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $err = System::mkdir(array('-p', $tmpdir));
+            PEAR::staticPopErrorHandling();
+            if (PEAR::isError($err)) {
+                return $this->raiseError('channel-add: temp_dir does not exist: "' .
+                    $tmpdir .
+                    '" - You can change this location with "pear config-set temp_dir"');
+            }
+        }
+
+        if (!is_writable($tmpdir)) {
+            return $this->raiseError('channel-add: temp_dir is not writable: "' .
+                $tmpdir .
+                '" - You can change this location with "pear config-set temp_dir"');
+        }
+
+        $reg = &$this->config->getRegistry();
+        $lastmodified = false;
+        if ((!file_exists($params[0]) || is_dir($params[0]))
+              && $reg->channelExists(strtolower($params[0]))) {
+            $c = $reg->getChannel(strtolower($params[0]));
+            if (PEAR::isError($c)) {
+                return $this->raiseError($c);
+            }
+
+            $this->ui->outputData("Updating channel \"$params[0]\"", $command);
+            $dl = &$this->getDownloader(array());
+            // if force is specified, use a timestamp of "1" to force retrieval
+            $lastmodified = isset($options['force']) ? false : $c->lastModified();
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $contents = $dl->downloadHttp('http://' . $c->getName() . '/channel.xml',
+                $this->ui, $tmpdir, null, $lastmodified);
+            PEAR::staticPopErrorHandling();
+            if (PEAR::isError($contents)) {
+                // Attempt to fall back to https
+                $this->ui->outputData("Channel \"$params[0]\" is not responding over http://, failed with message: " . $contents->getMessage());
+                $this->ui->outputData("Trying channel \"$params[0]\" over https:// instead");
+                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                $contents = $dl->downloadHttp('https://' . $c->getName() . '/channel.xml',
+                    $this->ui, $tmpdir, null, $lastmodified);
+                PEAR::staticPopErrorHandling();
+                if (PEAR::isError($contents)) {
+                    return $this->raiseError('Cannot retrieve channel.xml for channel "' .
+                        $c->getName() . '" (' . $contents->getMessage() . ')');
+                }
+            }
+
+            list($contents, $lastmodified) = $contents;
+            if (!$contents) {
+                $this->ui->outputData("Channel \"$params[0]\" is up to date");
+                return;
+            }
+
+            $contents = implode('', file($contents));
+            if (!class_exists('PEAR_ChannelFile')) {
+                require_once 'PEAR/ChannelFile.php';
+            }
+
+            $channel = new PEAR_ChannelFile;
+            $channel->fromXmlString($contents);
+            if (!$channel->getErrors()) {
+                // security check: is the downloaded file for the channel we got it from?
+                if (strtolower($channel->getName()) != strtolower($c->getName())) {
+                    if (!isset($options['force'])) {
+                        return $this->raiseError('ERROR: downloaded channel definition file' .
+                            ' for channel "' . $channel->getName() . '" from channel "' .
+                            strtolower($c->getName()) . '"');
+                    }
+
+                    $this->ui->log(0, 'WARNING: downloaded channel definition file' .
+                        ' for channel "' . $channel->getName() . '" from channel "' .
+                        strtolower($c->getName()) . '"');
+                }
+            }
+        } else {
+            if (strpos($params[0], '://')) {
+                $dl = &$this->getDownloader();
+                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                $loc = $dl->downloadHttp($params[0],
+                    $this->ui, $tmpdir, null, $lastmodified);
+                PEAR::staticPopErrorHandling();
+                if (PEAR::isError($loc)) {
+                    return $this->raiseError("Cannot open " . $params[0] .
+                         ' (' . $loc->getMessage() . ')');
+                }
+
+                list($loc, $lastmodified) = $loc;
+                $contents = implode('', file($loc));
+            } else {
+                $fp = false;
+                if (file_exists($params[0])) {
+                    $fp = fopen($params[0], 'r');
+                }
+
+                if (!$fp) {
+                    return $this->raiseError("Cannot open " . $params[0]);
+                }
+
+                $contents = '';
+                while (!feof($fp)) {
+                    $contents .= fread($fp, 1024);
+                }
+                fclose($fp);
+            }
+
+            if (!class_exists('PEAR_ChannelFile')) {
+                require_once 'PEAR/ChannelFile.php';
+            }
+
+            $channel = new PEAR_ChannelFile;
+            $channel->fromXmlString($contents);
+        }
+
+        $exit = false;
+        if (count($errors = $channel->getErrors(true))) {
+            foreach ($errors as $error) {
+                $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message']));
+                if (!$exit) {
+                    $exit = $error['level'] == 'error' ? true : false;
+                }
+            }
+            if ($exit) {
+                return $this->raiseError('Invalid channel.xml file');
+            }
+        }
+
+        if (!$reg->channelExists($channel->getName())) {
+            return $this->raiseError('Error: Channel "' . $channel->getName() .
+                '" does not exist, use channel-add to add an entry');
+        }
+
+        $ret = $reg->updateChannel($channel, $lastmodified);
+        if (PEAR::isError($ret)) {
+            return $ret;
+        }
+
+        if (!$ret) {
+            return $this->raiseError('Updating Channel "' . $channel->getName() .
+                '" in registry failed');
+        }
+
+        $this->config->setChannels($reg->listChannels());
+        $this->config->writeConfigFile();
+        $this->ui->outputData('Update of Channel "' . $channel->getName() . '" succeeded');
+    }
+
+    function &getDownloader()
+    {
+        if (!class_exists('PEAR_Downloader')) {
+            require_once 'PEAR/Downloader.php';
+        }
+        $a = new PEAR_Downloader($this->ui, array(), $this->config);
+        return $a;
+    }
+
+    function doAlias($command, $options, $params)
+    {
+        if (count($params) === 1) {
+            return $this->raiseError('No channel alias specified');
+        }
+
+        if (count($params) !== 2 || (!empty($params[1]) && $params[1]{0} == '-')) {
+            return $this->raiseError(
+                'Invalid format, correct is: channel-alias channel alias');
+        }
+
+        $reg = &$this->config->getRegistry();
+        if (!$reg->channelExists($params[0], true)) {
+            $extra = '';
+            if ($reg->isAlias($params[0])) {
+                $extra = ' (use "channel-alias ' . $reg->channelName($params[0]) . ' ' .
+                    strtolower($params[1]) . '")';
+            }
+
+            return $this->raiseError('"' . $params[0] . '" is not a valid channel' . $extra);
+        }
+
+        if ($reg->isAlias($params[1])) {
+            return $this->raiseError('Channel "' . $reg->channelName($params[1]) . '" is ' .
+                'already aliased to "' . strtolower($params[1]) . '", cannot re-alias');
+        }
+
+        $chan = &$reg->getChannel($params[0]);
+        if (PEAR::isError($chan)) {
+            return $this->raiseError('Corrupt registry?  Error retrieving channel "' . $params[0] .
+                '" information (' . $chan->getMessage() . ')');
+        }
+
+        // make it a local alias
+        if (!$chan->setAlias(strtolower($params[1]), true)) {
+            return $this->raiseError('Alias "' . strtolower($params[1]) .
+                '" is not a valid channel alias');
+        }
+
+        $reg->updateChannel($chan);
+        $this->ui->outputData('Channel "' . $chan->getName() . '" aliased successfully to "' .
+            strtolower($params[1]) . '"');
+    }
+
+    /**
+     * The channel-discover command
+     *
+     * @param string $command command name
+     * @param array  $options option_name => value
+     * @param array  $params  list of additional parameters.
+     *               $params[0] should contain a string with either:
+     *               - <channel name> or
+     *               - <username>:<password>@<channel name>
+     * @return null|PEAR_Error
+     */
+    function doDiscover($command, $options, $params)
+    {
+        if (count($params) !== 1) {
+            return $this->raiseError("No channel server specified");
+        }
+
+        // Look for the possible input format "<username>:<password>@<channel>"
+        if (preg_match('/^(.+):(.+)@(.+)\\z/', $params[0], $matches)) {
+            $username = $matches[1];
+            $password = $matches[2];
+            $channel  = $matches[3];
+        } else {
+            $channel = $params[0];
+        }
+
+        $reg = &$this->config->getRegistry();
+        if ($reg->channelExists($channel)) {
+            if (!$reg->isAlias($channel)) {
+                return $this->raiseError("Channel \"$channel\" is already initialized", PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
+            }
+
+            return $this->raiseError("A channel alias named \"$channel\" " .
+                'already exists, aliasing channel "' . $reg->channelName($channel)
+                . '"');
+        }
+
+        $this->pushErrorHandling(PEAR_ERROR_RETURN);
+        $err = $this->doAdd($command, $options, array('http://' . $channel . '/channel.xml'));
+        $this->popErrorHandling();
+        if (PEAR::isError($err)) {
+            if ($err->getCode() === PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS) {
+                return $this->raiseError("Discovery of channel \"$channel\" failed (" .
+                    $err->getMessage() . ')');
+            }
+            // Attempt fetch via https
+            $this->ui->outputData("Discovering channel $channel over http:// failed with message: " . $err->getMessage());
+            $this->ui->outputData("Trying to discover channel $channel over https:// instead");
+            $this->pushErrorHandling(PEAR_ERROR_RETURN);
+            $err = $this->doAdd($command, $options, array('https://' . $channel . '/channel.xml'));
+            $this->popErrorHandling();
+            if (PEAR::isError($err)) {
+                return $this->raiseError("Discovery of channel \"$channel\" failed (" .
+                    $err->getMessage() . ')');
+            }
+        }
+
+        // Store username/password if they were given
+        // Arguably we should do a logintest on the channel here, but since
+        // that's awkward on a REST-based channel (even "pear login" doesn't
+        // do it for those), and XML-RPC is deprecated, it's fairly pointless.
+        if (isset($username)) {
+            $this->config->set('username', $username, 'user', $channel);
+            $this->config->set('password', $password, 'user', $channel);
+            $this->config->store();
+            $this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\"", $command);
+        }
+
+        $this->ui->outputData("Discovery of channel \"$channel\" succeeded", $command);
+    }
+
+    /**
+     * Execute the 'login' command.
+     *
+     * @param string $command command name
+     * @param array $options option_name => value
+     * @param array $params list of additional parameters
+     *
+     * @return bool TRUE on success or
+     * a PEAR error on failure
+     *
+     * @access public
+     */
+    function doLogin($command, $options, $params)
+    {
+        $reg = &$this->config->getRegistry();
+
+        // If a parameter is supplied, use that as the channel to log in to
+        $channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel');
+
+        $chan = $reg->getChannel($channel);
+        if (PEAR::isError($chan)) {
+            return $this->raiseError($chan);
+        }
+
+        $server   = $this->config->get('preferred_mirror', null, $channel);
+        $username = $this->config->get('username',         null, $channel);
+        if (empty($username)) {
+            $username = isset($_ENV['USER']) ? $_ENV['USER'] : null;
+        }
+        $this->ui->outputData("Logging in to $server.", $command);
+
+        list($username, $password) = $this->ui->userDialog(
+            $command,
+            array('Username', 'Password'),
+            array('text',     'password'),
+            array($username,  '')
+            );
+        $username = trim($username);
+        $password = trim($password);
+
+        $ourfile = $this->config->getConfFile('user');
+        if (!$ourfile) {
+            $ourfile = $this->config->getConfFile('system');
+        }
+
+        $this->config->set('username', $username, 'user', $channel);
+        $this->config->set('password', $password, 'user', $channel);
+
+        if ($chan->supportsREST()) {
+            $ok = true;
+        }
+
+        if ($ok !== true) {
+            return $this->raiseError('Login failed!');
+        }
+
+        $this->ui->outputData("Logged in.", $command);
+        // avoid changing any temporary settings changed with -d
+        $ourconfig = new PEAR_Config($ourfile, $ourfile);
+        $ourconfig->set('username', $username, 'user', $channel);
+        $ourconfig->set('password', $password, 'user', $channel);
+        $ourconfig->store();
+
+        return true;
+    }
+
+    /**
+     * Execute the 'logout' command.
+     *
+     * @param string $command command name
+     * @param array $options option_name => value
+     * @param array $params list of additional parameters
+     *
+     * @return bool TRUE on success or
+     * a PEAR error on failure
+     *
+     * @access public
+     */
+    function doLogout($command, $options, $params)
+    {
+        $reg     = &$this->config->getRegistry();
+
+        // If a parameter is supplied, use that as the channel to log in to
+        $channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel');
+
+        $chan    = $reg->getChannel($channel);
+        if (PEAR::isError($chan)) {
+            return $this->raiseError($chan);
+        }
+
+        $server = $this->config->get('preferred_mirror', null, $channel);
+        $this->ui->outputData("Logging out from $server.", $command);
+        $this->config->remove('username', 'user', $channel);
+        $this->config->remove('password', 'user', $channel);
+        $this->config->store();
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Channels.xml b/lib/php/PEAR/Command/Channels.xml
new file mode 100644
index 00000000..47b72066
--- /dev/null
+++ b/lib/php/PEAR/Command/Channels.xml
@@ -0,0 +1,123 @@
+<commands version="1.0">
+ <list-channels>
+  <summary>List Available Channels</summary>
+  <function>doList</function>
+  <shortcut>lc</shortcut>
+  <options />
+  <doc>
+List all available channels for installation.
+</doc>
+ </list-channels>
+ <update-channels>
+  <summary>Update the Channel List</summary>
+  <function>doUpdateAll</function>
+  <shortcut>uc</shortcut>
+  <options />
+  <doc>
+List all installed packages in all channels.
+</doc>
+ </update-channels>
+ <channel-delete>
+  <summary>Remove a Channel From the List</summary>
+  <function>doDelete</function>
+  <shortcut>cde</shortcut>
+  <options />
+  <doc>&lt;channel name&gt;
+Delete a channel from the registry.  You may not
+remove any channel that has installed packages.
+</doc>
+ </channel-delete>
+ <channel-add>
+  <summary>Add a Channel</summary>
+  <function>doAdd</function>
+  <shortcut>ca</shortcut>
+  <options />
+  <doc>&lt;channel.xml&gt;
+Add a private channel to the channel list.  Note that all
+public channels should be synced using &quot;update-channels&quot;.
+Parameter may be either a local file or remote URL to a
+channel.xml.
+</doc>
+ </channel-add>
+ <channel-update>
+  <summary>Update an Existing Channel</summary>
+  <function>doUpdate</function>
+  <shortcut>cu</shortcut>
+  <options>
+   <force>
+    <shortopt>f</shortopt>
+    <doc>will force download of new channel.xml if an existing channel name is used</doc>
+   </force>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>will force download of new channel.xml if an existing channel name is used</doc>
+    <arg>CHANNEL</arg>
+   </channel>
+  </options>
+  <doc>[&lt;channel.xml&gt;|&lt;channel name&gt;]
+Update a channel in the channel list directly.  Note that all
+public channels can be synced using &quot;update-channels&quot;.
+Parameter may be a local or remote channel.xml, or the name of
+an existing channel.
+</doc>
+ </channel-update>
+ <channel-info>
+  <summary>Retrieve Information on a Channel</summary>
+  <function>doInfo</function>
+  <shortcut>ci</shortcut>
+  <options />
+  <doc>&lt;package&gt;
+List the files in an installed package.
+</doc>
+ </channel-info>
+ <channel-alias>
+  <summary>Specify an alias to a channel name</summary>
+  <function>doAlias</function>
+  <shortcut>cha</shortcut>
+  <options />
+  <doc>&lt;channel&gt; &lt;alias&gt;
+Specify a specific alias to use for a channel name.
+The alias may not be an existing channel name or
+alias.
+</doc>
+ </channel-alias>
+ <channel-discover>
+  <summary>Initialize a Channel from its server</summary>
+  <function>doDiscover</function>
+  <shortcut>di</shortcut>
+  <options />
+  <doc>[&lt;channel.xml&gt;|&lt;channel name&gt;]
+Initialize a channel from its server and create a local channel.xml.
+If &lt;channel name&gt; is in the format &quot;&lt;username&gt;:&lt;password&gt;@&lt;channel&gt;&quot; then
+&lt;username&gt; and &lt;password&gt; will be set as the login username/password for
+&lt;channel&gt;. Use caution when passing the username/password in this way, as
+it may allow other users on your computer to briefly view your username/
+password via the system&#039;s process list.
+</doc>
+ </channel-discover>
+ <channel-login>
+  <summary>Connects and authenticates to remote channel server</summary>
+  <function>doLogin</function>
+  <shortcut>cli</shortcut>
+  <options />
+  <doc>&lt;channel name&gt;
+Log in to a remote channel server.  If &lt;channel name&gt; is not supplied,
+the default channel is used. To use remote functions in the installer
+that require any kind of privileges, you need to log in first.  The
+username and password you enter here will be stored in your per-user
+PEAR configuration (~/.pearrc on Unix-like systems).  After logging
+in, your username and password will be sent along in subsequent
+operations on the remote server.</doc>
+ </channel-login>
+ <channel-logout>
+  <summary>Logs out from the remote channel server</summary>
+  <function>doLogout</function>
+  <shortcut>clo</shortcut>
+  <options />
+  <doc>&lt;channel name&gt;
+Logs out from a remote channel server.  If &lt;channel name&gt; is not supplied,
+the default channel is used. This command does not actually connect to the
+remote server, it only deletes the stored username and password from your user
+configuration.</doc>
+ </channel-logout>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Common.php b/lib/php/PEAR/Command/Common.php
new file mode 100644
index 00000000..9427bccc
--- /dev/null
+++ b/lib/php/PEAR/Command/Common.php
@@ -0,0 +1,273 @@
+<?php
+/**
+ * PEAR_Command_Common base class
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR.php';
+
+/**
+ * PEAR commands base class
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Command_Common extends PEAR
+{
+    /**
+     * PEAR_Config object used to pass user system and configuration
+     * on when executing commands
+     *
+     * @var PEAR_Config
+     */
+    var $config;
+    /**
+     * @var PEAR_Registry
+     * @access protected
+     */
+    var $_registry;
+
+    /**
+     * User Interface object, for all interaction with the user.
+     * @var object
+     */
+    var $ui;
+
+    var $_deps_rel_trans = array(
+                                 'lt' => '<',
+                                 'le' => '<=',
+                                 'eq' => '=',
+                                 'ne' => '!=',
+                                 'gt' => '>',
+                                 'ge' => '>=',
+                                 'has' => '=='
+                                 );
+
+    var $_deps_type_trans = array(
+                                  'pkg' => 'package',
+                                  'ext' => 'extension',
+                                  'php' => 'PHP',
+                                  'prog' => 'external program',
+                                  'ldlib' => 'external library for linking',
+                                  'rtlib' => 'external runtime library',
+                                  'os' => 'operating system',
+                                  'websrv' => 'web server',
+                                  'sapi' => 'SAPI backend'
+                                  );
+
+    /**
+     * PEAR_Command_Common constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Common(&$ui, &$config)
+    {
+        parent::PEAR();
+        $this->config = &$config;
+        $this->ui = &$ui;
+    }
+
+    /**
+     * Return a list of all the commands defined by this class.
+     * @return array list of commands
+     * @access public
+     */
+    function getCommands()
+    {
+        $ret = array();
+        foreach (array_keys($this->commands) as $command) {
+            $ret[$command] = $this->commands[$command]['summary'];
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Return a list of all the command shortcuts defined by this class.
+     * @return array shortcut => command
+     * @access public
+     */
+    function getShortcuts()
+    {
+        $ret = array();
+        foreach (array_keys($this->commands) as $command) {
+            if (isset($this->commands[$command]['shortcut'])) {
+                $ret[$this->commands[$command]['shortcut']] = $command;
+            }
+        }
+
+        return $ret;
+    }
+
+    function getOptions($command)
+    {
+        $shortcuts = $this->getShortcuts();
+        if (isset($shortcuts[$command])) {
+            $command = $shortcuts[$command];
+        }
+
+        if (isset($this->commands[$command]) &&
+              isset($this->commands[$command]['options'])) {
+            return $this->commands[$command]['options'];
+        }
+
+        return null;
+    }
+
+    function getGetoptArgs($command, &$short_args, &$long_args)
+    {
+        $short_args = '';
+        $long_args = array();
+        if (empty($this->commands[$command]) || empty($this->commands[$command]['options'])) {
+            return;
+        }
+
+        reset($this->commands[$command]['options']);
+        while (list($option, $info) = each($this->commands[$command]['options'])) {
+            $larg = $sarg = '';
+            if (isset($info['arg'])) {
+                if ($info['arg']{0} == '(') {
+                    $larg = '==';
+                    $sarg = '::';
+                    $arg = substr($info['arg'], 1, -1);
+                } else {
+                    $larg = '=';
+                    $sarg = ':';
+                    $arg = $info['arg'];
+                }
+            }
+
+            if (isset($info['shortopt'])) {
+                $short_args .= $info['shortopt'] . $sarg;
+            }
+
+            $long_args[] = $option . $larg;
+        }
+    }
+
+    /**
+    * Returns the help message for the given command
+    *
+    * @param string $command The command
+    * @return mixed A fail string if the command does not have help or
+    *               a two elements array containing [0]=>help string,
+    *               [1]=> help string for the accepted cmd args
+    */
+    function getHelp($command)
+    {
+        $config = &PEAR_Config::singleton();
+        if (!isset($this->commands[$command])) {
+            return "No such command \"$command\"";
+        }
+
+        $help = null;
+        if (isset($this->commands[$command]['doc'])) {
+            $help = $this->commands[$command]['doc'];
+        }
+
+        if (empty($help)) {
+            // XXX (cox) Fallback to summary if there is no doc (show both?)
+            if (!isset($this->commands[$command]['summary'])) {
+                return "No help for command \"$command\"";
+            }
+            $help = $this->commands[$command]['summary'];
+        }
+
+        if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) {
+            foreach($matches[0] as $k => $v) {
+                $help = preg_replace("/$v/", $config->get($matches[1][$k]), $help);
+            }
+        }
+
+        return array($help, $this->getHelpArgs($command));
+    }
+
+    /**
+     * Returns the help for the accepted arguments of a command
+     *
+     * @param  string $command
+     * @return string The help string
+     */
+    function getHelpArgs($command)
+    {
+        if (isset($this->commands[$command]['options']) &&
+            count($this->commands[$command]['options']))
+        {
+            $help = "Options:\n";
+            foreach ($this->commands[$command]['options'] as $k => $v) {
+                if (isset($v['arg'])) {
+                    if ($v['arg'][0] == '(') {
+                        $arg = substr($v['arg'], 1, -1);
+                        $sapp = " [$arg]";
+                        $lapp = "[=$arg]";
+                    } else {
+                        $sapp = " $v[arg]";
+                        $lapp = "=$v[arg]";
+                    }
+                } else {
+                    $sapp = $lapp = "";
+                }
+
+                if (isset($v['shortopt'])) {
+                    $s = $v['shortopt'];
+                    $help .= "  -$s$sapp, --$k$lapp\n";
+                } else {
+                    $help .= "  --$k$lapp\n";
+                }
+
+                $p = "        ";
+                $doc = rtrim(str_replace("\n", "\n$p", $v['doc']));
+                $help .= "        $doc\n";
+            }
+
+            return $help;
+        }
+
+        return null;
+    }
+
+    function run($command, $options, $params)
+    {
+        if (empty($this->commands[$command]['function'])) {
+            // look for shortcuts
+            foreach (array_keys($this->commands) as $cmd) {
+                if (isset($this->commands[$cmd]['shortcut']) && $this->commands[$cmd]['shortcut'] == $command) {
+                    if (empty($this->commands[$cmd]['function'])) {
+                        return $this->raiseError("unknown command `$command'");
+                    } else {
+                        $func = $this->commands[$cmd]['function'];
+                    }
+                    $command = $cmd;
+
+                    //$command = $this->commands[$cmd]['function'];
+                    break;
+                }
+            }
+        } else {
+            $func = $this->commands[$command]['function'];
+        }
+
+        return $this->$func($command, $options, $params);
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Config.php b/lib/php/PEAR/Command/Config.php
new file mode 100644
index 00000000..7fd863b4
--- /dev/null
+++ b/lib/php/PEAR/Command/Config.php
@@ -0,0 +1,413 @@
+<?php
+/**
+ * PEAR_Command_Config (config-show, config-get, config-set, config-help, config-create commands)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Config.php 287554 2009-08-21 21:16:25Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+
+/**
+ * PEAR commands for managing configuration data.
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Command_Config extends PEAR_Command_Common
+{
+    var $commands = array(
+        'config-show' => array(
+            'summary' => 'Show All Settings',
+            'function' => 'doConfigShow',
+            'shortcut' => 'csh',
+            'options' => array(
+                'channel' => array(
+                    'shortopt' => 'c',
+                    'doc' => 'show configuration variables for another channel',
+                    'arg' => 'CHAN',
+                    ),
+),
+            'doc' => '[layer]
+Displays all configuration values.  An optional argument
+may be used to tell which configuration layer to display.  Valid
+configuration layers are "user", "system" and "default". To display
+configurations for different channels, set the default_channel
+configuration variable and run config-show again.
+',
+            ),
+        'config-get' => array(
+            'summary' => 'Show One Setting',
+            'function' => 'doConfigGet',
+            'shortcut' => 'cg',
+            'options' => array(
+                'channel' => array(
+                    'shortopt' => 'c',
+                    'doc' => 'show configuration variables for another channel',
+                    'arg' => 'CHAN',
+                    ),
+),
+            'doc' => '<parameter> [layer]
+Displays the value of one configuration parameter.  The
+first argument is the name of the parameter, an optional second argument
+may be used to tell which configuration layer to look in.  Valid configuration
+layers are "user", "system" and "default".  If no layer is specified, a value
+will be picked from the first layer that defines the parameter, in the order
+just specified.  The configuration value will be retrieved for the channel
+specified by the default_channel configuration variable.
+',
+            ),
+        'config-set' => array(
+            'summary' => 'Change Setting',
+            'function' => 'doConfigSet',
+            'shortcut' => 'cs',
+            'options' => array(
+                'channel' => array(
+                    'shortopt' => 'c',
+                    'doc' => 'show configuration variables for another channel',
+                    'arg' => 'CHAN',
+                    ),
+),
+            'doc' => '<parameter> <value> [layer]
+Sets the value of one configuration parameter.  The first argument is
+the name of the parameter, the second argument is the new value.  Some
+parameters are subject to validation, and the command will fail with
+an error message if the new value does not make sense.  An optional
+third argument may be used to specify in which layer to set the
+configuration parameter.  The default layer is "user".  The
+configuration value will be set for the current channel, which
+is controlled by the default_channel configuration variable.
+',
+            ),
+        'config-help' => array(
+            'summary' => 'Show Information About Setting',
+            'function' => 'doConfigHelp',
+            'shortcut' => 'ch',
+            'options' => array(),
+            'doc' => '[parameter]
+Displays help for a configuration parameter.  Without arguments it
+displays help for all configuration parameters.
+',
+           ),
+        'config-create' => array(
+            'summary' => 'Create a Default configuration file',
+            'function' => 'doConfigCreate',
+            'shortcut' => 'coc',
+            'options' => array(
+                'windows' => array(
+                    'shortopt' => 'w',
+                    'doc' => 'create a config file for a windows install',
+                    ),
+            ),
+            'doc' => '<root path> <filename>
+Create a default configuration file with all directory configuration
+variables set to subdirectories of <root path>, and save it as <filename>.
+This is useful especially for creating a configuration file for a remote
+PEAR installation (using the --remoteconfig option of install, upgrade,
+and uninstall).
+',
+            ),
+        );
+
+    /**
+     * PEAR_Command_Config constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Config(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    function doConfigShow($command, $options, $params)
+    {
+        $layer = null;
+        if (is_array($params)) {
+            $layer = isset($params[0]) ? $params[0] : null;
+        }
+
+        // $params[0] -> the layer
+        if ($error = $this->_checkLayer($layer)) {
+            return $this->raiseError("config-show:$error");
+        }
+
+        $keys = $this->config->getKeys();
+        sort($keys);
+        $channel = isset($options['channel']) ? $options['channel'] :
+            $this->config->get('default_channel');
+        $reg = &$this->config->getRegistry();
+        if (!$reg->channelExists($channel)) {
+            return $this->raiseError('Channel "' . $channel . '" does not exist');
+        }
+
+        $channel = $reg->channelName($channel);
+        $data = array('caption' => 'Configuration (channel ' . $channel . '):');
+        foreach ($keys as $key) {
+            $type = $this->config->getType($key);
+            $value = $this->config->get($key, $layer, $channel);
+            if ($type == 'password' && $value) {
+                $value = '********';
+            }
+
+            if ($value === false) {
+                $value = 'false';
+            } elseif ($value === true) {
+                $value = 'true';
+            }
+
+            $data['data'][$this->config->getGroup($key)][] = array($this->config->getPrompt($key) , $key, $value);
+        }
+
+        foreach ($this->config->getLayers() as $layer) {
+            $data['data']['Config Files'][] = array(ucfirst($layer) . ' Configuration File', 'Filename' , $this->config->getConfFile($layer));
+        }
+
+        $this->ui->outputData($data, $command);
+        return true;
+    }
+
+    function doConfigGet($command, $options, $params)
+    {
+        $args_cnt = is_array($params) ? count($params) : 0;
+        switch ($args_cnt) {
+            case 1:
+                $config_key = $params[0];
+                $layer = null;
+                break;
+            case 2:
+                $config_key = $params[0];
+                $layer = $params[1];
+                if ($error = $this->_checkLayer($layer)) {
+                    return $this->raiseError("config-get:$error");
+                }
+                break;
+            case 0:
+            default:
+                return $this->raiseError("config-get expects 1 or 2 parameters");
+        }
+
+        $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
+        $reg = &$this->config->getRegistry();
+        if (!$reg->channelExists($channel)) {
+            return $this->raiseError('Channel "' . $channel . '" does not exist');
+        }
+
+        $this->ui->outputData($this->config->get($config_key, $layer, $channel), $command);
+        return true;
+    }
+
+    function doConfigSet($command, $options, $params)
+    {
+        // $param[0] -> a parameter to set
+        // $param[1] -> the value for the parameter
+        // $param[2] -> the layer
+        $failmsg = '';
+        if (count($params) < 2 || count($params) > 3) {
+            $failmsg .= "config-set expects 2 or 3 parameters";
+            return PEAR::raiseError($failmsg);
+        }
+
+        if (isset($params[2]) && ($error = $this->_checkLayer($params[2]))) {
+            $failmsg .= $error;
+            return PEAR::raiseError("config-set:$failmsg");
+        }
+
+        $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
+        $reg = &$this->config->getRegistry();
+        if (!$reg->channelExists($channel)) {
+            return $this->raiseError('Channel "' . $channel . '" does not exist');
+        }
+
+        $channel = $reg->channelName($channel);
+        if ($params[0] == 'default_channel' && !$reg->channelExists($params[1])) {
+            return $this->raiseError('Channel "' . $params[1] . '" does not exist');
+        }
+
+        if ($params[0] == 'preferred_mirror'
+            && (
+                !$reg->mirrorExists($channel, $params[1]) &&
+                (!$reg->channelExists($params[1]) || $channel != $params[1])
+            )
+        ) {
+            $msg  = 'Channel Mirror "' . $params[1] . '" does not exist';
+            $msg .= ' in your registry for channel "' . $channel . '".';
+            $msg .= "\n" . 'Attempt to run "pear channel-update ' . $channel .'"';
+            $msg .= ' if you believe this mirror should exist as you may';
+            $msg .= ' have outdated channel information.';
+            return $this->raiseError($msg);
+        }
+
+        if (count($params) == 2) {
+            array_push($params, 'user');
+            $layer = 'user';
+        } else {
+            $layer = $params[2];
+        }
+
+        array_push($params, $channel);
+        if (!call_user_func_array(array(&$this->config, 'set'), $params)) {
+            array_pop($params);
+            $failmsg = "config-set (" . implode(", ", $params) . ") failed, channel $channel";
+        } else {
+            $this->config->store($layer);
+        }
+
+        if ($failmsg) {
+            return $this->raiseError($failmsg);
+        }
+
+        $this->ui->outputData('config-set succeeded', $command);
+        return true;
+    }
+
+    function doConfigHelp($command, $options, $params)
+    {
+        if (empty($params)) {
+            $params = $this->config->getKeys();
+        }
+
+        $data['caption']  = "Config help" . ((count($params) == 1) ? " for $params[0]" : '');
+        $data['headline'] = array('Name', 'Type', 'Description');
+        $data['border']   = true;
+        foreach ($params as $name) {
+            $type = $this->config->getType($name);
+            $docs = $this->config->getDocs($name);
+            if ($type == 'set') {
+                $docs = rtrim($docs) . "\nValid set: " .
+                    implode(' ', $this->config->getSetValues($name));
+            }
+
+            $data['data'][] = array($name, $type, $docs);
+        }
+
+        $this->ui->outputData($data, $command);
+    }
+
+    function doConfigCreate($command, $options, $params)
+    {
+        if (count($params) != 2) {
+            return PEAR::raiseError('config-create: must have 2 parameters, root path and ' .
+                'filename to save as');
+        }
+
+        $root = $params[0];
+        // Clean up the DIRECTORY_SEPARATOR mess
+        $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
+        $root = preg_replace(array('!\\\\+!', '!/+!', "!$ds2+!"),
+                             array('/', '/', '/'),
+                            $root);
+        if ($root{0} != '/') {
+            if (!isset($options['windows'])) {
+                return PEAR::raiseError('Root directory must be an absolute path beginning ' .
+                    'with "/", was: "' . $root . '"');
+            }
+
+            if (!preg_match('/^[A-Za-z]:/', $root)) {
+                return PEAR::raiseError('Root directory must be an absolute path beginning ' .
+                    'with "\\" or "C:\\", was: "' . $root . '"');
+            }
+        }
+
+        $windows = isset($options['windows']);
+        if ($windows) {
+            $root = str_replace('/', '\\', $root);
+        }
+
+        if (!file_exists($params[1]) && !@touch($params[1])) {
+            return PEAR::raiseError('Could not create "' . $params[1] . '"');
+        }
+
+        $params[1] = realpath($params[1]);
+        $config = &new PEAR_Config($params[1], '#no#system#config#', false, false);
+        if ($root{strlen($root) - 1} == '/') {
+            $root = substr($root, 0, strlen($root) - 1);
+        }
+
+        $config->noRegistry();
+        $config->set('php_dir', $windows ? "$root\\pear\\php" : "$root/pear/php", 'user');
+        $config->set('data_dir', $windows ? "$root\\pear\\data" : "$root/pear/data");
+        $config->set('www_dir', $windows ? "$root\\pear\\www" : "$root/pear/www");
+        $config->set('cfg_dir', $windows ? "$root\\pear\\cfg" : "$root/pear/cfg");
+        $config->set('ext_dir', $windows ? "$root\\pear\\ext" : "$root/pear/ext");
+        $config->set('doc_dir', $windows ? "$root\\pear\\docs" : "$root/pear/docs");
+        $config->set('test_dir', $windows ? "$root\\pear\\tests" : "$root/pear/tests");
+        $config->set('cache_dir', $windows ? "$root\\pear\\cache" : "$root/pear/cache");
+        $config->set('download_dir', $windows ? "$root\\pear\\download" : "$root/pear/download");
+        $config->set('temp_dir', $windows ? "$root\\pear\\temp" : "$root/pear/temp");
+        $config->set('bin_dir', $windows ? "$root\\pear" : "$root/pear");
+        $config->writeConfigFile();
+        $this->_showConfig($config);
+        $this->ui->outputData('Successfully created default configuration file "' . $params[1] . '"',
+            $command);
+    }
+
+    function _showConfig(&$config)
+    {
+        $params = array('user');
+        $keys = $config->getKeys();
+        sort($keys);
+        $channel = 'pear.php.net';
+        $data = array('caption' => 'Configuration (channel ' . $channel . '):');
+        foreach ($keys as $key) {
+            $type = $config->getType($key);
+            $value = $config->get($key, 'user', $channel);
+            if ($type == 'password' && $value) {
+                $value = '********';
+            }
+
+            if ($value === false) {
+                $value = 'false';
+            } elseif ($value === true) {
+                $value = 'true';
+            }
+            $data['data'][$config->getGroup($key)][] =
+                array($config->getPrompt($key) , $key, $value);
+        }
+
+        foreach ($config->getLayers() as $layer) {
+            $data['data']['Config Files'][] =
+                array(ucfirst($layer) . ' Configuration File', 'Filename' ,
+                    $config->getConfFile($layer));
+        }
+
+        $this->ui->outputData($data, 'config-show');
+        return true;
+    }
+
+    /**
+     * Checks if a layer is defined or not
+     *
+     * @param string $layer The layer to search for
+     * @return mixed False on no error or the error message
+     */
+    function _checkLayer($layer = null)
+    {
+        if (!empty($layer) && $layer != 'default') {
+            $layers = $this->config->getLayers();
+            if (!in_array($layer, $layers)) {
+                return " only the layers: \"" . implode('" or "', $layers) . "\" are supported";
+            }
+        }
+
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Config.xml b/lib/php/PEAR/Command/Config.xml
new file mode 100644
index 00000000..f64a925f
--- /dev/null
+++ b/lib/php/PEAR/Command/Config.xml
@@ -0,0 +1,92 @@
+<commands version="1.0">
+ <config-show>
+  <summary>Show All Settings</summary>
+  <function>doConfigShow</function>
+  <shortcut>csh</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>show configuration variables for another channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+  </options>
+  <doc>[layer]
+Displays all configuration values.  An optional argument
+may be used to tell which configuration layer to display.  Valid
+configuration layers are &quot;user&quot;, &quot;system&quot; and &quot;default&quot;. To display
+configurations for different channels, set the default_channel
+configuration variable and run config-show again.
+</doc>
+ </config-show>
+ <config-get>
+  <summary>Show One Setting</summary>
+  <function>doConfigGet</function>
+  <shortcut>cg</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>show configuration variables for another channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+  </options>
+  <doc>&lt;parameter&gt; [layer]
+Displays the value of one configuration parameter.  The
+first argument is the name of the parameter, an optional second argument
+may be used to tell which configuration layer to look in.  Valid configuration
+layers are &quot;user&quot;, &quot;system&quot; and &quot;default&quot;.  If no layer is specified, a value
+will be picked from the first layer that defines the parameter, in the order
+just specified.  The configuration value will be retrieved for the channel
+specified by the default_channel configuration variable.
+</doc>
+ </config-get>
+ <config-set>
+  <summary>Change Setting</summary>
+  <function>doConfigSet</function>
+  <shortcut>cs</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>show configuration variables for another channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+  </options>
+  <doc>&lt;parameter&gt; &lt;value&gt; [layer]
+Sets the value of one configuration parameter.  The first argument is
+the name of the parameter, the second argument is the new value.  Some
+parameters are subject to validation, and the command will fail with
+an error message if the new value does not make sense.  An optional
+third argument may be used to specify in which layer to set the
+configuration parameter.  The default layer is &quot;user&quot;.  The
+configuration value will be set for the current channel, which
+is controlled by the default_channel configuration variable.
+</doc>
+ </config-set>
+ <config-help>
+  <summary>Show Information About Setting</summary>
+  <function>doConfigHelp</function>
+  <shortcut>ch</shortcut>
+  <options />
+  <doc>[parameter]
+Displays help for a configuration parameter.  Without arguments it
+displays help for all configuration parameters.
+</doc>
+ </config-help>
+ <config-create>
+  <summary>Create a Default configuration file</summary>
+  <function>doConfigCreate</function>
+  <shortcut>coc</shortcut>
+  <options>
+   <windows>
+    <shortopt>w</shortopt>
+    <doc>create a config file for a windows install</doc>
+   </windows>
+  </options>
+  <doc>&lt;root path&gt; &lt;filename&gt;
+Create a default configuration file with all directory configuration
+variables set to subdirectories of &lt;root path&gt;, and save it as &lt;filename&gt;.
+This is useful especially for creating a configuration file for a remote
+PEAR installation (using the --remoteconfig option of install, upgrade,
+and uninstall).
+</doc>
+ </config-create>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Install.php b/lib/php/PEAR/Command/Install.php
new file mode 100644
index 00000000..d5a8dd47
--- /dev/null
+++ b/lib/php/PEAR/Command/Install.php
@@ -0,0 +1,1266 @@
+<?php
+/**
+ * PEAR_Command_Install (install, upgrade, upgrade-all, uninstall, bundle, run-scripts commands)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Install.php 287477 2009-08-19 14:19:43Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+
+/**
+ * PEAR commands for installation or deinstallation/upgrading of
+ * packages.
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Command_Install extends PEAR_Command_Common
+{
+    // {{{ properties
+
+    var $commands = array(
+        'install' => array(
+            'summary' => 'Install Package',
+            'function' => 'doInstall',
+            'shortcut' => 'i',
+            'options' => array(
+                'force' => array(
+                    'shortopt' => 'f',
+                    'doc' => 'will overwrite newer installed packages',
+                    ),
+                'loose' => array(
+                    'shortopt' => 'l',
+                    'doc' => 'do not check for recommended dependency version',
+                    ),
+                'nodeps' => array(
+                    'shortopt' => 'n',
+                    'doc' => 'ignore dependencies, install anyway',
+                    ),
+                'register-only' => array(
+                    'shortopt' => 'r',
+                    'doc' => 'do not install files, only register the package as installed',
+                    ),
+                'soft' => array(
+                    'shortopt' => 's',
+                    'doc' => 'soft install, fail silently, or upgrade if already installed',
+                    ),
+                'nobuild' => array(
+                    'shortopt' => 'B',
+                    'doc' => 'don\'t build C extensions',
+                    ),
+                'nocompress' => array(
+                    'shortopt' => 'Z',
+                    'doc' => 'request uncompressed files when downloading',
+                    ),
+                'installroot' => array(
+                    'shortopt' => 'R',
+                    'arg' => 'DIR',
+                    'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
+                    ),
+                'packagingroot' => array(
+                    'shortopt' => 'P',
+                    'arg' => 'DIR',
+                    'doc' => 'root directory used when packaging files, like RPM packaging',
+                    ),
+                'ignore-errors' => array(
+                    'doc' => 'force install even if there were errors',
+                    ),
+                'alldeps' => array(
+                    'shortopt' => 'a',
+                    'doc' => 'install all required and optional dependencies',
+                    ),
+                'onlyreqdeps' => array(
+                    'shortopt' => 'o',
+                    'doc' => 'install all required dependencies',
+                    ),
+                'offline' => array(
+                    'shortopt' => 'O',
+                    'doc' => 'do not attempt to download any urls or contact channels',
+                    ),
+                'pretend' => array(
+                    'shortopt' => 'p',
+                    'doc' => 'Only list the packages that would be downloaded',
+                    ),
+                ),
+            'doc' => '[channel/]<package> ...
+Installs one or more PEAR packages.  You can specify a package to
+install in four ways:
+
+"Package-1.0.tgz" : installs from a local file
+
+"http://example.com/Package-1.0.tgz" : installs from
+anywhere on the net.
+
+"package.xml" : installs the package described in
+package.xml.  Useful for testing, or for wrapping a PEAR package in
+another package manager such as RPM.
+
+"Package[-version/state][.tar]" : queries your default channel\'s server
+({config master_server}) and downloads the newest package with
+the preferred quality/state ({config preferred_state}).
+
+To retrieve Package version 1.1, use "Package-1.1," to retrieve
+Package state beta, use "Package-beta."  To retrieve an uncompressed
+file, append .tar (make sure there is no file by the same name first)
+
+To download a package from another channel, prefix with the channel name like
+"channel/Package"
+
+More than one package may be specified at once.  It is ok to mix these
+four ways of specifying packages.
+'),
+        'upgrade' => array(
+            'summary' => 'Upgrade Package',
+            'function' => 'doInstall',
+            'shortcut' => 'up',
+            'options' => array(
+                'channel' => array(
+                    'shortopt' => 'c',
+                    'doc' => 'upgrade packages from a specific channel',
+                    'arg' => 'CHAN',
+                    ),
+                'force' => array(
+                    'shortopt' => 'f',
+                    'doc' => 'overwrite newer installed packages',
+                    ),
+                'loose' => array(
+                    'shortopt' => 'l',
+                    'doc' => 'do not check for recommended dependency version',
+                    ),
+                'nodeps' => array(
+                    'shortopt' => 'n',
+                    'doc' => 'ignore dependencies, upgrade anyway',
+                    ),
+                'register-only' => array(
+                    'shortopt' => 'r',
+                    'doc' => 'do not install files, only register the package as upgraded',
+                    ),
+                'nobuild' => array(
+                    'shortopt' => 'B',
+                    'doc' => 'don\'t build C extensions',
+                    ),
+                'nocompress' => array(
+                    'shortopt' => 'Z',
+                    'doc' => 'request uncompressed files when downloading',
+                    ),
+                'installroot' => array(
+                    'shortopt' => 'R',
+                    'arg' => 'DIR',
+                    'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)',
+                    ),
+                'ignore-errors' => array(
+                    'doc' => 'force install even if there were errors',
+                    ),
+                'alldeps' => array(
+                    'shortopt' => 'a',
+                    'doc' => 'install all required and optional dependencies',
+                    ),
+                'onlyreqdeps' => array(
+                    'shortopt' => 'o',
+                    'doc' => 'install all required dependencies',
+                    ),
+                'offline' => array(
+                    'shortopt' => 'O',
+                    'doc' => 'do not attempt to download any urls or contact channels',
+                    ),
+                'pretend' => array(
+                    'shortopt' => 'p',
+                    'doc' => 'Only list the packages that would be downloaded',
+                    ),
+                ),
+            'doc' => '<package> ...
+Upgrades one or more PEAR packages.  See documentation for the
+"install" command for ways to specify a package.
+
+When upgrading, your package will be updated if the provided new
+package has a higher version number (use the -f option if you need to
+upgrade anyway).
+
+More than one package may be specified at once.
+'),
+        'upgrade-all' => array(
+            'summary' => 'Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]',
+            'function' => 'doUpgradeAll',
+            'shortcut' => 'ua',
+            'options' => array(
+                'channel' => array(
+                    'shortopt' => 'c',
+                    'doc' => 'upgrade packages from a specific channel',
+                    'arg' => 'CHAN',
+                    ),
+                'nodeps' => array(
+                    'shortopt' => 'n',
+                    'doc' => 'ignore dependencies, upgrade anyway',
+                    ),
+                'register-only' => array(
+                    'shortopt' => 'r',
+                    'doc' => 'do not install files, only register the package as upgraded',
+                    ),
+                'nobuild' => array(
+                    'shortopt' => 'B',
+                    'doc' => 'don\'t build C extensions',
+                    ),
+                'nocompress' => array(
+                    'shortopt' => 'Z',
+                    'doc' => 'request uncompressed files when downloading',
+                    ),
+                'installroot' => array(
+                    'shortopt' => 'R',
+                    'arg' => 'DIR',
+                    'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
+                    ),
+                'ignore-errors' => array(
+                    'doc' => 'force install even if there were errors',
+                    ),
+                'loose' => array(
+                    'doc' => 'do not check for recommended dependency version',
+                    ),
+                ),
+            'doc' => '
+WARNING: This function is deprecated in favor of using the upgrade command with no params
+
+Upgrades all packages that have a newer release available.  Upgrades are
+done only if there is a release available of the state specified in
+"preferred_state" (currently {config preferred_state}), or a state considered
+more stable.
+'),
+        'uninstall' => array(
+            'summary' => 'Un-install Package',
+            'function' => 'doUninstall',
+            'shortcut' => 'un',
+            'options' => array(
+                'nodeps' => array(
+                    'shortopt' => 'n',
+                    'doc' => 'ignore dependencies, uninstall anyway',
+                    ),
+                'register-only' => array(
+                    'shortopt' => 'r',
+                    'doc' => 'do not remove files, only register the packages as not installed',
+                    ),
+                'installroot' => array(
+                    'shortopt' => 'R',
+                    'arg' => 'DIR',
+                    'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)',
+                    ),
+                'ignore-errors' => array(
+                    'doc' => 'force install even if there were errors',
+                    ),
+                'offline' => array(
+                    'shortopt' => 'O',
+                    'doc' => 'do not attempt to uninstall remotely',
+                    ),
+                ),
+            'doc' => '[channel/]<package> ...
+Uninstalls one or more PEAR packages.  More than one package may be
+specified at once.  Prefix with channel name to uninstall from a
+channel not in your default channel ({config default_channel})
+'),
+        'bundle' => array(
+            'summary' => 'Unpacks a Pecl Package',
+            'function' => 'doBundle',
+            'shortcut' => 'bun',
+            'options' => array(
+                'destination' => array(
+                   'shortopt' => 'd',
+                    'arg' => 'DIR',
+                    'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)',
+                    ),
+                'force' => array(
+                    'shortopt' => 'f',
+                    'doc' => 'Force the unpacking even if there were errors in the package',
+                ),
+            ),
+            'doc' => '<package>
+Unpacks a Pecl Package into the selected location. It will download the
+package if needed.
+'),
+        'run-scripts' => array(
+            'summary' => 'Run Post-Install Scripts bundled with a package',
+            'function' => 'doRunScripts',
+            'shortcut' => 'rs',
+            'options' => array(
+            ),
+            'doc' => '<package>
+Run post-installation scripts in package <package>, if any exist.
+'),
+    );
+
+    // }}}
+    // {{{ constructor
+
+    /**
+     * PEAR_Command_Install constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Install(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    // }}}
+
+    /**
+     * For unit testing purposes
+     */
+    function &getDownloader(&$ui, $options, &$config)
+    {
+        if (!class_exists('PEAR_Downloader')) {
+            require_once 'PEAR/Downloader.php';
+        }
+        $a = &new PEAR_Downloader($ui, $options, $config);
+        return $a;
+    }
+
+    /**
+     * For unit testing purposes
+     */
+    function &getInstaller(&$ui)
+    {
+        if (!class_exists('PEAR_Installer')) {
+            require_once 'PEAR/Installer.php';
+        }
+        $a = &new PEAR_Installer($ui);
+        return $a;
+    }
+
+    function enableExtension($binaries, $type)
+    {
+        if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) {
+            return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location');
+        }
+        $ini = $this->_parseIni($phpini);
+        if (PEAR::isError($ini)) {
+            return $ini;
+        }
+        $line = 0;
+        if ($type == 'extsrc' || $type == 'extbin') {
+            $search = 'extensions';
+            $enable = 'extension';
+        } else {
+            $search = 'zend_extensions';
+            ob_start();
+            phpinfo(INFO_GENERAL);
+            $info = ob_get_contents();
+            ob_end_clean();
+            $debug = function_exists('leak') ? '_debug' : '';
+            $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
+            $enable = 'zend_extension' . $debug . $ts;
+        }
+        foreach ($ini[$search] as $line => $extension) {
+            if (in_array($extension, $binaries, true) || in_array(
+                  $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) {
+                // already enabled - assume if one is, all are
+                return true;
+            }
+        }
+        if ($line) {
+            $newini = array_slice($ini['all'], 0, $line);
+        } else {
+            $newini = array();
+        }
+        foreach ($binaries as $binary) {
+            if ($ini['extension_dir']) {
+                $binary = basename($binary);
+            }
+            $newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n");
+        }
+        $newini = array_merge($newini, array_slice($ini['all'], $line));
+        $fp = @fopen($phpini, 'wb');
+        if (!$fp) {
+            return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
+        }
+        foreach ($newini as $line) {
+            fwrite($fp, $line);
+        }
+        fclose($fp);
+        return true;
+    }
+
+    function disableExtension($binaries, $type)
+    {
+        if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) {
+            return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location');
+        }
+        $ini = $this->_parseIni($phpini);
+        if (PEAR::isError($ini)) {
+            return $ini;
+        }
+        $line = 0;
+        if ($type == 'extsrc' || $type == 'extbin') {
+            $search = 'extensions';
+            $enable = 'extension';
+        } else {
+            $search = 'zend_extensions';
+            ob_start();
+            phpinfo(INFO_GENERAL);
+            $info = ob_get_contents();
+            ob_end_clean();
+            $debug = function_exists('leak') ? '_debug' : '';
+            $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
+            $enable = 'zend_extension' . $debug . $ts;
+        }
+        $found = false;
+        foreach ($ini[$search] as $line => $extension) {
+            if (in_array($extension, $binaries, true) || in_array(
+                  $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) {
+                $found = true;
+                break;
+            }
+        }
+        if (!$found) {
+            // not enabled
+            return true;
+        }
+        $fp = @fopen($phpini, 'wb');
+        if (!$fp) {
+            return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
+        }
+        if ($line) {
+            $newini = array_slice($ini['all'], 0, $line);
+            // delete the enable line
+            $newini = array_merge($newini, array_slice($ini['all'], $line + 1));
+        } else {
+            $newini = array_slice($ini['all'], 1);
+        }
+        foreach ($newini as $line) {
+            fwrite($fp, $line);
+        }
+        fclose($fp);
+        return true;
+    }
+
+    function _parseIni($filename)
+    {
+        if (!file_exists($filename)) {
+            return PEAR::raiseError('php.ini "' . $filename . '" does not exist');
+        }
+
+        if (filesize($filename) > 300000) {
+            return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting');
+        }
+
+        ob_start();
+        phpinfo(INFO_GENERAL);
+        $info = ob_get_contents();
+        ob_end_clean();
+        $debug = function_exists('leak') ? '_debug' : '';
+        $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
+        $zend_extension_line = 'zend_extension' . $debug . $ts;
+        $all = @file($filename);
+        if (!$all) {
+            return PEAR::raiseError('php.ini "' . $filename .'" could not be read');
+        }
+        $zend_extensions = $extensions = array();
+        // assume this is right, but pull from the php.ini if it is found
+        $extension_dir = ini_get('extension_dir');
+        foreach ($all as $linenum => $line) {
+            $line = trim($line);
+            if (!$line) {
+                continue;
+            }
+            if ($line[0] == ';') {
+                continue;
+            }
+            if (strtolower(substr($line, 0, 13)) == 'extension_dir') {
+                $line = trim(substr($line, 13));
+                if ($line[0] == '=') {
+                    $x = trim(substr($line, 1));
+                    $x = explode(';', $x);
+                    $extension_dir = str_replace('"', '', array_shift($x));
+                    continue;
+                }
+            }
+            if (strtolower(substr($line, 0, 9)) == 'extension') {
+                $line = trim(substr($line, 9));
+                if ($line[0] == '=') {
+                    $x = trim(substr($line, 1));
+                    $x = explode(';', $x);
+                    $extensions[$linenum] = str_replace('"', '', array_shift($x));
+                    continue;
+                }
+            }
+            if (strtolower(substr($line, 0, strlen($zend_extension_line))) ==
+                  $zend_extension_line) {
+                $line = trim(substr($line, strlen($zend_extension_line)));
+                if ($line[0] == '=') {
+                    $x = trim(substr($line, 1));
+                    $x = explode(';', $x);
+                    $zend_extensions[$linenum] = str_replace('"', '', array_shift($x));
+                    continue;
+                }
+            }
+        }
+        return array(
+            'extensions' => $extensions,
+            'zend_extensions' => $zend_extensions,
+            'extension_dir' => $extension_dir,
+            'all' => $all,
+        );
+    }
+
+    // {{{ doInstall()
+
+    function doInstall($command, $options, $params)
+    {
+        if (!class_exists('PEAR_PackageFile')) {
+            require_once 'PEAR/PackageFile.php';
+        }
+
+        if (isset($options['installroot']) && isset($options['packagingroot'])) {
+            return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot');
+        }
+
+        $reg = &$this->config->getRegistry();
+        $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
+        if (!$reg->channelExists($channel)) {
+            return $this->raiseError('Channel "' . $channel . '" does not exist');
+        }
+
+        if (empty($this->installer)) {
+            $this->installer = &$this->getInstaller($this->ui);
+        }
+
+        if ($command == 'upgrade' || $command == 'upgrade-all') {
+            // If people run the upgrade command but pass nothing, emulate a upgrade-all
+            if ($command == 'upgrade' && empty($params)) {
+                return $this->doUpgradeAll($command, $options, $params);
+            }
+            $options['upgrade'] = true;
+        } else {
+            $packages = $params;
+        }
+
+        $instreg = &$reg; // instreg used to check if package is installed
+        if (isset($options['packagingroot']) && !isset($options['upgrade'])) {
+            $packrootphp_dir = $this->installer->_prependPath(
+                $this->config->get('php_dir', null, 'pear.php.net'),
+                $options['packagingroot']);
+            $instreg = new PEAR_Registry($packrootphp_dir); // other instreg!
+
+            if ($this->config->get('verbose') > 2) {
+                $this->ui->outputData('using package root: ' . $options['packagingroot']);
+            }
+        }
+
+        $abstractpackages = $otherpackages = array();
+        // parse params
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+
+        foreach ($params as $param) {
+            if (strpos($param, 'http://') === 0) {
+                $otherpackages[] = $param;
+                continue;
+            }
+
+            if (strpos($param, 'channel://') === false && @file_exists($param)) {
+                if (isset($options['force'])) {
+                    $otherpackages[] = $param;
+                    continue;
+                }
+
+                $pkg = new PEAR_PackageFile($this->config);
+                $pf  = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING);
+                if (PEAR::isError($pf)) {
+                    $otherpackages[] = $param;
+                    continue;
+                }
+
+                $exists   = $reg->packageExists($pf->getPackage(), $pf->getChannel());
+                $pversion = $reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel());
+                $version_compare = version_compare($pf->getVersion(), $pversion, '<=');
+                if ($exists && $version_compare) {
+                    if ($this->config->get('verbose')) {
+                        $this->ui->outputData('Ignoring installed package ' .
+                            $reg->parsedPackageNameToString(
+                            array('package' => $pf->getPackage(),
+                                  'channel' => $pf->getChannel()), true));
+                    }
+                    continue;
+                }
+                $otherpackages[] = $param;
+                continue;
+            }
+
+            $e = $reg->parsePackageName($param, $channel);
+            if (PEAR::isError($e)) {
+                $otherpackages[] = $param;
+            } else {
+                $abstractpackages[] = $e;
+            }
+        }
+        PEAR::staticPopErrorHandling();
+
+        // if there are any local package .tgz or remote static url, we can't
+        // filter.  The filter only works for abstract packages
+        if (count($abstractpackages) && !isset($options['force'])) {
+            // when not being forced, only do necessary upgrades/installs
+            if (isset($options['upgrade'])) {
+                $abstractpackages = $this->_filterUptodatePackages($abstractpackages, $command);
+            } else {
+                $count = count($abstractpackages);
+                foreach ($abstractpackages as $i => $package) {
+                    if (isset($package['group'])) {
+                        // do not filter out install groups
+                        continue;
+                    }
+
+                    if ($instreg->packageExists($package['package'], $package['channel'])) {
+                        if ($count > 1) {
+                            if ($this->config->get('verbose')) {
+                                $this->ui->outputData('Ignoring installed package ' .
+                                    $reg->parsedPackageNameToString($package, true));
+                            }
+                            unset($abstractpackages[$i]);
+                        } elseif ($count === 1) {
+                            // Lets try to upgrade it since it's already installed
+                            $options['upgrade'] = true;
+                        }
+                    }
+                }
+            }
+            $abstractpackages =
+                array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
+        } elseif (count($abstractpackages)) {
+            $abstractpackages =
+                array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
+        }
+
+        $packages = array_merge($abstractpackages, $otherpackages);
+        if (!count($packages)) {
+            $c = '';
+            if (isset($options['channel'])){
+                $c .= ' in channel "' . $options['channel'] . '"';
+            }
+            $this->ui->outputData('Nothing to ' . $command . $c);
+            return true;
+        }
+
+        $this->downloader = &$this->getDownloader($this->ui, $options, $this->config);
+        $errors = $downloaded = $binaries = array();
+        $downloaded = &$this->downloader->download($packages);
+        if (PEAR::isError($downloaded)) {
+            return $this->raiseError($downloaded);
+        }
+
+        $errors = $this->downloader->getErrorMsgs();
+        if (count($errors)) {
+            $err = array();
+            $err['data'] = array();
+            foreach ($errors as $error) {
+                if ($error !== null) {
+                    $err['data'][] = array($error);
+                }
+            }
+
+            if (!empty($err['data'])) {
+                $err['headline'] = 'Install Errors';
+                $this->ui->outputData($err);
+            }
+
+            if (!count($downloaded)) {
+                return $this->raiseError("$command failed");
+            }
+        }
+
+        $data = array(
+            'headline' => 'Packages that would be Installed'
+        );
+
+        if (isset($options['pretend'])) {
+            foreach ($downloaded as $package) {
+                $data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage()));
+            }
+            $this->ui->outputData($data, 'pretend');
+            return true;
+        }
+
+        $this->installer->setOptions($options);
+        $this->installer->sortPackagesForInstall($downloaded);
+        if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) {
+            $this->raiseError($err->getMessage());
+            return true;
+        }
+
+        $binaries = $extrainfo = array();
+        foreach ($downloaded as $param) {
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $info = $this->installer->install($param, $options);
+            PEAR::staticPopErrorHandling();
+            if (PEAR::isError($info)) {
+                $oldinfo = $info;
+                $pkg = &$param->getPackageFile();
+                if ($info->getCode() != PEAR_INSTALLER_NOBINARY) {
+                    if (!($info = $pkg->installBinary($this->installer))) {
+                        $this->ui->outputData('ERROR: ' .$oldinfo->getMessage());
+                        continue;
+                    }
+
+                    // we just installed a different package than requested,
+                    // let's change the param and info so that the rest of this works
+                    $param = $info[0];
+                    $info  = $info[1];
+                }
+            }
+
+            if (!is_array($info)) {
+                return $this->raiseError("$command failed");
+            }
+
+            if ($param->getPackageType() == 'extsrc' ||
+                  $param->getPackageType() == 'extbin' ||
+                  $param->getPackageType() == 'zendextsrc' ||
+                  $param->getPackageType() == 'zendextbin') {
+                $pkg = &$param->getPackageFile();
+                if ($instbin = $pkg->getInstalledBinary()) {
+                    $instpkg = &$instreg->getPackage($instbin, $pkg->getChannel());
+                } else {
+                    $instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel());
+                }
+
+                foreach ($instpkg->getFilelist() as $name => $atts) {
+                    $pinfo = pathinfo($atts['installed_as']);
+                    if (!isset($pinfo['extension']) ||
+                          in_array($pinfo['extension'], array('c', 'h'))) {
+                        continue; // make sure we don't match php_blah.h
+                    }
+
+                    if ((strpos($pinfo['basename'], 'php_') === 0 &&
+                          $pinfo['extension'] == 'dll') ||
+                          // most unices
+                          $pinfo['extension'] == 'so' ||
+                          // hp-ux
+                          $pinfo['extension'] == 'sl') {
+                        $binaries[] = array($atts['installed_as'], $pinfo);
+                        break;
+                    }
+                }
+
+                if (count($binaries)) {
+                    foreach ($binaries as $pinfo) {
+                        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                        $ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType());
+                        PEAR::staticPopErrorHandling();
+                        if (PEAR::isError($ret)) {
+                            $extrainfo[] = $ret->getMessage();
+                            if ($param->getPackageType() == 'extsrc' ||
+                                  $param->getPackageType() == 'extbin') {
+                                $exttype = 'extension';
+                            } else {
+                                ob_start();
+                                phpinfo(INFO_GENERAL);
+                                $info = ob_get_contents();
+                                ob_end_clean();
+                                $debug = function_exists('leak') ? '_debug' : '';
+                                $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
+                                $exttype = 'zend_extension' . $debug . $ts;
+                            }
+                            $extrainfo[] = 'You should add "' . $exttype . '=' .
+                                $pinfo[1]['basename'] . '" to php.ini';
+                        } else {
+                            $extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() .
+                                ' enabled in php.ini';
+                        }
+                    }
+                }
+            }
+
+            if ($this->config->get('verbose') > 0) {
+                $chan = $param->getChannel();
+                $label = $reg->parsedPackageNameToString(
+                    array(
+                        'channel' => $chan,
+                        'package' => $param->getPackage(),
+                        'version' => $param->getVersion(),
+                    ));
+                $out = array('data' => "$command ok: $label");
+                if (isset($info['release_warnings'])) {
+                    $out['release_warnings'] = $info['release_warnings'];
+                }
+                $this->ui->outputData($out, $command);
+
+                if (!isset($options['register-only']) && !isset($options['offline'])) {
+                    if ($this->config->isDefinedLayer('ftp')) {
+                        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                        $info = $this->installer->ftpInstall($param);
+                        PEAR::staticPopErrorHandling();
+                        if (PEAR::isError($info)) {
+                            $this->ui->outputData($info->getMessage());
+                            $this->ui->outputData("remote install failed: $label");
+                        } else {
+                            $this->ui->outputData("remote install ok: $label");
+                        }
+                    }
+                }
+            }
+
+            $deps = $param->getDeps();
+            if ($deps) {
+                if (isset($deps['group'])) {
+                    $groups = $deps['group'];
+                    if (!isset($groups[0])) {
+                        $groups = array($groups);
+                    }
+
+                    foreach ($groups as $group) {
+                        if ($group['attribs']['name'] == 'default') {
+                            // default group is always installed, unless the user
+                            // explicitly chooses to install another group
+                            continue;
+                        }
+                        $extrainfo[] = $param->getPackage() . ': Optional feature ' .
+                            $group['attribs']['name'] . ' available (' .
+                            $group['attribs']['hint'] . ')';
+                    }
+
+                    $extrainfo[] = $param->getPackage() .
+                        ': To install optional features use "pear install ' .
+                        $reg->parsedPackageNameToString(
+                            array('package' => $param->getPackage(),
+                                  'channel' => $param->getChannel()), true) .
+                              '#featurename"';
+                }
+            }
+
+            $pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel());
+            // $pkg may be NULL if install is a 'fake' install via --packagingroot
+            if (is_object($pkg)) {
+                $pkg->setConfig($this->config);
+                if ($list = $pkg->listPostinstallScripts()) {
+                    $pn = $reg->parsedPackageNameToString(array('channel' =>
+                       $param->getChannel(), 'package' => $param->getPackage()), true);
+                    $extrainfo[] = $pn . ' has post-install scripts:';
+                    foreach ($list as $file) {
+                        $extrainfo[] = $file;
+                    }
+                    $extrainfo[] = $param->getPackage() .
+                        ': Use "pear run-scripts ' . $pn . '" to finish setup.';
+                    $extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES';
+                }
+            }
+        }
+
+        if (count($extrainfo)) {
+            foreach ($extrainfo as $info) {
+                $this->ui->outputData($info);
+            }
+        }
+
+        return true;
+    }
+
+    // }}}
+    // {{{ doUpgradeAll()
+
+    function doUpgradeAll($command, $options, $params)
+    {
+        $reg = &$this->config->getRegistry();
+        $upgrade = array();
+
+        if (isset($options['channel'])) {
+            $channels = array($options['channel']);
+        } else {
+            $channels = $reg->listChannels();
+        }
+
+        foreach ($channels as $channel) {
+            if ($channel == '__uri') {
+                continue;
+            }
+
+            // parse name with channel
+            foreach ($reg->listPackages($channel) as $name) {
+                $upgrade[] = $reg->parsedPackageNameToString(array(
+                        'channel' => $channel,
+                        'package' => $name
+                    ));
+            }
+        }
+
+        $err = $this->doInstall($command, $options, $upgrade);
+        if (PEAR::isError($err)) {
+            $this->ui->outputData($err->getMessage(), $command);
+        }
+   }
+
+    // }}}
+    // {{{ doUninstall()
+
+    function doUninstall($command, $options, $params)
+    {
+        if (count($params) < 1) {
+            return $this->raiseError("Please supply the package(s) you want to uninstall");
+        }
+
+        if (empty($this->installer)) {
+            $this->installer = &$this->getInstaller($this->ui);
+        }
+
+        if (isset($options['remoteconfig'])) {
+            $e = $this->config->readFTPConfigFile($options['remoteconfig']);
+            if (!PEAR::isError($e)) {
+                $this->installer->setConfig($this->config);
+            }
+        }
+
+        $reg = &$this->config->getRegistry();
+        $newparams = array();
+        $binaries = array();
+        $badparams = array();
+        foreach ($params as $pkg) {
+            $channel = $this->config->get('default_channel');
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $parsed = $reg->parsePackageName($pkg, $channel);
+            PEAR::staticPopErrorHandling();
+            if (!$parsed || PEAR::isError($parsed)) {
+                $badparams[] = $pkg;
+                continue;
+            }
+            $package = $parsed['package'];
+            $channel = $parsed['channel'];
+            $info = &$reg->getPackage($package, $channel);
+            if ($info === null &&
+                 ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) {
+                // make sure this isn't a package that has flipped from pear to pecl but
+                // used a package.xml 1.0
+                $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net';
+                $info = &$reg->getPackage($package, $testc);
+                if ($info !== null) {
+                    $channel = $testc;
+                }
+            }
+            if ($info === null) {
+                $badparams[] = $pkg;
+            } else {
+                $newparams[] = &$info;
+                // check for binary packages (this is an alias for those packages if so)
+                if ($installedbinary = $info->getInstalledBinary()) {
+                    $this->ui->log('adding binary package ' .
+                        $reg->parsedPackageNameToString(array('channel' => $channel,
+                            'package' => $installedbinary), true));
+                    $newparams[] = &$reg->getPackage($installedbinary, $channel);
+                }
+                // add the contents of a dependency group to the list of installed packages
+                if (isset($parsed['group'])) {
+                    $group = $info->getDependencyGroup($parsed['group']);
+                    if ($group) {
+                        $installed = $reg->getInstalledGroup($group);
+                        if ($installed) {
+                            foreach ($installed as $i => $p) {
+                                $newparams[] = &$installed[$i];
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        $err = $this->installer->sortPackagesForUninstall($newparams);
+        if (PEAR::isError($err)) {
+            $this->ui->outputData($err->getMessage(), $command);
+            return true;
+        }
+        $params = $newparams;
+        // twist this to use it to check on whether dependent packages are also being uninstalled
+        // for circular dependencies like subpackages
+        $this->installer->setUninstallPackages($newparams);
+        $params = array_merge($params, $badparams);
+        $binaries = array();
+        foreach ($params as $pkg) {
+            $this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
+            if ($err = $this->installer->uninstall($pkg, $options)) {
+                $this->installer->popErrorHandling();
+                if (PEAR::isError($err)) {
+                    $this->ui->outputData($err->getMessage(), $command);
+                    continue;
+                }
+                if ($pkg->getPackageType() == 'extsrc' ||
+                      $pkg->getPackageType() == 'extbin' ||
+                      $pkg->getPackageType() == 'zendextsrc' ||
+                      $pkg->getPackageType() == 'zendextbin') {
+                    if ($instbin = $pkg->getInstalledBinary()) {
+                        continue; // this will be uninstalled later
+                    }
+
+                    foreach ($pkg->getFilelist() as $name => $atts) {
+                        $pinfo = pathinfo($atts['installed_as']);
+                        if (!isset($pinfo['extension']) ||
+                              in_array($pinfo['extension'], array('c', 'h'))) {
+                            continue; // make sure we don't match php_blah.h
+                        }
+                        if ((strpos($pinfo['basename'], 'php_') === 0 &&
+                              $pinfo['extension'] == 'dll') ||
+                              // most unices
+                              $pinfo['extension'] == 'so' ||
+                              // hp-ux
+                              $pinfo['extension'] == 'sl') {
+                            $binaries[] = array($atts['installed_as'], $pinfo);
+                            break;
+                        }
+                    }
+                    if (count($binaries)) {
+                        foreach ($binaries as $pinfo) {
+                            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                            $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType());
+                            PEAR::staticPopErrorHandling();
+                            if (PEAR::isError($ret)) {
+                                $extrainfo[] = $ret->getMessage();
+                                if ($pkg->getPackageType() == 'extsrc' ||
+                                      $pkg->getPackageType() == 'extbin') {
+                                    $exttype = 'extension';
+                                } else {
+                                    ob_start();
+                                    phpinfo(INFO_GENERAL);
+                                    $info = ob_get_contents();
+                                    ob_end_clean();
+                                    $debug = function_exists('leak') ? '_debug' : '';
+                                    $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
+                                    $exttype = 'zend_extension' . $debug . $ts;
+                                }
+                                $this->ui->outputData('Unable to remove "' . $exttype . '=' .
+                                    $pinfo[1]['basename'] . '" from php.ini', $command);
+                            } else {
+                                $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() .
+                                    ' disabled in php.ini', $command);
+                            }
+                        }
+                    }
+                }
+                $savepkg = $pkg;
+                if ($this->config->get('verbose') > 0) {
+                    if (is_object($pkg)) {
+                        $pkg = $reg->parsedPackageNameToString($pkg);
+                    }
+                    $this->ui->outputData("uninstall ok: $pkg", $command);
+                }
+                if (!isset($options['offline']) && is_object($savepkg) &&
+                      defined('PEAR_REMOTEINSTALL_OK')) {
+                    if ($this->config->isDefinedLayer('ftp')) {
+                        $this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
+                        $info = $this->installer->ftpUninstall($savepkg);
+                        $this->installer->popErrorHandling();
+                        if (PEAR::isError($info)) {
+                            $this->ui->outputData($info->getMessage());
+                            $this->ui->outputData("remote uninstall failed: $pkg");
+                        } else {
+                            $this->ui->outputData("remote uninstall ok: $pkg");
+                        }
+                    }
+                }
+            } else {
+                $this->installer->popErrorHandling();
+                if (!is_object($pkg)) {
+                    return $this->raiseError("uninstall failed: $pkg");
+                }
+                $pkg = $reg->parsedPackageNameToString($pkg);
+            }
+        }
+
+        return true;
+    }
+
+    // }}}
+
+
+    // }}}
+    // {{{ doBundle()
+    /*
+    (cox) It just downloads and untars the package, does not do
+            any check that the PEAR_Installer::_installFile() does.
+    */
+
+    function doBundle($command, $options, $params)
+    {
+        $opts = array(
+            'force'        => true,
+            'nodeps'       => true,
+            'soft'         => true,
+            'downloadonly' => true
+        );
+        $downloader = &$this->getDownloader($this->ui, $opts, $this->config);
+        $reg = &$this->config->getRegistry();
+        if (count($params) < 1) {
+            return $this->raiseError("Please supply the package you want to bundle");
+        }
+
+        if (isset($options['destination'])) {
+            if (!is_dir($options['destination'])) {
+                System::mkdir('-p ' . $options['destination']);
+            }
+            $dest = realpath($options['destination']);
+        } else {
+            $pwd  = getcwd();
+            $dir  = $pwd . DIRECTORY_SEPARATOR . 'ext';
+            $dest = is_dir($dir) ? $dir : $pwd;
+        }
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $err = $downloader->setDownloadDir($dest);
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($err)) {
+            return PEAR::raiseError('download directory "' . $dest .
+                '" is not writeable.');
+        }
+        $result = &$downloader->download(array($params[0]));
+        if (PEAR::isError($result)) {
+            return $result;
+        }
+        if (!isset($result[0])) {
+            return $this->raiseError('unable to unpack ' . $params[0]);
+        }
+        $pkgfile = &$result[0]->getPackageFile();
+        $pkgname = $pkgfile->getName();
+        $pkgversion = $pkgfile->getVersion();
+
+        // Unpacking -------------------------------------------------
+        $dest .= DIRECTORY_SEPARATOR . $pkgname;
+        $orig = $pkgname . '-' . $pkgversion;
+
+        $tar = &new Archive_Tar($pkgfile->getArchiveFile());
+        if (!$tar->extractModify($dest, $orig)) {
+            return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile());
+        }
+        $this->ui->outputData("Package ready at '$dest'");
+    // }}}
+    }
+
+    // }}}
+
+    function doRunScripts($command, $options, $params)
+    {
+        if (!isset($params[0])) {
+            return $this->raiseError('run-scripts expects 1 parameter: a package name');
+        }
+
+        $reg = &$this->config->getRegistry();
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($parsed)) {
+            return $this->raiseError($parsed);
+        }
+
+        $package = &$reg->getPackage($parsed['package'], $parsed['channel']);
+        if (!is_object($package)) {
+            return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry');
+        }
+
+        $package->setConfig($this->config);
+        $package->runPostinstallScripts();
+        $this->ui->outputData('Install scripts complete', $command);
+        return true;
+    }
+
+    /**
+     * Given a list of packages, filter out those ones that are already up to date
+     *
+     * @param $packages: packages, in parsed array format !
+     * @return list of packages that can be upgraded
+     */
+    function _filterUptodatePackages($packages, $command)
+    {
+        $reg = &$this->config->getRegistry();
+        $latestReleases = array();
+
+        $ret = array();
+        foreach ($packages as $package) {
+            if (isset($package['group'])) {
+                $ret[] = $package;
+                continue;
+            }
+
+            $channel = $package['channel'];
+            $name    = $package['package'];
+            if (!$reg->packageExists($name, $channel)) {
+                $ret[] = $package;
+                continue;
+            }
+
+            if (!isset($latestReleases[$channel])) {
+                // fill in cache for this channel
+                $chan = &$reg->getChannel($channel);
+                if (PEAR::isError($chan)) {
+                    return $this->raiseError($chan);
+                }
+
+                $base2 = false;
+                $preferred_mirror = $this->config->get('preferred_mirror', null, $channel);
+                if ($chan->supportsREST($preferred_mirror) &&
+                    (
+                       //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) ||
+                       ($base  = $chan->getBaseURL('REST1.0', $preferred_mirror))
+                    )
+                ) {
+                    $dorest = true;
+                }
+
+                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                if (!isset($package['state'])) {
+                    $state = $this->config->get('preferred_state', null, $channel);
+                } else {
+                    $state = $package['state'];
+                }
+
+                if ($dorest) {
+                    if ($base2) {
+                        $rest = &$this->config->getREST('1.4', array());
+                        $base = $base2;
+                    } else {
+                        $rest = &$this->config->getREST('1.0', array());
+                    }
+
+                    $installed = array_flip($reg->listPackages($channel));
+                    $latest    = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg);
+                }
+
+                PEAR::staticPopErrorHandling();
+                if (PEAR::isError($latest)) {
+                    $this->ui->outputData('Error getting channel info from ' . $channel .
+                        ': ' . $latest->getMessage());
+                    continue;
+                }
+
+                $latestReleases[$channel] = array_change_key_case($latest);
+            }
+
+            // check package for latest release
+            $name_lower = strtolower($name);
+            if (isset($latestReleases[$channel][$name_lower])) {
+                // if not set, up to date
+                $inst_version    = $reg->packageInfo($name, 'version', $channel);
+                $channel_version = $latestReleases[$channel][$name_lower]['version'];
+                if (version_compare($channel_version, $inst_version, 'le')) {
+                    // installed version is up-to-date
+                    continue;
+                }
+
+                // maintain BC
+                if ($command == 'upgrade-all') {
+                    $this->ui->outputData(array('data' => 'Will upgrade ' .
+                        $reg->parsedPackageNameToString($package)), $command);
+                }
+                $ret[] = $package;
+            }
+        }
+
+        return $ret;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Install.xml b/lib/php/PEAR/Command/Install.xml
new file mode 100644
index 00000000..1b1e933c
--- /dev/null
+++ b/lib/php/PEAR/Command/Install.xml
@@ -0,0 +1,276 @@
+<commands version="1.0">
+ <install>
+  <summary>Install Package</summary>
+  <function>doInstall</function>
+  <shortcut>i</shortcut>
+  <options>
+   <force>
+    <shortopt>f</shortopt>
+    <doc>will overwrite newer installed packages</doc>
+   </force>
+   <loose>
+    <shortopt>l</shortopt>
+    <doc>do not check for recommended dependency version</doc>
+   </loose>
+   <nodeps>
+    <shortopt>n</shortopt>
+    <doc>ignore dependencies, install anyway</doc>
+   </nodeps>
+   <register-only>
+    <shortopt>r</shortopt>
+    <doc>do not install files, only register the package as installed</doc>
+   </register-only>
+   <soft>
+    <shortopt>s</shortopt>
+    <doc>soft install, fail silently, or upgrade if already installed</doc>
+   </soft>
+   <nobuild>
+    <shortopt>B</shortopt>
+    <doc>don&#039;t build C extensions</doc>
+   </nobuild>
+   <nocompress>
+    <shortopt>Z</shortopt>
+    <doc>request uncompressed files when downloading</doc>
+   </nocompress>
+   <installroot>
+    <shortopt>R</shortopt>
+    <doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT), use packagingroot for RPM</doc>
+    <arg>DIR</arg>
+   </installroot>
+   <packagingroot>
+    <shortopt>P</shortopt>
+    <doc>root directory used when packaging files, like RPM packaging</doc>
+    <arg>DIR</arg>
+   </packagingroot>
+   <ignore-errors>
+    <shortopt></shortopt>
+    <doc>force install even if there were errors</doc>
+   </ignore-errors>
+   <alldeps>
+    <shortopt>a</shortopt>
+    <doc>install all required and optional dependencies</doc>
+   </alldeps>
+   <onlyreqdeps>
+    <shortopt>o</shortopt>
+    <doc>install all required dependencies</doc>
+   </onlyreqdeps>
+   <offline>
+    <shortopt>O</shortopt>
+    <doc>do not attempt to download any urls or contact channels</doc>
+   </offline>
+   <pretend>
+    <shortopt>p</shortopt>
+    <doc>Only list the packages that would be downloaded</doc>
+   </pretend>
+  </options>
+  <doc>[channel/]&lt;package&gt; ...
+Installs one or more PEAR packages.  You can specify a package to
+install in four ways:
+
+&quot;Package-1.0.tgz&quot; : installs from a local file
+
+&quot;http://example.com/Package-1.0.tgz&quot; : installs from
+anywhere on the net.
+
+&quot;package.xml&quot; : installs the package described in
+package.xml.  Useful for testing, or for wrapping a PEAR package in
+another package manager such as RPM.
+
+&quot;Package[-version/state][.tar]&quot; : queries your default channel&#039;s server
+({config master_server}) and downloads the newest package with
+the preferred quality/state ({config preferred_state}).
+
+To retrieve Package version 1.1, use &quot;Package-1.1,&quot; to retrieve
+Package state beta, use &quot;Package-beta.&quot;  To retrieve an uncompressed
+file, append .tar (make sure there is no file by the same name first)
+
+To download a package from another channel, prefix with the channel name like
+&quot;channel/Package&quot;
+
+More than one package may be specified at once.  It is ok to mix these
+four ways of specifying packages.
+</doc>
+ </install>
+ <upgrade>
+  <summary>Upgrade Package</summary>
+  <function>doInstall</function>
+  <shortcut>up</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>upgrade packages from a specific channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+   <force>
+    <shortopt>f</shortopt>
+    <doc>overwrite newer installed packages</doc>
+   </force>
+   <loose>
+    <shortopt>l</shortopt>
+    <doc>do not check for recommended dependency version</doc>
+   </loose>
+   <nodeps>
+    <shortopt>n</shortopt>
+    <doc>ignore dependencies, upgrade anyway</doc>
+   </nodeps>
+   <register-only>
+    <shortopt>r</shortopt>
+    <doc>do not install files, only register the package as upgraded</doc>
+   </register-only>
+   <nobuild>
+    <shortopt>B</shortopt>
+    <doc>don&#039;t build C extensions</doc>
+   </nobuild>
+   <nocompress>
+    <shortopt>Z</shortopt>
+    <doc>request uncompressed files when downloading</doc>
+   </nocompress>
+   <installroot>
+    <shortopt>R</shortopt>
+    <doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT)</doc>
+    <arg>DIR</arg>
+   </installroot>
+   <ignore-errors>
+    <shortopt></shortopt>
+    <doc>force install even if there were errors</doc>
+   </ignore-errors>
+   <alldeps>
+    <shortopt>a</shortopt>
+    <doc>install all required and optional dependencies</doc>
+   </alldeps>
+   <onlyreqdeps>
+    <shortopt>o</shortopt>
+    <doc>install all required dependencies</doc>
+   </onlyreqdeps>
+   <offline>
+    <shortopt>O</shortopt>
+    <doc>do not attempt to download any urls or contact channels</doc>
+   </offline>
+   <pretend>
+    <shortopt>p</shortopt>
+    <doc>Only list the packages that would be downloaded</doc>
+   </pretend>
+  </options>
+  <doc>&lt;package&gt; ...
+Upgrades one or more PEAR packages.  See documentation for the
+&quot;install&quot; command for ways to specify a package.
+
+When upgrading, your package will be updated if the provided new
+package has a higher version number (use the -f option if you need to
+upgrade anyway).
+
+More than one package may be specified at once.
+</doc>
+ </upgrade>
+ <upgrade-all>
+  <summary>Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]</summary>
+  <function>doUpgradeAll</function>
+  <shortcut>ua</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>upgrade packages from a specific channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+   <nodeps>
+    <shortopt>n</shortopt>
+    <doc>ignore dependencies, upgrade anyway</doc>
+   </nodeps>
+   <register-only>
+    <shortopt>r</shortopt>
+    <doc>do not install files, only register the package as upgraded</doc>
+   </register-only>
+   <nobuild>
+    <shortopt>B</shortopt>
+    <doc>don&#039;t build C extensions</doc>
+   </nobuild>
+   <nocompress>
+    <shortopt>Z</shortopt>
+    <doc>request uncompressed files when downloading</doc>
+   </nocompress>
+   <installroot>
+    <shortopt>R</shortopt>
+    <doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT), use packagingroot for RPM</doc>
+    <arg>DIR</arg>
+   </installroot>
+   <ignore-errors>
+    <shortopt></shortopt>
+    <doc>force install even if there were errors</doc>
+   </ignore-errors>
+   <loose>
+    <shortopt></shortopt>
+    <doc>do not check for recommended dependency version</doc>
+   </loose>
+  </options>
+  <doc>
+WARNING: This function is deprecated in favor of using the upgrade command with no params
+
+Upgrades all packages that have a newer release available.  Upgrades are
+done only if there is a release available of the state specified in
+&quot;preferred_state&quot; (currently {config preferred_state}), or a state considered
+more stable.
+</doc>
+ </upgrade-all>
+ <uninstall>
+  <summary>Un-install Package</summary>
+  <function>doUninstall</function>
+  <shortcut>un</shortcut>
+  <options>
+   <nodeps>
+    <shortopt>n</shortopt>
+    <doc>ignore dependencies, uninstall anyway</doc>
+   </nodeps>
+   <register-only>
+    <shortopt>r</shortopt>
+    <doc>do not remove files, only register the packages as not installed</doc>
+   </register-only>
+   <installroot>
+    <shortopt>R</shortopt>
+    <doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT)</doc>
+    <arg>DIR</arg>
+   </installroot>
+   <ignore-errors>
+    <shortopt></shortopt>
+    <doc>force install even if there were errors</doc>
+   </ignore-errors>
+   <offline>
+    <shortopt>O</shortopt>
+    <doc>do not attempt to uninstall remotely</doc>
+   </offline>
+  </options>
+  <doc>[channel/]&lt;package&gt; ...
+Uninstalls one or more PEAR packages.  More than one package may be
+specified at once.  Prefix with channel name to uninstall from a
+channel not in your default channel ({config default_channel})
+</doc>
+ </uninstall>
+ <bundle>
+  <summary>Unpacks a Pecl Package</summary>
+  <function>doBundle</function>
+  <shortcut>bun</shortcut>
+  <options>
+   <destination>
+    <shortopt>d</shortopt>
+    <doc>Optional destination directory for unpacking (defaults to current path or &quot;ext&quot; if exists)</doc>
+    <arg>DIR</arg>
+   </destination>
+   <force>
+    <shortopt>f</shortopt>
+    <doc>Force the unpacking even if there were errors in the package</doc>
+   </force>
+  </options>
+  <doc>&lt;package&gt;
+Unpacks a Pecl Package into the selected location. It will download the
+package if needed.
+</doc>
+ </bundle>
+ <run-scripts>
+  <summary>Run Post-Install Scripts bundled with a package</summary>
+  <function>doRunScripts</function>
+  <shortcut>rs</shortcut>
+  <options />
+  <doc>&lt;package&gt;
+Run post-installation scripts in package &lt;package&gt;, if any exist.
+</doc>
+ </run-scripts>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Mirror.php b/lib/php/PEAR/Command/Mirror.php
new file mode 100644
index 00000000..10140b88
--- /dev/null
+++ b/lib/php/PEAR/Command/Mirror.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ * PEAR_Command_Mirror (download-all command)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Alexander Merz <alexmerz@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Mirror.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.2.0
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+
+/**
+ * PEAR commands for providing file mirrors
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Alexander Merz <alexmerz@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.2.0
+ */
+class PEAR_Command_Mirror extends PEAR_Command_Common
+{
+    var $commands = array(
+        'download-all' => array(
+            'summary' => 'Downloads each available package from the default channel',
+            'function' => 'doDownloadAll',
+            'shortcut' => 'da',
+            'options' => array(
+                'channel' =>
+                    array(
+                    'shortopt' => 'c',
+                    'doc' => 'specify a channel other than the default channel',
+                    'arg' => 'CHAN',
+                    ),
+                ),
+            'doc' => '
+Requests a list of available packages from the default channel ({config default_channel})
+and downloads them to current working directory.  Note: only
+packages within preferred_state ({config preferred_state}) will be downloaded'
+            ),
+        );
+
+    /**
+     * PEAR_Command_Mirror constructor.
+     *
+     * @access public
+     * @param object PEAR_Frontend a reference to an frontend
+     * @param object PEAR_Config a reference to the configuration data
+     */
+    function PEAR_Command_Mirror(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    /**
+     * For unit-testing
+     */
+    function &factory($a)
+    {
+        $a = &PEAR_Command::factory($a, $this->config);
+        return $a;
+    }
+
+    /**
+    * retrieves a list of avaible Packages from master server
+    * and downloads them
+    *
+    * @access public
+    * @param string $command the command
+    * @param array $options the command options before the command
+    * @param array $params the stuff after the command name
+    * @return bool true if succesful
+    * @throw PEAR_Error
+    */
+    function doDownloadAll($command, $options, $params)
+    {
+        $savechannel = $this->config->get('default_channel');
+        $reg = &$this->config->getRegistry();
+        $channel = isset($options['channel']) ? $options['channel'] :
+            $this->config->get('default_channel');
+        if (!$reg->channelExists($channel)) {
+            $this->config->set('default_channel', $savechannel);
+            return $this->raiseError('Channel "' . $channel . '" does not exist');
+        }
+        $this->config->set('default_channel', $channel);
+
+        $this->ui->outputData('Using Channel ' . $this->config->get('default_channel'));
+        $chan = $reg->getChannel($channel);
+        if (PEAR::isError($chan)) {
+            return $this->raiseError($chan);
+        }
+
+        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
+              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
+            $rest = &$this->config->getREST('1.0', array());
+            $remoteInfo = array_flip($rest->listPackages($base, $channel));
+        }
+
+        if (PEAR::isError($remoteInfo)) {
+            return $remoteInfo;
+        }
+
+        $cmd = &$this->factory("download");
+        if (PEAR::isError($cmd)) {
+            return $cmd;
+        }
+
+        $this->ui->outputData('Using Preferred State of ' .
+            $this->config->get('preferred_state'));
+        $this->ui->outputData('Gathering release information, please wait...');
+
+        /**
+         * Error handling not necessary, because already done by
+         * the download command
+         */
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $err = $cmd->run('download', array('downloadonly' => true), array_keys($remoteInfo));
+        PEAR::staticPopErrorHandling();
+        $this->config->set('default_channel', $savechannel);
+        if (PEAR::isError($err)) {
+            $this->ui->outputData($err->getMessage());
+        }
+
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Mirror.xml b/lib/php/PEAR/Command/Mirror.xml
new file mode 100644
index 00000000..fe8be9d0
--- /dev/null
+++ b/lib/php/PEAR/Command/Mirror.xml
@@ -0,0 +1,18 @@
+<commands version="1.0">
+ <download-all>
+  <summary>Downloads each available package from the default channel</summary>
+  <function>doDownloadAll</function>
+  <shortcut>da</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>specify a channel other than the default channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+  </options>
+  <doc>
+Requests a list of available packages from the default channel ({config default_channel})
+and downloads them to current working directory.  Note: only
+packages within preferred_state ({config preferred_state}) will be downloaded</doc>
+ </download-all>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Package.php b/lib/php/PEAR/Command/Package.php
new file mode 100644
index 00000000..483decc2
--- /dev/null
+++ b/lib/php/PEAR/Command/Package.php
@@ -0,0 +1,1108 @@
+<?php
+/**
+ * PEAR_Command_Package (package, package-validate, cvsdiff, cvstag, package-dependencies,
+ * sign, makerpm, convert commands)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Package.php 287559 2009-08-21 22:33:10Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+
+/**
+ * PEAR commands for login/logout
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+
+class PEAR_Command_Package extends PEAR_Command_Common
+{
+    var $commands = array(
+        'package' => array(
+            'summary' => 'Build Package',
+            'function' => 'doPackage',
+            'shortcut' => 'p',
+            'options' => array(
+                'nocompress' => array(
+                    'shortopt' => 'Z',
+                    'doc' => 'Do not gzip the package file'
+                    ),
+                'showname' => array(
+                    'shortopt' => 'n',
+                    'doc' => 'Print the name of the packaged file.',
+                    ),
+                ),
+            'doc' => '[descfile] [descfile2]
+Creates a PEAR package from its description file (usually called
+package.xml).  If a second packagefile is passed in, then
+the packager will check to make sure that one is a package.xml
+version 1.0, and the other is a package.xml version 2.0.  The
+package.xml version 1.0 will be saved as "package.xml" in the archive,
+and the other as "package2.xml" in the archive"
+'
+            ),
+        'package-validate' => array(
+            'summary' => 'Validate Package Consistency',
+            'function' => 'doPackageValidate',
+            'shortcut' => 'pv',
+            'options' => array(),
+            'doc' => '
+',
+            ),
+        'cvsdiff' => array(
+            'summary' => 'Run a "cvs diff" for all files in a package',
+            'function' => 'doCvsDiff',
+            'shortcut' => 'cd',
+            'options' => array(
+                'quiet' => array(
+                    'shortopt' => 'q',
+                    'doc' => 'Be quiet',
+                    ),
+                'reallyquiet' => array(
+                    'shortopt' => 'Q',
+                    'doc' => 'Be really quiet',
+                    ),
+                'date' => array(
+                    'shortopt' => 'D',
+                    'doc' => 'Diff against revision of DATE',
+                    'arg' => 'DATE',
+                    ),
+                'release' => array(
+                    'shortopt' => 'R',
+                    'doc' => 'Diff against tag for package release REL',
+                    'arg' => 'REL',
+                    ),
+                'revision' => array(
+                    'shortopt' => 'r',
+                    'doc' => 'Diff against revision REV',
+                    'arg' => 'REV',
+                    ),
+                'context' => array(
+                    'shortopt' => 'c',
+                    'doc' => 'Generate context diff',
+                    ),
+                'unified' => array(
+                    'shortopt' => 'u',
+                    'doc' => 'Generate unified diff',
+                    ),
+                'ignore-case' => array(
+                    'shortopt' => 'i',
+                    'doc' => 'Ignore case, consider upper- and lower-case letters equivalent',
+                    ),
+                'ignore-whitespace' => array(
+                    'shortopt' => 'b',
+                    'doc' => 'Ignore changes in amount of white space',
+                    ),
+                'ignore-blank-lines' => array(
+                    'shortopt' => 'B',
+                    'doc' => 'Ignore changes that insert or delete blank lines',
+                    ),
+                'brief' => array(
+                    'doc' => 'Report only whether the files differ, no details',
+                    ),
+                'dry-run' => array(
+                    'shortopt' => 'n',
+                    'doc' => 'Don\'t do anything, just pretend',
+                    ),
+                ),
+            'doc' => '<package.xml>
+Compares all the files in a package.  Without any options, this
+command will compare the current code with the last checked-in code.
+Using the -r or -R option you may compare the current code with that
+of a specific release.
+',
+            ),
+         'svntag' => array(
+             'summary' => 'Set SVN Release Tag',
+             'function' => 'doSvnTag',
+             'shortcut' => 'sv',
+             'options' => array(
+                 'quiet' => array(
+                     'shortopt' => 'q',
+                     'doc' => 'Be quiet',
+                     ),
+                 'slide' => array(
+                     'shortopt' => 'F',
+                     'doc' => 'Move (slide) tag if it exists',
+                     ),
+                 'delete' => array(
+                     'shortopt' => 'd',
+                     'doc' => 'Remove tag',
+                     ),
+                 'dry-run' => array(
+                     'shortopt' => 'n',
+                     'doc' => 'Don\'t do anything, just pretend',
+                     ),
+                 ),
+             'doc' => '<package.xml> [files...]
+ Sets a SVN tag on all files in a package.  Use this command after you have
+ packaged a distribution tarball with the "package" command to tag what
+ revisions of what files were in that release.  If need to fix something
+ after running cvstag once, but before the tarball is released to the public,
+ use the "slide" option to move the release tag.
+
+ to include files (such as a second package.xml, or tests not included in the
+ release), pass them as additional parameters.
+ ',
+             ),
+        'cvstag' => array(
+            'summary' => 'Set CVS Release Tag',
+            'function' => 'doCvsTag',
+            'shortcut' => 'ct',
+            'options' => array(
+                'quiet' => array(
+                    'shortopt' => 'q',
+                    'doc' => 'Be quiet',
+                    ),
+                'reallyquiet' => array(
+                    'shortopt' => 'Q',
+                    'doc' => 'Be really quiet',
+                    ),
+                'slide' => array(
+                    'shortopt' => 'F',
+                    'doc' => 'Move (slide) tag if it exists',
+                    ),
+                'delete' => array(
+                    'shortopt' => 'd',
+                    'doc' => 'Remove tag',
+                    ),
+                'dry-run' => array(
+                    'shortopt' => 'n',
+                    'doc' => 'Don\'t do anything, just pretend',
+                    ),
+                ),
+            'doc' => '<package.xml> [files...]
+Sets a CVS tag on all files in a package.  Use this command after you have
+packaged a distribution tarball with the "package" command to tag what
+revisions of what files were in that release.  If need to fix something
+after running cvstag once, but before the tarball is released to the public,
+use the "slide" option to move the release tag.
+
+to include files (such as a second package.xml, or tests not included in the
+release), pass them as additional parameters.
+',
+            ),
+        'package-dependencies' => array(
+            'summary' => 'Show package dependencies',
+            'function' => 'doPackageDependencies',
+            'shortcut' => 'pd',
+            'options' => array(),
+            'doc' => '<package-file> or <package.xml> or <install-package-name>
+List all dependencies the package has.
+Can take a tgz / tar file, package.xml or a package name of an installed package.'
+            ),
+        'sign' => array(
+            'summary' => 'Sign a package distribution file',
+            'function' => 'doSign',
+            'shortcut' => 'si',
+            'options' => array(
+                'verbose' => array(
+                    'shortopt' => 'v',
+                    'doc' => 'Display GnuPG output',
+                    ),
+            ),
+            'doc' => '<package-file>
+Signs a package distribution (.tar or .tgz) file with GnuPG.',
+            ),
+        'makerpm' => array(
+            'summary' => 'Builds an RPM spec file from a PEAR package',
+            'function' => 'doMakeRPM',
+            'shortcut' => 'rpm',
+            'options' => array(
+                'spec-template' => array(
+                    'shortopt' => 't',
+                    'arg' => 'FILE',
+                    'doc' => 'Use FILE as RPM spec file template'
+                    ),
+                'rpm-pkgname' => array(
+                    'shortopt' => 'p',
+                    'arg' => 'FORMAT',
+                    'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced
+by the PEAR package name, defaults to "PEAR::%s".',
+                    ),
+                ),
+            'doc' => '<package-file>
+
+Creates an RPM .spec file for wrapping a PEAR package inside an RPM
+package.  Intended to be used from the SPECS directory, with the PEAR
+package tarball in the SOURCES directory:
+
+$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
+Wrote RPM spec file PEAR::Net_Geo-1.0.spec
+$ rpm -bb PEAR::Net_Socket-1.0.spec
+...
+Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
+',
+            ),
+        'convert' => array(
+            'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format',
+            'function' => 'doConvert',
+            'shortcut' => 'c2',
+            'options' => array(
+                'flat' => array(
+                    'shortopt' => 'f',
+                    'doc' => 'do not beautify the filelist.',
+                    ),
+                ),
+            'doc' => '[descfile] [descfile2]
+Converts a package.xml in 1.0 format into a package.xml
+in 2.0 format.  The new file will be named package2.xml by default,
+and package.xml will be used as the old file by default.
+This is not the most intelligent conversion, and should only be
+used for automated conversion or learning the format.
+'
+            ),
+        );
+
+    var $output;
+
+    /**
+     * PEAR_Command_Package constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Package(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    function _displayValidationResults($err, $warn, $strict = false)
+    {
+        foreach ($err as $e) {
+            $this->output .= "Error: $e\n";
+        }
+        foreach ($warn as $w) {
+            $this->output .= "Warning: $w\n";
+        }
+        $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n",
+                                       sizeof($err), sizeof($warn));
+        if ($strict && count($err) > 0) {
+            $this->output .= "Fix these errors and try again.";
+            return false;
+        }
+        return true;
+    }
+
+    function &getPackager()
+    {
+        if (!class_exists('PEAR_Packager')) {
+            require_once 'PEAR/Packager.php';
+        }
+        $a = &new PEAR_Packager;
+        return $a;
+    }
+
+    function &getPackageFile($config, $debug = false, $tmpdir = null)
+    {
+        if (!class_exists('PEAR_Common')) {
+            require_once 'PEAR/Common.php';
+        }
+        if (!class_exists('PEAR_PackageFile')) {
+            require_once 'PEAR/PackageFile.php';
+        }
+        $a = &new PEAR_PackageFile($config, $debug, $tmpdir);
+        $common = new PEAR_Common;
+        $common->ui = $this->ui;
+        $a->setLogger($common);
+        return $a;
+    }
+
+    function doPackage($command, $options, $params)
+    {
+        $this->output = '';
+        $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml';
+        $pkg2 = isset($params[1]) ? $params[1] : null;
+        if (!$pkg2 && !isset($params[0]) && file_exists('package2.xml')) {
+            $pkg2 = 'package2.xml';
+        }
+
+        $packager = &$this->getPackager();
+        $compress = empty($options['nocompress']) ? true : false;
+        $result   = $packager->package($pkginfofile, $compress, $pkg2);
+        if (PEAR::isError($result)) {
+            return $this->raiseError($result);
+        }
+
+        // Don't want output, only the package file name just created
+        if (isset($options['showname'])) {
+            $this->output = $result;
+        }
+
+        if ($this->output) {
+            $this->ui->outputData($this->output, $command);
+        }
+
+        return true;
+    }
+
+    function doPackageValidate($command, $options, $params)
+    {
+        $this->output = '';
+        if (count($params) < 1) {
+            $params[0] = 'package.xml';
+        }
+
+        $obj = &$this->getPackageFile($this->config, $this->_debug);
+        $obj->rawReturn();
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
+        if (PEAR::isError($info)) {
+            $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL);
+        } else {
+            $archive = $info->getArchiveFile();
+            $tar = &new Archive_Tar($archive);
+            $tar->extract(dirname($info->getPackageFile()));
+            $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR .
+                $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR .
+                basename($info->getPackageFile()));
+        }
+
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($info)) {
+            return $this->raiseError($info);
+        }
+
+        $valid = false;
+        if ($info->getPackagexmlVersion() == '2.0') {
+            if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) {
+                $info->flattenFileList();
+                $valid = $info->validate(PEAR_VALIDATE_PACKAGING);
+            }
+        } else {
+            $valid = $info->validate(PEAR_VALIDATE_PACKAGING);
+        }
+
+        $err = $warn = array();
+        if ($errors = $info->getValidationWarnings()) {
+            foreach ($errors as $error) {
+                if ($error['level'] == 'warning') {
+                    $warn[] = $error['message'];
+                } else {
+                    $err[] = $error['message'];
+                }
+            }
+        }
+
+        $this->_displayValidationResults($err, $warn);
+        $this->ui->outputData($this->output, $command);
+        return true;
+    }
+
+    function doSvnTag($command, $options, $params)
+    {
+        $this->output = '';
+        $_cmd = $command;
+        if (count($params) < 1) {
+            $help = $this->getHelp($command);
+            return $this->raiseError("$command: missing parameter: $help[0]");
+        }
+
+        $packageFile = realpath($params[0]);
+        $dir = dirname($packageFile);
+        $dir = substr($dir, strrpos($dir, '/') + 1);
+        $obj  = &$this->getPackageFile($this->config, $this->_debug);
+        $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL);
+        if (PEAR::isError($info)) {
+            return $this->raiseError($info);
+        }
+
+        $err = $warn = array();
+        if (!$info->validate()) {
+            foreach ($info->getValidationWarnings() as $error) {
+                if ($error['level'] == 'warning') {
+                    $warn[] = $error['message'];
+                } else {
+                    $err[] = $error['message'];
+                }
+            }
+        }
+
+        if (!$this->_displayValidationResults($err, $warn, true)) {
+            $this->ui->outputData($this->output, $command);
+            return $this->raiseError('SVN tag failed');
+        }
+
+        $version    = $info->getVersion();
+        $package    = $info->getName();
+        $svntag     = "$package-$version";
+
+        if (isset($options['delete'])) {
+            return $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options);
+        }
+
+        $path = $this->_svnFindPath($packageFile);
+
+        // Check if there are any modified files
+        $fp = popen('svn st --xml ' . dirname($packageFile), "r");
+        $out = '';
+        while ($line = fgets($fp, 1024)) {
+            $out .= rtrim($line)."\n";
+        }
+        pclose($fp);
+
+        if (!isset($options['quiet']) && strpos($out, 'item="modified"')) {
+            $params = array(array(
+                'name' => 'modified',
+                'type' => 'yesno',
+                'default' => 'no',
+                'prompt' => 'You have files in your SVN checkout (' . $path['from']  . ') that have been modified but not commited, do you still want to tag ' . $version . '?',
+            ));
+            $answers = $this->ui->confirmDialog($params);
+
+            if (!in_array($answers['modified'], array('y', 'yes', 'on', '1'))) {
+                return true;
+            }
+        }
+
+        if (isset($options['slide'])) {
+            $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options);
+        }
+
+        // Check if tag already exists
+        $releaseTag = $path['local']['base'] . 'tags/' . $svntag;
+        $existsCommand = 'svn ls ' . $path['base'] . 'tags/';
+
+        $fp = popen($existsCommand, "r");
+        $out = '';
+        while ($line = fgets($fp, 1024)) {
+            $out .= rtrim($line)."\n";
+        }
+        pclose($fp);
+
+        if (in_array($svntag . '/', explode("\n", $out))) {
+            $this->ui->outputData($this->output, $command);
+            return $this->raiseError('SVN tag ' . $svntag . ' for ' . $package . ' already exists.');
+        } else {
+            $makeCommand = 'svn mkdir ' . $releaseTag;
+            $this->output .= "+ $makeCommand\n";
+            if (empty($options['dry-run'])) {
+                // We need to create the tag dir.
+                $fp = popen($makeCommand, "r");
+                $out = '';
+                while ($line = fgets($fp, 1024)) {
+                    $out .= rtrim($line)."\n";
+                }
+                pclose($fp);
+                $this->output .= "$out\n";
+            }
+        }
+
+        $command = 'svn';
+        if (isset($options['quiet'])) {
+            $command .= ' -q';
+        }
+
+        $command .= ' copy --parents ';
+
+        $dir   = dirname($packageFile);
+        $dir   = substr($dir, strrpos($dir, '/') + 1);
+        $files = array_keys($info->getFilelist());
+        $commands = array();
+        foreach ($files as $file) {
+            if (!file_exists($file)) {
+                $file = $dir . DIRECTORY_SEPARATOR . $file;
+            }
+            $commands[] = $command . ' ' . escapeshellarg($file) . ' ' .
+                          escapeshellarg($releaseTag . DIRECTORY_SEPARATOR . $file);
+        }
+
+        $this->output .= implode("\n", $commands) . "\n";
+        if (empty($options['dry-run'])) {
+            foreach ($commands as $command) {
+                $fp = popen($command, "r");
+                while ($line = fgets($fp, 1024)) {
+                    $this->output .= rtrim($line)."\n";
+                }
+                pclose($fp);
+            }
+        }
+
+        $command = 'svn ci -m "Tagging the ' . $version  . ' release" ' . $releaseTag . "\n";
+        $this->output .= "+ $command\n";
+        if (empty($options['dry-run'])) {
+            $fp = popen($command, "r");
+            while ($line = fgets($fp, 1024)) {
+                $this->output .= rtrim($line)."\n";
+            }
+            pclose($fp);
+        }
+
+        $this->ui->outputData($this->output, $_cmd);
+        return true;
+    }
+
+    function _svnFindPath($file)
+    {
+        $xml = '';
+        $command = "svn info --xml $file";
+        $fp = popen($command, "r");
+        while ($line = fgets($fp, 1024)) {
+            $xml .= rtrim($line)."\n";
+        }
+        pclose($fp);
+        $url_tag = strpos($xml, '<url>');
+        $url = substr($xml, $url_tag + 5, strpos($xml, '</url>', $url_tag + 5) - ($url_tag + 5));
+
+        $path = array();
+        $path['from'] = substr($url, 0, strrpos($url, '/'));
+        $path['base'] = substr($path['from'], 0, strrpos($path['from'], '/') + 1);
+
+        // Figure out the local paths
+        $pos = strpos($file, '/trunk/');
+        if ($pos === false) {
+            $pos = strpos($file, '/branches/');
+        }
+        $path['local']['base'] = substr($file, 0, $pos + 1);
+
+        return $path;
+    }
+
+    function _svnRemoveTag($version, $package, $tag, $packageFile, $options)
+    {
+        $command = 'svn';
+
+        if (isset($options['quiet'])) {
+            $command .= ' -q';
+        }
+
+        $command .= ' remove';
+        $command .= ' -m "Removing tag for the ' . $version  . ' release."';
+
+        $path = $this->_svnFindPath($packageFile);
+        $command .= ' ' . $path['base'] . 'tags/' . $tag;
+
+
+        if ($this->config->get('verbose') > 1) {
+            $this->output .= "+ $command\n";
+        }
+
+        $this->output .= "+ $command\n";
+        if (empty($options['dry-run'])) {
+            $fp = popen($command, "r");
+            while ($line = fgets($fp, 1024)) {
+                $this->output .= rtrim($line)."\n";
+            }
+            pclose($fp);
+        }
+
+        $this->ui->outputData($this->output, $command);
+        return true;
+    }
+
+    function doCvsTag($command, $options, $params)
+    {
+        $this->output = '';
+        $_cmd = $command;
+        if (count($params) < 1) {
+            $help = $this->getHelp($command);
+            return $this->raiseError("$command: missing parameter: $help[0]");
+        }
+
+        $packageFile = realpath($params[0]);
+        $obj  = &$this->getPackageFile($this->config, $this->_debug);
+        $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL);
+        if (PEAR::isError($info)) {
+            return $this->raiseError($info);
+        }
+
+        $err = $warn = array();
+        if (!$info->validate()) {
+            foreach ($info->getValidationWarnings() as $error) {
+                if ($error['level'] == 'warning') {
+                    $warn[] = $error['message'];
+                } else {
+                    $err[] = $error['message'];
+                }
+            }
+        }
+
+        if (!$this->_displayValidationResults($err, $warn, true)) {
+            $this->ui->outputData($this->output, $command);
+            return $this->raiseError('CVS tag failed');
+        }
+
+        $version    = $info->getVersion();
+        $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version);
+        $cvstag     = "RELEASE_$cvsversion";
+        $files      = array_keys($info->getFilelist());
+        $command = 'cvs';
+        if (isset($options['quiet'])) {
+            $command .= ' -q';
+        }
+
+        if (isset($options['reallyquiet'])) {
+            $command .= ' -Q';
+        }
+
+        $command .= ' tag';
+        if (isset($options['slide'])) {
+            $command .= ' -F';
+        }
+
+        if (isset($options['delete'])) {
+            $command .= ' -d';
+        }
+
+        $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]);
+        array_shift($params);
+        if (count($params)) {
+            // add in additional files to be tagged
+            $files = array_merge($files, $params);
+        }
+
+        $dir = dirname($packageFile);
+        $dir = substr($dir, strrpos($dir, '/') + 1);
+        foreach ($files as $file) {
+            if (!file_exists($file)) {
+                $file = $dir . DIRECTORY_SEPARATOR . $file;
+            }
+            $command .= ' ' . escapeshellarg($file);
+        }
+
+        if ($this->config->get('verbose') > 1) {
+            $this->output .= "+ $command\n";
+        }
+
+        $this->output .= "+ $command\n";
+        if (empty($options['dry-run'])) {
+            $fp = popen($command, "r");
+            while ($line = fgets($fp, 1024)) {
+                $this->output .= rtrim($line)."\n";
+            }
+            pclose($fp);
+        }
+
+        $this->ui->outputData($this->output, $_cmd);
+        return true;
+    }
+
+    function doCvsDiff($command, $options, $params)
+    {
+        $this->output = '';
+        if (sizeof($params) < 1) {
+            $help = $this->getHelp($command);
+            return $this->raiseError("$command: missing parameter: $help[0]");
+        }
+
+        $file = realpath($params[0]);
+        $obj  = &$this->getPackageFile($this->config, $this->_debug);
+        $info = $obj->fromAnyFile($file, PEAR_VALIDATE_NORMAL);
+        if (PEAR::isError($info)) {
+            return $this->raiseError($info);
+        }
+
+        $err = $warn = array();
+        if (!$info->validate()) {
+            foreach ($info->getValidationWarnings() as $error) {
+                if ($error['level'] == 'warning') {
+                    $warn[] = $error['message'];
+                } else {
+                    $err[] = $error['message'];
+                }
+            }
+        }
+
+        if (!$this->_displayValidationResults($err, $warn, true)) {
+            $this->ui->outputData($this->output, $command);
+            return $this->raiseError('CVS diff failed');
+        }
+
+        $info1 = $info->getFilelist();
+        $files = $info1;
+        $cmd = "cvs";
+        if (isset($options['quiet'])) {
+            $cmd .= ' -q';
+            unset($options['quiet']);
+        }
+
+        if (isset($options['reallyquiet'])) {
+            $cmd .= ' -Q';
+            unset($options['reallyquiet']);
+        }
+
+        if (isset($options['release'])) {
+            $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']);
+            $cvstag = "RELEASE_$cvsversion";
+            $options['revision'] = $cvstag;
+            unset($options['release']);
+        }
+
+        $execute = true;
+        if (isset($options['dry-run'])) {
+            $execute = false;
+            unset($options['dry-run']);
+        }
+
+        $cmd .= ' diff';
+        // the rest of the options are passed right on to "cvs diff"
+        foreach ($options as $option => $optarg) {
+            $arg = $short = false;
+            if (isset($this->commands[$command]['options'][$option])) {
+                $arg = $this->commands[$command]['options'][$option]['arg'];
+                $short = $this->commands[$command]['options'][$option]['shortopt'];
+            }
+            $cmd .= $short ? " -$short" : " --$option";
+            if ($arg && $optarg) {
+                $cmd .= ($short ? '' : '=') . escapeshellarg($optarg);
+            }
+        }
+
+        foreach ($files as $file) {
+            $cmd .= ' ' . escapeshellarg($file['name']);
+        }
+
+        if ($this->config->get('verbose') > 1) {
+            $this->output .= "+ $cmd\n";
+        }
+
+        if ($execute) {
+            $fp = popen($cmd, "r");
+            while ($line = fgets($fp, 1024)) {
+                $this->output .= rtrim($line)."\n";
+            }
+            pclose($fp);
+        }
+
+        $this->ui->outputData($this->output, $command);
+        return true;
+    }
+
+    function doPackageDependencies($command, $options, $params)
+    {
+        // $params[0] -> the PEAR package to list its information
+        if (count($params) !== 1) {
+            return $this->raiseError("bad parameter(s), try \"help $command\"");
+        }
+
+        $obj = &$this->getPackageFile($this->config, $this->_debug);
+        if (is_file($params[0]) || strpos($params[0], '.xml') > 0) {
+           $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
+        } else {
+            $reg  = $this->config->getRegistry();
+            $info = $obj->fromArray($reg->packageInfo($params[0]));
+        }
+
+        if (PEAR::isError($info)) {
+            return $this->raiseError($info);
+        }
+
+        $deps = $info->getDeps();
+        if (is_array($deps)) {
+            if ($info->getPackagexmlVersion() == '1.0') {
+                $data = array(
+                    'caption' => 'Dependencies for pear/' . $info->getPackage(),
+                    'border' => true,
+                    'headline' => array("Required?", "Type", "Name", "Relation", "Version"),
+                    );
+
+                foreach ($deps as $d) {
+                    if (isset($d['optional'])) {
+                        if ($d['optional'] == 'yes') {
+                            $req = 'No';
+                        } else {
+                            $req = 'Yes';
+                        }
+                    } else {
+                        $req = 'Yes';
+                    }
+
+                    if (isset($this->_deps_rel_trans[$d['rel']])) {
+                        $rel = $this->_deps_rel_trans[$d['rel']];
+                    } else {
+                        $rel = $d['rel'];
+                    }
+
+                    if (isset($this->_deps_type_trans[$d['type']])) {
+                        $type = ucfirst($this->_deps_type_trans[$d['type']]);
+                    } else {
+                        $type = $d['type'];
+                    }
+
+                    if (isset($d['name'])) {
+                        $name = $d['name'];
+                    } else {
+                        $name = '';
+                    }
+
+                    if (isset($d['version'])) {
+                        $version = $d['version'];
+                    } else {
+                        $version = '';
+                    }
+
+                    $data['data'][] = array($req, $type, $name, $rel, $version);
+                }
+            } else { // package.xml 2.0 dependencies display
+                require_once 'PEAR/Dependency2.php';
+                $deps = $info->getDependencies();
+                $reg = &$this->config->getRegistry();
+                if (is_array($deps)) {
+                    $d = new PEAR_Dependency2($this->config, array(), '');
+                    $data = array(
+                        'caption' => 'Dependencies for ' . $info->getPackage(),
+                        'border' => true,
+                        'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'),
+                        );
+                    foreach ($deps as $type => $subd) {
+                        $req = ($type == 'required') ? 'Yes' : 'No';
+                        if ($type == 'group') {
+                            $group = $subd['attribs']['name'];
+                        } else {
+                            $group = '';
+                        }
+
+                        if (!isset($subd[0])) {
+                            $subd = array($subd);
+                        }
+
+                        foreach ($subd as $groupa) {
+                            foreach ($groupa as $deptype => $depinfo) {
+                                if ($deptype == 'attribs') {
+                                    continue;
+                                }
+
+                                if ($deptype == 'pearinstaller') {
+                                    $deptype = 'pear Installer';
+                                }
+
+                                if (!isset($depinfo[0])) {
+                                    $depinfo = array($depinfo);
+                                }
+
+                                foreach ($depinfo as $inf) {
+                                    $name = '';
+                                    if (isset($inf['channel'])) {
+                                        $alias = $reg->channelAlias($inf['channel']);
+                                        if (!$alias) {
+                                            $alias = '(channel?) ' .$inf['channel'];
+                                        }
+                                        $name = $alias . '/';
+
+                                    }
+                                    if (isset($inf['name'])) {
+                                        $name .= $inf['name'];
+                                    } elseif (isset($inf['pattern'])) {
+                                        $name .= $inf['pattern'];
+                                    } else {
+                                        $name .= '';
+                                    }
+
+                                    if (isset($inf['uri'])) {
+                                        $name .= ' [' . $inf['uri'] .  ']';
+                                    }
+
+                                    if (isset($inf['conflicts'])) {
+                                        $ver = 'conflicts';
+                                    } else {
+                                        $ver = $d->_getExtraString($inf);
+                                    }
+
+                                    $data['data'][] = array($req, ucfirst($deptype), $name,
+                                        $ver, $group);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            $this->ui->outputData($data, $command);
+            return true;
+        }
+
+        // Fallback
+        $this->ui->outputData("This package does not have any dependencies.", $command);
+    }
+
+    function doSign($command, $options, $params)
+    {
+        // should move most of this code into PEAR_Packager
+        // so it'll be easy to implement "pear package --sign"
+        if (count($params) !== 1) {
+            return $this->raiseError("bad parameter(s), try \"help $command\"");
+        }
+
+        require_once 'System.php';
+        require_once 'Archive/Tar.php';
+
+        if (!file_exists($params[0])) {
+            return $this->raiseError("file does not exist: $params[0]");
+        }
+
+        $obj = $this->getPackageFile($this->config, $this->_debug);
+        $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
+        if (PEAR::isError($info)) {
+            return $this->raiseError($info);
+        }
+
+        $tar = new Archive_Tar($params[0]);
+        $tmpdir = System::mktemp('-d pearsign');
+        if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) {
+            return $this->raiseError("failed to extract tar file");
+        }
+
+        if (file_exists("$tmpdir/package.sig")) {
+            return $this->raiseError("package already signed");
+        }
+
+        $packagexml = 'package.xml';
+        if (file_exists("$tmpdir/package2.xml")) {
+            $packagexml = 'package2.xml';
+        }
+
+        if (file_exists("$tmpdir/package.sig")) {
+            unlink("$tmpdir/package.sig");
+        }
+
+        if (!file_exists("$tmpdir/$packagexml")) {
+            return $this->raiseError("Extracted file $tmpdir/$packagexml not found.");
+        }
+
+        $input = $this->ui->userDialog($command,
+                                       array('GnuPG Passphrase'),
+                                       array('password'));
+        if (!isset($input[0])) {
+            //use empty passphrase
+            $input[0] = '';
+        }
+
+        $devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null';
+        $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w");
+        if (!$gpg) {
+            return $this->raiseError("gpg command failed");
+        }
+
+        fwrite($gpg, "$input[0]\n");
+        if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) {
+            return $this->raiseError("gpg sign failed");
+        }
+
+        if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) {
+            return $this->raiseError('failed adding signature to file');
+        }
+
+        $this->ui->outputData("Package signed.", $command);
+        return true;
+    }
+
+    /**
+     * For unit testing purposes
+     */
+    function &getInstaller(&$ui)
+    {
+        if (!class_exists('PEAR_Installer')) {
+            require_once 'PEAR/Installer.php';
+        }
+        $a = &new PEAR_Installer($ui);
+        return $a;
+    }
+
+    /**
+     * For unit testing purposes
+     */
+    function &getCommandPackaging(&$ui, &$config)
+    {
+        if (!class_exists('PEAR_Command_Packaging')) {
+            if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) {
+                fclose($fp);
+                include_once 'PEAR/Command/Packaging.php';
+            }
+        }
+
+        if (class_exists('PEAR_Command_Packaging')) {
+            $a = &new PEAR_Command_Packaging($ui, $config);
+        } else {
+            $a = null;
+        }
+
+        return $a;
+    }
+
+    function doMakeRPM($command, $options, $params)
+    {
+
+        // Check to see if PEAR_Command_Packaging is installed, and
+        // transparently switch to use the "make-rpm-spec" command from it
+        // instead, if it does. Otherwise, continue to use the old version
+        // of "makerpm" supplied with this package (PEAR).
+        $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config);
+        if ($packaging_cmd !== null) {
+            $this->ui->outputData('PEAR_Command_Packaging is installed; using '.
+                'newer "make-rpm-spec" command instead');
+            return $packaging_cmd->run('make-rpm-spec', $options, $params);
+        }
+
+        $this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '.
+          'improved version is available via "pear make-rpm-spec", which '.
+          'is available by installing PEAR_Command_Packaging');
+        return true;
+    }
+
+    function doConvert($command, $options, $params)
+    {
+        $packagexml    = isset($params[0]) ? $params[0] : 'package.xml';
+        $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) .
+            DIRECTORY_SEPARATOR . 'package2.xml';
+        $pkg = &$this->getPackageFile($this->config, $this->_debug);
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($pf)) {
+            if (is_array($pf->getUserInfo())) {
+                foreach ($pf->getUserInfo() as $warning) {
+                    $this->ui->outputData($warning['message']);
+                }
+            }
+            return $this->raiseError($pf);
+        }
+
+        if (is_a($pf, 'PEAR_PackageFile_v2')) {
+            $this->ui->outputData($packagexml . ' is already a package.xml version 2.0');
+            return true;
+        }
+
+        $gen   = &$pf->getDefaultGenerator();
+        $newpf = &$gen->toV2();
+        $newpf->setPackagefile($newpackagexml);
+        $gen = &$newpf->getDefaultGenerator();
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL);
+        $saved = $gen->toPackageFile(dirname($newpackagexml), $state, basename($newpackagexml));
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($saved)) {
+            if (is_array($saved->getUserInfo())) {
+                foreach ($saved->getUserInfo() as $warning) {
+                    $this->ui->outputData($warning['message']);
+                }
+            }
+
+            $this->ui->outputData($saved->getMessage());
+            return true;
+        }
+
+        $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"');
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Package.xml b/lib/php/PEAR/Command/Package.xml
new file mode 100644
index 00000000..9f093ef6
--- /dev/null
+++ b/lib/php/PEAR/Command/Package.xml
@@ -0,0 +1,237 @@
+<commands version="1.0">
+ <package>
+  <summary>Build Package</summary>
+  <function>doPackage</function>
+  <shortcut>p</shortcut>
+  <options>
+   <nocompress>
+    <shortopt>Z</shortopt>
+    <doc>Do not gzip the package file</doc>
+   </nocompress>
+   <showname>
+    <shortopt>n</shortopt>
+    <doc>Print the name of the packaged file.</doc>
+   </showname>
+  </options>
+  <doc>[descfile] [descfile2]
+Creates a PEAR package from its description file (usually called
+package.xml).  If a second packagefile is passed in, then
+the packager will check to make sure that one is a package.xml
+version 1.0, and the other is a package.xml version 2.0.  The
+package.xml version 1.0 will be saved as &quot;package.xml&quot; in the archive,
+and the other as &quot;package2.xml&quot; in the archive&quot;
+</doc>
+ </package>
+ <package-validate>
+  <summary>Validate Package Consistency</summary>
+  <function>doPackageValidate</function>
+  <shortcut>pv</shortcut>
+  <options />
+  <doc>
+</doc>
+ </package-validate>
+ <cvsdiff>
+  <summary>Run a &quot;cvs diff&quot; for all files in a package</summary>
+  <function>doCvsDiff</function>
+  <shortcut>cd</shortcut>
+  <options>
+   <quiet>
+    <shortopt>q</shortopt>
+    <doc>Be quiet</doc>
+   </quiet>
+   <reallyquiet>
+    <shortopt>Q</shortopt>
+    <doc>Be really quiet</doc>
+   </reallyquiet>
+   <date>
+    <shortopt>D</shortopt>
+    <doc>Diff against revision of DATE</doc>
+    <arg>DATE</arg>
+   </date>
+   <release>
+    <shortopt>R</shortopt>
+    <doc>Diff against tag for package release REL</doc>
+    <arg>REL</arg>
+   </release>
+   <revision>
+    <shortopt>r</shortopt>
+    <doc>Diff against revision REV</doc>
+    <arg>REV</arg>
+   </revision>
+   <context>
+    <shortopt>c</shortopt>
+    <doc>Generate context diff</doc>
+   </context>
+   <unified>
+    <shortopt>u</shortopt>
+    <doc>Generate unified diff</doc>
+   </unified>
+   <ignore-case>
+    <shortopt>i</shortopt>
+    <doc>Ignore case, consider upper- and lower-case letters equivalent</doc>
+   </ignore-case>
+   <ignore-whitespace>
+    <shortopt>b</shortopt>
+    <doc>Ignore changes in amount of white space</doc>
+   </ignore-whitespace>
+   <ignore-blank-lines>
+    <shortopt>B</shortopt>
+    <doc>Ignore changes that insert or delete blank lines</doc>
+   </ignore-blank-lines>
+   <brief>
+    <shortopt></shortopt>
+    <doc>Report only whether the files differ, no details</doc>
+   </brief>
+   <dry-run>
+    <shortopt>n</shortopt>
+    <doc>Don&#039;t do anything, just pretend</doc>
+   </dry-run>
+  </options>
+  <doc>&lt;package.xml&gt;
+Compares all the files in a package.  Without any options, this
+command will compare the current code with the last checked-in code.
+Using the -r or -R option you may compare the current code with that
+of a specific release.
+</doc>
+ </cvsdiff>
+ <svntag>
+  <summary>Set SVN Release Tag</summary>
+  <function>doSvnTag</function>
+  <shortcut>sv</shortcut>
+  <options>
+   <quiet>
+    <shortopt>q</shortopt>
+    <doc>Be quiet</doc>
+   </quiet>
+   <slide>
+    <shortopt>F</shortopt>
+    <doc>Move (slide) tag if it exists</doc>
+   </slide>
+   <delete>
+    <shortopt>d</shortopt>
+    <doc>Remove tag</doc>
+   </delete>
+   <dry-run>
+    <shortopt>n</shortopt>
+    <doc>Don&#039;t do anything, just pretend</doc>
+   </dry-run>
+  </options>
+  <doc>&lt;package.xml&gt; [files...]
+ Sets a SVN tag on all files in a package.  Use this command after you have
+ packaged a distribution tarball with the &quot;package&quot; command to tag what
+ revisions of what files were in that release.  If need to fix something
+ after running cvstag once, but before the tarball is released to the public,
+ use the &quot;slide&quot; option to move the release tag.
+
+ to include files (such as a second package.xml, or tests not included in the
+ release), pass them as additional parameters.
+ </doc>
+ </svntag>
+ <cvstag>
+  <summary>Set CVS Release Tag</summary>
+  <function>doCvsTag</function>
+  <shortcut>ct</shortcut>
+  <options>
+   <quiet>
+    <shortopt>q</shortopt>
+    <doc>Be quiet</doc>
+   </quiet>
+   <reallyquiet>
+    <shortopt>Q</shortopt>
+    <doc>Be really quiet</doc>
+   </reallyquiet>
+   <slide>
+    <shortopt>F</shortopt>
+    <doc>Move (slide) tag if it exists</doc>
+   </slide>
+   <delete>
+    <shortopt>d</shortopt>
+    <doc>Remove tag</doc>
+   </delete>
+   <dry-run>
+    <shortopt>n</shortopt>
+    <doc>Don&#039;t do anything, just pretend</doc>
+   </dry-run>
+  </options>
+  <doc>&lt;package.xml&gt; [files...]
+Sets a CVS tag on all files in a package.  Use this command after you have
+packaged a distribution tarball with the &quot;package&quot; command to tag what
+revisions of what files were in that release.  If need to fix something
+after running cvstag once, but before the tarball is released to the public,
+use the &quot;slide&quot; option to move the release tag.
+
+to include files (such as a second package.xml, or tests not included in the
+release), pass them as additional parameters.
+</doc>
+ </cvstag>
+ <package-dependencies>
+  <summary>Show package dependencies</summary>
+  <function>doPackageDependencies</function>
+  <shortcut>pd</shortcut>
+  <options />
+  <doc>&lt;package-file&gt; or &lt;package.xml&gt; or &lt;install-package-name&gt;
+List all dependencies the package has.
+Can take a tgz / tar file, package.xml or a package name of an installed package.</doc>
+ </package-dependencies>
+ <sign>
+  <summary>Sign a package distribution file</summary>
+  <function>doSign</function>
+  <shortcut>si</shortcut>
+  <options>
+   <verbose>
+    <shortopt>v</shortopt>
+    <doc>Display GnuPG output</doc>
+   </verbose>
+  </options>
+  <doc>&lt;package-file&gt;
+Signs a package distribution (.tar or .tgz) file with GnuPG.</doc>
+ </sign>
+ <makerpm>
+  <summary>Builds an RPM spec file from a PEAR package</summary>
+  <function>doMakeRPM</function>
+  <shortcut>rpm</shortcut>
+  <options>
+   <spec-template>
+    <shortopt>t</shortopt>
+    <doc>Use FILE as RPM spec file template</doc>
+    <arg>FILE</arg>
+   </spec-template>
+   <rpm-pkgname>
+    <shortopt>p</shortopt>
+    <doc>Use FORMAT as format string for RPM package name, %s is replaced
+by the PEAR package name, defaults to &quot;PEAR::%s&quot;.</doc>
+    <arg>FORMAT</arg>
+   </rpm-pkgname>
+  </options>
+  <doc>&lt;package-file&gt;
+
+Creates an RPM .spec file for wrapping a PEAR package inside an RPM
+package.  Intended to be used from the SPECS directory, with the PEAR
+package tarball in the SOURCES directory:
+
+$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
+Wrote RPM spec file PEAR::Net_Geo-1.0.spec
+$ rpm -bb PEAR::Net_Socket-1.0.spec
+...
+Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
+</doc>
+ </makerpm>
+ <convert>
+  <summary>Convert a package.xml 1.0 to package.xml 2.0 format</summary>
+  <function>doConvert</function>
+  <shortcut>c2</shortcut>
+  <options>
+   <flat>
+    <shortopt>f</shortopt>
+    <doc>do not beautify the filelist.</doc>
+   </flat>
+  </options>
+  <doc>[descfile] [descfile2]
+Converts a package.xml in 1.0 format into a package.xml
+in 2.0 format.  The new file will be named package2.xml by default,
+and package.xml will be used as the old file by default.
+This is not the most intelligent conversion, and should only be
+used for automated conversion or learning the format.
+</doc>
+ </convert>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Pickle.php b/lib/php/PEAR/Command/Pickle.php
new file mode 100644
index 00000000..9cdb77b2
--- /dev/null
+++ b/lib/php/PEAR/Command/Pickle.php
@@ -0,0 +1,421 @@
+<?php
+/**
+ * PEAR_Command_Pickle (pickle command)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  2005-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Pickle.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+
+/**
+ * PEAR commands for login/logout
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  2005-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.1
+ */
+
+class PEAR_Command_Pickle extends PEAR_Command_Common
+{
+    var $commands = array(
+        'pickle' => array(
+            'summary' => 'Build PECL Package',
+            'function' => 'doPackage',
+            'shortcut' => 'pi',
+            'options' => array(
+                'nocompress' => array(
+                    'shortopt' => 'Z',
+                    'doc' => 'Do not gzip the package file'
+                    ),
+                'showname' => array(
+                    'shortopt' => 'n',
+                    'doc' => 'Print the name of the packaged file.',
+                    ),
+                ),
+            'doc' => '[descfile]
+Creates a PECL package from its package2.xml file.
+
+An automatic conversion will be made to a package.xml 1.0 and written out to
+disk in the current directory as "package.xml".  Note that
+only simple package.xml 2.0 will be converted.  package.xml 2.0 with:
+
+ - dependency types other than required/optional PECL package/ext/php/pearinstaller
+ - more than one extsrcrelease or zendextsrcrelease
+ - zendextbinrelease, extbinrelease, phprelease, or bundle release type
+ - dependency groups
+ - ignore tags in release filelist
+ - tasks other than replace
+ - custom roles
+
+will cause pickle to fail, and output an error message.  If your package2.xml
+uses any of these features, you are best off using PEAR_PackageFileManager to
+generate both package.xml.
+'
+            ),
+        );
+
+    /**
+     * PEAR_Command_Package constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Pickle(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    /**
+     * For unit-testing ease
+     *
+     * @return PEAR_Packager
+     */
+    function &getPackager()
+    {
+        if (!class_exists('PEAR_Packager')) {
+            require_once 'PEAR/Packager.php';
+        }
+
+        $a = &new PEAR_Packager;
+        return $a;
+    }
+
+    /**
+     * For unit-testing ease
+     *
+     * @param PEAR_Config $config
+     * @param bool $debug
+     * @param string|null $tmpdir
+     * @return PEAR_PackageFile
+     */
+    function &getPackageFile($config, $debug = false, $tmpdir = null)
+    {
+        if (!class_exists('PEAR_Common')) {
+            require_once 'PEAR/Common.php';
+        }
+
+        if (!class_exists('PEAR_PackageFile')) {
+            require_once 'PEAR/PackageFile.php';
+        }
+
+        $a = &new PEAR_PackageFile($config, $debug, $tmpdir);
+        $common = new PEAR_Common;
+        $common->ui = $this->ui;
+        $a->setLogger($common);
+        return $a;
+    }
+
+    function doPackage($command, $options, $params)
+    {
+        $this->output = '';
+        $pkginfofile = isset($params[0]) ? $params[0] : 'package2.xml';
+        $packager = &$this->getPackager();
+        if (PEAR::isError($err = $this->_convertPackage($pkginfofile))) {
+            return $err;
+        }
+
+        $compress = empty($options['nocompress']) ? true : false;
+        $result = $packager->package($pkginfofile, $compress, 'package.xml');
+        if (PEAR::isError($result)) {
+            return $this->raiseError($result);
+        }
+
+        // Don't want output, only the package file name just created
+        if (isset($options['showname'])) {
+            $this->ui->outputData($result, $command);
+        }
+
+        return true;
+    }
+
+    function _convertPackage($packagexml)
+    {
+        $pkg = &$this->getPackageFile($this->config);
+        $pf2 = &$pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
+        if (!is_a($pf2, 'PEAR_PackageFile_v2')) {
+            return $this->raiseError('Cannot process "' .
+                $packagexml . '", is not a package.xml 2.0');
+        }
+
+        require_once 'PEAR/PackageFile/v1.php';
+        $pf = new PEAR_PackageFile_v1;
+        $pf->setConfig($this->config);
+        if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') {
+            return $this->raiseError('Cannot safely convert "' . $packagexml .
+            '", is not an extension source package.  Using a PEAR_PackageFileManager-based ' .
+            'script is an option');
+        }
+
+        if (is_array($pf2->getUsesRole())) {
+            return $this->raiseError('Cannot safely convert "' . $packagexml .
+            '", contains custom roles.  Using a PEAR_PackageFileManager-based script or ' .
+            'the convert command is an option');
+        }
+
+        if (is_array($pf2->getUsesTask())) {
+            return $this->raiseError('Cannot safely convert "' . $packagexml .
+            '", contains custom tasks.  Using a PEAR_PackageFileManager-based script or ' .
+            'the convert command is an option');
+        }
+
+        $deps = $pf2->getDependencies();
+        if (isset($deps['group'])) {
+            return $this->raiseError('Cannot safely convert "' . $packagexml .
+            '", contains dependency groups.  Using a PEAR_PackageFileManager-based script ' .
+            'or the convert command is an option');
+        }
+
+        if (isset($deps['required']['subpackage']) ||
+              isset($deps['optional']['subpackage'])) {
+            return $this->raiseError('Cannot safely convert "' . $packagexml .
+            '", contains subpackage dependencies.  Using a PEAR_PackageFileManager-based  '.
+            'script is an option');
+        }
+
+        if (isset($deps['required']['os'])) {
+            return $this->raiseError('Cannot safely convert "' . $packagexml .
+            '", contains os dependencies.  Using a PEAR_PackageFileManager-based  '.
+            'script is an option');
+        }
+
+        if (isset($deps['required']['arch'])) {
+            return $this->raiseError('Cannot safely convert "' . $packagexml .
+            '", contains arch dependencies.  Using a PEAR_PackageFileManager-based  '.
+            'script is an option');
+        }
+
+        $pf->setPackage($pf2->getPackage());
+        $pf->setSummary($pf2->getSummary());
+        $pf->setDescription($pf2->getDescription());
+        foreach ($pf2->getMaintainers() as $maintainer) {
+            $pf->addMaintainer($maintainer['role'], $maintainer['handle'],
+                $maintainer['name'], $maintainer['email']);
+        }
+
+        $pf->setVersion($pf2->getVersion());
+        $pf->setDate($pf2->getDate());
+        $pf->setLicense($pf2->getLicense());
+        $pf->setState($pf2->getState());
+        $pf->setNotes($pf2->getNotes());
+        $pf->addPhpDep($deps['required']['php']['min'], 'ge');
+        if (isset($deps['required']['php']['max'])) {
+            $pf->addPhpDep($deps['required']['php']['max'], 'le');
+        }
+
+        if (isset($deps['required']['package'])) {
+            if (!isset($deps['required']['package'][0])) {
+                $deps['required']['package'] = array($deps['required']['package']);
+            }
+
+            foreach ($deps['required']['package'] as $dep) {
+                if (!isset($dep['channel'])) {
+                    return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
+                    ' contains uri-based dependency on a package.  Using a ' .
+                    'PEAR_PackageFileManager-based script is an option');
+                }
+
+                if ($dep['channel'] != 'pear.php.net'
+                    && $dep['channel'] != 'pecl.php.net'
+                    && $dep['channel'] != 'doc.php.net') {
+                    return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
+                    ' contains dependency on a non-standard channel package.  Using a ' .
+                    'PEAR_PackageFileManager-based script is an option');
+                }
+
+                if (isset($dep['conflicts'])) {
+                    return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
+                    ' contains conflicts dependency.  Using a ' .
+                    'PEAR_PackageFileManager-based script is an option');
+                }
+
+                if (isset($dep['exclude'])) {
+                    $this->ui->outputData('WARNING: exclude tags are ignored in conversion');
+                }
+
+                if (isset($dep['min'])) {
+                    $pf->addPackageDep($dep['name'], $dep['min'], 'ge');
+                }
+
+                if (isset($dep['max'])) {
+                    $pf->addPackageDep($dep['name'], $dep['max'], 'le');
+                }
+            }
+        }
+
+        if (isset($deps['required']['extension'])) {
+            if (!isset($deps['required']['extension'][0])) {
+                $deps['required']['extension'] = array($deps['required']['extension']);
+            }
+
+            foreach ($deps['required']['extension'] as $dep) {
+                if (isset($dep['conflicts'])) {
+                    return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
+                    ' contains conflicts dependency.  Using a ' .
+                    'PEAR_PackageFileManager-based script is an option');
+                }
+
+                if (isset($dep['exclude'])) {
+                    $this->ui->outputData('WARNING: exclude tags are ignored in conversion');
+                }
+
+                if (isset($dep['min'])) {
+                    $pf->addExtensionDep($dep['name'], $dep['min'], 'ge');
+                }
+
+                if (isset($dep['max'])) {
+                    $pf->addExtensionDep($dep['name'], $dep['max'], 'le');
+                }
+            }
+        }
+
+        if (isset($deps['optional']['package'])) {
+            if (!isset($deps['optional']['package'][0])) {
+                $deps['optional']['package'] = array($deps['optional']['package']);
+            }
+
+            foreach ($deps['optional']['package'] as $dep) {
+                if (!isset($dep['channel'])) {
+                    return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
+                    ' contains uri-based dependency on a package.  Using a ' .
+                    'PEAR_PackageFileManager-based script is an option');
+                }
+
+                if ($dep['channel'] != 'pear.php.net'
+                    && $dep['channel'] != 'pecl.php.net'
+                    && $dep['channel'] != 'doc.php.net') {
+                    return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
+                    ' contains dependency on a non-standard channel package.  Using a ' .
+                    'PEAR_PackageFileManager-based script is an option');
+                }
+
+                if (isset($dep['exclude'])) {
+                    $this->ui->outputData('WARNING: exclude tags are ignored in conversion');
+                }
+
+                if (isset($dep['min'])) {
+                    $pf->addPackageDep($dep['name'], $dep['min'], 'ge', 'yes');
+                }
+
+                if (isset($dep['max'])) {
+                    $pf->addPackageDep($dep['name'], $dep['max'], 'le', 'yes');
+                }
+            }
+        }
+
+        if (isset($deps['optional']['extension'])) {
+            if (!isset($deps['optional']['extension'][0])) {
+                $deps['optional']['extension'] = array($deps['optional']['extension']);
+            }
+
+            foreach ($deps['optional']['extension'] as $dep) {
+                if (isset($dep['exclude'])) {
+                    $this->ui->outputData('WARNING: exclude tags are ignored in conversion');
+                }
+
+                if (isset($dep['min'])) {
+                    $pf->addExtensionDep($dep['name'], $dep['min'], 'ge', 'yes');
+                }
+
+                if (isset($dep['max'])) {
+                    $pf->addExtensionDep($dep['name'], $dep['max'], 'le', 'yes');
+                }
+            }
+        }
+
+        $contents = $pf2->getContents();
+        $release  = $pf2->getReleases();
+        if (isset($releases[0])) {
+            return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
+            . 'multiple extsrcrelease/zendextsrcrelease tags.  Using a PEAR_PackageFileManager-based script ' .
+            'or the convert command is an option');
+        }
+
+        if ($configoptions = $pf2->getConfigureOptions()) {
+            foreach ($configoptions as $option) {
+                $default = isset($option['default']) ? $option['default'] : false;
+                $pf->addConfigureOption($option['name'], $option['prompt'], $default);
+            }
+        }
+
+        if (isset($release['filelist']['ignore'])) {
+            return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
+            . 'ignore tags.  Using a PEAR_PackageFileManager-based script or the convert' .
+            ' command is an option');
+        }
+
+        if (isset($release['filelist']['install']) &&
+              !isset($release['filelist']['install'][0])) {
+            $release['filelist']['install'] = array($release['filelist']['install']);
+        }
+
+        if (isset($contents['dir']['attribs']['baseinstalldir'])) {
+            $baseinstalldir = $contents['dir']['attribs']['baseinstalldir'];
+        } else {
+            $baseinstalldir = false;
+        }
+
+        if (!isset($contents['dir']['file'][0])) {
+            $contents['dir']['file'] = array($contents['dir']['file']);
+        }
+
+        foreach ($contents['dir']['file'] as $file) {
+            if ($baseinstalldir && !isset($file['attribs']['baseinstalldir'])) {
+                $file['attribs']['baseinstalldir'] = $baseinstalldir;
+            }
+
+            $processFile = $file;
+            unset($processFile['attribs']);
+            if (count($processFile)) {
+                foreach ($processFile as $name => $task) {
+                    if ($name != $pf2->getTasksNs() . ':replace') {
+                        return $this->raiseError('Cannot safely process "' . $packagexml .
+                        '" contains tasks other than replace.  Using a ' .
+                        'PEAR_PackageFileManager-based script is an option.');
+                    }
+                    $file['attribs']['replace'][] = $task;
+                }
+            }
+
+            if (!in_array($file['attribs']['role'], PEAR_Common::getFileRoles())) {
+                return $this->raiseError('Cannot safely convert "' . $packagexml .
+                '", contains custom roles.  Using a PEAR_PackageFileManager-based script ' .
+                'or the convert command is an option');
+            }
+
+            if (isset($release['filelist']['install'])) {
+                foreach ($release['filelist']['install'] as $installas) {
+                    if ($installas['attribs']['name'] == $file['attribs']['name']) {
+                        $file['attribs']['install-as'] = $installas['attribs']['as'];
+                    }
+                }
+            }
+
+            $pf->addFile('/', $file['attribs']['name'], $file['attribs']);
+        }
+
+        if ($pf2->getChangeLog()) {
+            $this->ui->outputData('WARNING: changelog is not translated to package.xml ' .
+                '1.0, use PEAR_PackageFileManager-based script if you need changelog-' .
+                'translation for package.xml 1.0');
+        }
+
+        $gen = &$pf->getDefaultGenerator();
+        $gen->toPackageFile('.');
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Pickle.xml b/lib/php/PEAR/Command/Pickle.xml
new file mode 100644
index 00000000..721ecea9
--- /dev/null
+++ b/lib/php/PEAR/Command/Pickle.xml
@@ -0,0 +1,36 @@
+<commands version="1.0">
+ <pickle>
+  <summary>Build PECL Package</summary>
+  <function>doPackage</function>
+  <shortcut>pi</shortcut>
+  <options>
+   <nocompress>
+    <shortopt>Z</shortopt>
+    <doc>Do not gzip the package file</doc>
+   </nocompress>
+   <showname>
+    <shortopt>n</shortopt>
+    <doc>Print the name of the packaged file.</doc>
+   </showname>
+  </options>
+  <doc>[descfile]
+Creates a PECL package from its package2.xml file.
+
+An automatic conversion will be made to a package.xml 1.0 and written out to
+disk in the current directory as &quot;package.xml&quot;.  Note that
+only simple package.xml 2.0 will be converted.  package.xml 2.0 with:
+
+ - dependency types other than required/optional PECL package/ext/php/pearinstaller
+ - more than one extsrcrelease or zendextsrcrelease
+ - zendextbinrelease, extbinrelease, phprelease, or bundle release type
+ - dependency groups
+ - ignore tags in release filelist
+ - tasks other than replace
+ - custom roles
+
+will cause pickle to fail, and output an error message.  If your package2.xml
+uses any of these features, you are best off using PEAR_PackageFileManager to
+generate both package.xml.
+</doc>
+ </pickle>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Registry.php b/lib/php/PEAR/Command/Registry.php
new file mode 100644
index 00000000..7ebc5efb
--- /dev/null
+++ b/lib/php/PEAR/Command/Registry.php
@@ -0,0 +1,1143 @@
+<?php
+/**
+ * PEAR_Command_Registry (list, list-files, shell-test, info commands)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Registry.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+
+/**
+ * PEAR commands for registry manipulation
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Command_Registry extends PEAR_Command_Common
+{
+    var $commands = array(
+        'list' => array(
+            'summary' => 'List Installed Packages In The Default Channel',
+            'function' => 'doList',
+            'shortcut' => 'l',
+            'options' => array(
+                'channel' => array(
+                    'shortopt' => 'c',
+                    'doc' => 'list installed packages from this channel',
+                    'arg' => 'CHAN',
+                    ),
+                'allchannels' => array(
+                    'shortopt' => 'a',
+                    'doc' => 'list installed packages from all channels',
+                    ),
+                'channelinfo' => array(
+                    'shortopt' => 'i',
+                    'doc' => 'output fully channel-aware data, even on failure',
+                    ),
+                ),
+            'doc' => '<package>
+If invoked without parameters, this command lists the PEAR packages
+installed in your php_dir ({config php_dir}).  With a parameter, it
+lists the files in a package.
+',
+            ),
+        'list-files' => array(
+            'summary' => 'List Files In Installed Package',
+            'function' => 'doFileList',
+            'shortcut' => 'fl',
+            'options' => array(),
+            'doc' => '<package>
+List the files in an installed package.
+'
+            ),
+        'shell-test' => array(
+            'summary' => 'Shell Script Test',
+            'function' => 'doShellTest',
+            'shortcut' => 'st',
+            'options' => array(),
+            'doc' => '<package> [[relation] version]
+Tests if a package is installed in the system. Will exit(1) if it is not.
+   <relation>   The version comparison operator. One of:
+                <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne
+   <version>    The version to compare with
+'),
+        'info' => array(
+            'summary'  => 'Display information about a package',
+            'function' => 'doInfo',
+            'shortcut' => 'in',
+            'options'  => array(),
+            'doc'      => '<package>
+Displays information about a package. The package argument may be a
+local package file, an URL to a package file, or the name of an
+installed package.'
+            )
+        );
+
+    /**
+     * PEAR_Command_Registry constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Registry(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    function _sortinfo($a, $b)
+    {
+        $apackage = isset($a['package']) ? $a['package'] : $a['name'];
+        $bpackage = isset($b['package']) ? $b['package'] : $b['name'];
+        return strcmp($apackage, $bpackage);
+    }
+
+    function doList($command, $options, $params)
+    {
+        $reg = &$this->config->getRegistry();
+        $channelinfo = isset($options['channelinfo']);
+        if (isset($options['allchannels']) && !$channelinfo) {
+            return $this->doListAll($command, array(), $params);
+        }
+
+        if (isset($options['allchannels']) && $channelinfo) {
+            // allchannels with $channelinfo
+            unset($options['allchannels']);
+            $channels = $reg->getChannels();
+            $errors = array();
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            foreach ($channels as $channel) {
+                $options['channel'] = $channel->getName();
+                $ret = $this->doList($command, $options, $params);
+
+                if (PEAR::isError($ret)) {
+                    $errors[] = $ret;
+                }
+            }
+
+            PEAR::staticPopErrorHandling();
+            if (count($errors)) {
+                // for now, only give first error
+                return PEAR::raiseError($errors[0]);
+            }
+
+            return true;
+        }
+
+        if (count($params) === 1) {
+            return $this->doFileList($command, $options, $params);
+        }
+
+        if (isset($options['channel'])) {
+            if (!$reg->channelExists($options['channel'])) {
+                return $this->raiseError('Channel "' . $options['channel'] .'" does not exist');
+            }
+
+            $channel = $reg->channelName($options['channel']);
+        } else {
+            $channel = $this->config->get('default_channel');
+        }
+
+        $installed = $reg->packageInfo(null, null, $channel);
+        usort($installed, array(&$this, '_sortinfo'));
+
+        $data = array(
+            'caption' => 'Installed packages, channel ' .
+                $channel . ':',
+            'border' => true,
+            'headline' => array('Package', 'Version', 'State'),
+            'channel' => $channel,
+            );
+        if ($channelinfo) {
+            $data['headline'] = array('Channel', 'Package', 'Version', 'State');
+        }
+
+        if (count($installed) && !isset($data['data'])) {
+            $data['data'] = array();
+        }
+
+        foreach ($installed as $package) {
+            $pobj = $reg->getPackage(isset($package['package']) ?
+                                        $package['package'] : $package['name'], $channel);
+            if ($channelinfo) {
+                $packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(),
+                                    $pobj->getState() ? $pobj->getState() : null);
+            } else {
+                $packageinfo = array($pobj->getPackage(), $pobj->getVersion(),
+                                    $pobj->getState() ? $pobj->getState() : null);
+            }
+            $data['data'][] = $packageinfo;
+        }
+
+        if (count($installed) === 0) {
+            if (!$channelinfo) {
+                $data = '(no packages installed from channel ' . $channel . ')';
+            } else {
+                $data = array(
+                    'caption' => 'Installed packages, channel ' .
+                        $channel . ':',
+                    'border' => true,
+                    'channel' => $channel,
+                    'data' => array(array('(no packages installed)')),
+                );
+            }
+        }
+
+        $this->ui->outputData($data, $command);
+        return true;
+    }
+
+    function doListAll($command, $options, $params)
+    {
+        // This duplicate code is deprecated over
+        // list --channelinfo, which gives identical
+        // output for list and list --allchannels.
+        $reg = &$this->config->getRegistry();
+        $installed = $reg->packageInfo(null, null, null);
+        foreach ($installed as $channel => $packages) {
+            usort($packages, array($this, '_sortinfo'));
+            $data = array(
+                'caption'  => 'Installed packages, channel ' . $channel . ':',
+                'border'   => true,
+                'headline' => array('Package', 'Version', 'State'),
+                'channel'  => $channel
+            );
+
+            foreach ($packages as $package) {
+                $p = isset($package['package']) ? $package['package'] : $package['name'];
+                $pobj = $reg->getPackage($p, $channel);
+                $data['data'][] = array($pobj->getPackage(), $pobj->getVersion(),
+                                        $pobj->getState() ? $pobj->getState() : null);
+            }
+
+            // Adds a blank line after each section
+            $data['data'][] = array();
+
+            if (count($packages) === 0) {
+                $data = array(
+                    'caption' => 'Installed packages, channel ' . $channel . ':',
+                    'border' => true,
+                    'data' => array(array('(no packages installed)'), array()),
+                    'channel' => $channel
+                    );
+            }
+            $this->ui->outputData($data, $command);
+        }
+        return true;
+    }
+
+    function doFileList($command, $options, $params)
+    {
+        if (count($params) !== 1) {
+            return $this->raiseError('list-files expects 1 parameter');
+        }
+
+        $reg = &$this->config->getRegistry();
+        $fp = false;
+        if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0], 'r'))) {
+            if ($fp) {
+                fclose($fp);
+            }
+
+            if (!class_exists('PEAR_PackageFile')) {
+                require_once 'PEAR/PackageFile.php';
+            }
+
+            $pkg = &new PEAR_PackageFile($this->config, $this->_debug);
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $info = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
+            PEAR::staticPopErrorHandling();
+            $headings = array('Package File', 'Install Path');
+            $installed = false;
+        } else {
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
+            PEAR::staticPopErrorHandling();
+            if (PEAR::isError($parsed)) {
+                return $this->raiseError($parsed);
+            }
+
+            $info = &$reg->getPackage($parsed['package'], $parsed['channel']);
+            $headings = array('Type', 'Install Path');
+            $installed = true;
+        }
+
+        if (PEAR::isError($info)) {
+            return $this->raiseError($info);
+        }
+
+        if ($info === null) {
+            return $this->raiseError("`$params[0]' not installed");
+        }
+
+        $list = ($info->getPackagexmlVersion() == '1.0' || $installed) ?
+            $info->getFilelist() : $info->getContents();
+        if ($installed) {
+            $caption = 'Installed Files For ' . $params[0];
+        } else {
+            $caption = 'Contents of ' . basename($params[0]);
+        }
+
+        $data = array(
+            'caption' => $caption,
+            'border' => true,
+            'headline' => $headings);
+        if ($info->getPackagexmlVersion() == '1.0' || $installed) {
+            foreach ($list as $file => $att) {
+                if ($installed) {
+                    if (empty($att['installed_as'])) {
+                        continue;
+                    }
+                    $data['data'][] = array($att['role'], $att['installed_as']);
+                } else {
+                    if (isset($att['baseinstalldir']) && !in_array($att['role'],
+                          array('test', 'data', 'doc'))) {
+                        $dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR .
+                            $file;
+                    } else {
+                        $dest = $file;
+                    }
+                    switch ($att['role']) {
+                        case 'test':
+                        case 'data':
+                        case 'doc':
+                            $role = $att['role'];
+                            if ($role == 'test') {
+                                $role .= 's';
+                            }
+                            $dest = $this->config->get($role . '_dir') . DIRECTORY_SEPARATOR .
+                                $info->getPackage() . DIRECTORY_SEPARATOR . $dest;
+                            break;
+                        case 'php':
+                        default:
+                            $dest = $this->config->get('php_dir') . DIRECTORY_SEPARATOR .
+                                $dest;
+                    }
+                    $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
+                    $dest = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
+                                                    array(DIRECTORY_SEPARATOR,
+                                                          DIRECTORY_SEPARATOR,
+                                                          DIRECTORY_SEPARATOR),
+                                                    $dest);
+                    $file = preg_replace('!/+!', '/', $file);
+                    $data['data'][] = array($file, $dest);
+                }
+            }
+        } else { // package.xml 2.0, not installed
+            if (!isset($list['dir']['file'][0])) {
+                $list['dir']['file'] = array($list['dir']['file']);
+            }
+
+            foreach ($list['dir']['file'] as $att) {
+                $att = $att['attribs'];
+                $file = $att['name'];
+                $role = &PEAR_Installer_Role::factory($info, $att['role'], $this->config);
+                $role->setup($this, $info, $att, $file);
+                if (!$role->isInstallable()) {
+                    $dest = '(not installable)';
+                } else {
+                    $dest = $role->processInstallation($info, $att, $file, '');
+                    if (PEAR::isError($dest)) {
+                        $dest = '(Unknown role "' . $att['role'] . ')';
+                    } else {
+                        list(,, $dest) = $dest;
+                    }
+                }
+                $data['data'][] = array($file, $dest);
+            }
+        }
+
+        $this->ui->outputData($data, $command);
+        return true;
+    }
+
+    function doShellTest($command, $options, $params)
+    {
+        if (count($params) < 1) {
+            return PEAR::raiseError('ERROR, usage: pear shell-test packagename [[relation] version]');
+        }
+
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $reg = &$this->config->getRegistry();
+        $info = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
+        if (PEAR::isError($info)) {
+            exit(1); // invalid package name
+        }
+
+        $package = $info['package'];
+        $channel = $info['channel'];
+        // "pear shell-test Foo"
+        if (!$reg->packageExists($package, $channel)) {
+            if ($channel == 'pecl.php.net') {
+                if ($reg->packageExists($package, 'pear.php.net')) {
+                    $channel = 'pear.php.net'; // magically change channels for extensions
+                }
+            }
+        }
+
+        if (count($params) === 1) {
+            if (!$reg->packageExists($package, $channel)) {
+                exit(1);
+            }
+            // "pear shell-test Foo 1.0"
+        } elseif (count($params) === 2) {
+            $v = $reg->packageInfo($package, 'version', $channel);
+            if (!$v || !version_compare("$v", "{$params[1]}", "ge")) {
+                exit(1);
+            }
+            // "pear shell-test Foo ge 1.0"
+        } elseif (count($params) === 3) {
+            $v = $reg->packageInfo($package, 'version', $channel);
+            if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) {
+                exit(1);
+            }
+        } else {
+            PEAR::staticPopErrorHandling();
+            $this->raiseError("$command: expects 1 to 3 parameters");
+            exit(1);
+        }
+    }
+
+    function doInfo($command, $options, $params)
+    {
+        if (count($params) !== 1) {
+            return $this->raiseError('pear info expects 1 parameter');
+        }
+
+        $info = $fp = false;
+        $reg = &$this->config->getRegistry();
+        if ((file_exists($params[0]) && is_file($params[0]) && !is_dir($params[0])) || $fp = @fopen($params[0], 'r')) {
+            if ($fp) {
+                fclose($fp);
+            }
+
+            if (!class_exists('PEAR_PackageFile')) {
+                require_once 'PEAR/PackageFile.php';
+            }
+
+            $pkg = &new PEAR_PackageFile($this->config, $this->_debug);
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $obj = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
+            PEAR::staticPopErrorHandling();
+            if (PEAR::isError($obj)) {
+                $uinfo = $obj->getUserInfo();
+                if (is_array($uinfo)) {
+                    foreach ($uinfo as $message) {
+                        if (is_array($message)) {
+                            $message = $message['message'];
+                        }
+                        $this->ui->outputData($message);
+                    }
+                }
+
+                return $this->raiseError($obj);
+            }
+
+            if ($obj->getPackagexmlVersion() != '1.0') {
+                return $this->_doInfo2($command, $options, $params, $obj, false);
+            }
+
+            $info = $obj->toArray();
+        } else {
+            $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
+            if (PEAR::isError($parsed)) {
+                return $this->raiseError($parsed);
+            }
+
+            $package = $parsed['package'];
+            $channel = $parsed['channel'];
+            $info = $reg->packageInfo($package, null, $channel);
+            if (isset($info['old'])) {
+                $obj = $reg->getPackage($package, $channel);
+                return $this->_doInfo2($command, $options, $params, $obj, true);
+            }
+        }
+
+        if (PEAR::isError($info)) {
+            return $info;
+        }
+
+        if (empty($info)) {
+            $this->raiseError("No information found for `$params[0]'");
+            return;
+        }
+
+        unset($info['filelist']);
+        unset($info['dirtree']);
+        unset($info['changelog']);
+        if (isset($info['xsdversion'])) {
+            $info['package.xml version'] = $info['xsdversion'];
+            unset($info['xsdversion']);
+        }
+
+        if (isset($info['packagerversion'])) {
+            $info['packaged with PEAR version'] = $info['packagerversion'];
+            unset($info['packagerversion']);
+        }
+
+        $keys = array_keys($info);
+        $longtext = array('description', 'summary');
+        foreach ($keys as $key) {
+            if (is_array($info[$key])) {
+                switch ($key) {
+                    case 'maintainers': {
+                        $i = 0;
+                        $mstr = '';
+                        foreach ($info[$key] as $m) {
+                            if ($i++ > 0) {
+                                $mstr .= "\n";
+                            }
+                            $mstr .= $m['name'] . " <";
+                            if (isset($m['email'])) {
+                                $mstr .= $m['email'];
+                            } else {
+                                $mstr .= $m['handle'] . '@php.net';
+                            }
+                            $mstr .= "> ($m[role])";
+                        }
+                        $info[$key] = $mstr;
+                        break;
+                    }
+                    case 'release_deps': {
+                        $i = 0;
+                        $dstr = '';
+                        foreach ($info[$key] as $d) {
+                            if (isset($this->_deps_rel_trans[$d['rel']])) {
+                                $rel = $this->_deps_rel_trans[$d['rel']];
+                            } else {
+                                $rel = $d['rel'];
+                            }
+                            if (isset($this->_deps_type_trans[$d['type']])) {
+                                $type = ucfirst($this->_deps_type_trans[$d['type']]);
+                            } else {
+                                $type = $d['type'];
+                            }
+                            if (isset($d['name'])) {
+                                $name = $d['name'] . ' ';
+                            } else {
+                                $name = '';
+                            }
+                            if (isset($d['version'])) {
+                                $version = $d['version'] . ' ';
+                            } else {
+                                $version = '';
+                            }
+                            if (isset($d['optional']) && $d['optional'] == 'yes') {
+                                $optional = ' (optional)';
+                            } else {
+                                $optional = '';
+                            }
+                            $dstr .= "$type $name$rel $version$optional\n";
+                        }
+                        $info[$key] = $dstr;
+                        break;
+                    }
+                    case 'provides' : {
+                        $debug = $this->config->get('verbose');
+                        if ($debug < 2) {
+                            $pstr = 'Classes: ';
+                        } else {
+                            $pstr = '';
+                        }
+                        $i = 0;
+                        foreach ($info[$key] as $p) {
+                            if ($debug < 2 && $p['type'] != "class") {
+                                continue;
+                            }
+                            // Only print classes when verbosity mode is < 2
+                            if ($debug < 2) {
+                                if ($i++ > 0) {
+                                    $pstr .= ", ";
+                                }
+                                $pstr .= $p['name'];
+                            } else {
+                                if ($i++ > 0) {
+                                    $pstr .= "\n";
+                                }
+                                $pstr .= ucfirst($p['type']) . " " . $p['name'];
+                                if (isset($p['explicit']) && $p['explicit'] == 1) {
+                                    $pstr .= " (explicit)";
+                                }
+                            }
+                        }
+                        $info[$key] = $pstr;
+                        break;
+                    }
+                    case 'configure_options' : {
+                        foreach ($info[$key] as $i => $p) {
+                            $info[$key][$i] = array_map(null, array_keys($p), array_values($p));
+                            $info[$key][$i] = array_map(create_function('$a',
+                                'return join(" = ",$a);'), $info[$key][$i]);
+                            $info[$key][$i] = implode(', ', $info[$key][$i]);
+                        }
+                        $info[$key] = implode("\n", $info[$key]);
+                        break;
+                    }
+                    default: {
+                        $info[$key] = implode(", ", $info[$key]);
+                        break;
+                    }
+                }
+            }
+
+            if ($key == '_lastmodified') {
+                $hdate = date('Y-m-d', $info[$key]);
+                unset($info[$key]);
+                $info['Last Modified'] = $hdate;
+            } elseif ($key == '_lastversion') {
+                $info['Previous Installed Version'] = $info[$key] ? $info[$key] : '- None -';
+                unset($info[$key]);
+            } else {
+                $info[$key] = trim($info[$key]);
+                if (in_array($key, $longtext)) {
+                    $info[$key] = preg_replace('/  +/', ' ', $info[$key]);
+                }
+            }
+        }
+
+        $caption = 'About ' . $info['package'] . '-' . $info['version'];
+        $data = array(
+            'caption' => $caption,
+            'border' => true);
+        foreach ($info as $key => $value) {
+            $key = ucwords(trim(str_replace('_', ' ', $key)));
+            $data['data'][] = array($key, $value);
+        }
+        $data['raw'] = $info;
+
+        $this->ui->outputData($data, 'package-info');
+    }
+
+    /**
+     * @access private
+     */
+    function _doInfo2($command, $options, $params, &$obj, $installed)
+    {
+        $reg = &$this->config->getRegistry();
+        $caption = 'About ' . $obj->getChannel() . '/' .$obj->getPackage() . '-' .
+            $obj->getVersion();
+        $data = array(
+            'caption' => $caption,
+            'border' => true);
+        switch ($obj->getPackageType()) {
+            case 'php' :
+                $release = 'PEAR-style PHP-based Package';
+            break;
+            case 'extsrc' :
+                $release = 'PECL-style PHP extension (source code)';
+            break;
+            case 'zendextsrc' :
+                $release = 'PECL-style Zend extension (source code)';
+            break;
+            case 'extbin' :
+                $release = 'PECL-style PHP extension (binary)';
+            break;
+            case 'zendextbin' :
+                $release = 'PECL-style Zend extension (binary)';
+            break;
+            case 'bundle' :
+                $release = 'Package bundle (collection of packages)';
+            break;
+        }
+        $extends = $obj->getExtends();
+        $extends = $extends ?
+            $obj->getPackage() . ' (extends ' . $extends . ')' : $obj->getPackage();
+        if ($src = $obj->getSourcePackage()) {
+            $extends .= ' (source package ' . $src['channel'] . '/' . $src['package'] . ')';
+        }
+
+        $info = array(
+            'Release Type' => $release,
+            'Name' => $extends,
+            'Channel' => $obj->getChannel(),
+            'Summary' => preg_replace('/  +/', ' ', $obj->getSummary()),
+            'Description' => preg_replace('/  +/', ' ', $obj->getDescription()),
+            );
+        $info['Maintainers'] = '';
+        foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
+            $leads = $obj->{"get{$role}s"}();
+            if (!$leads) {
+                continue;
+            }
+
+            if (isset($leads['active'])) {
+                $leads = array($leads);
+            }
+
+            foreach ($leads as $lead) {
+                if (!empty($info['Maintainers'])) {
+                    $info['Maintainers'] .= "\n";
+                }
+
+                $active = $lead['active'] == 'no' ? ', inactive' : '';
+                $info['Maintainers'] .= $lead['name'] . ' <';
+                $info['Maintainers'] .= $lead['email'] . "> ($role$active)";
+            }
+        }
+
+        $info['Release Date'] = $obj->getDate();
+        if ($time = $obj->getTime()) {
+            $info['Release Date'] .= ' ' . $time;
+        }
+
+        $info['Release Version'] = $obj->getVersion() . ' (' . $obj->getState() . ')';
+        $info['API Version'] = $obj->getVersion('api') . ' (' . $obj->getState('api') . ')';
+        $info['License'] = $obj->getLicense();
+        $uri = $obj->getLicenseLocation();
+        if ($uri) {
+            if (isset($uri['uri'])) {
+                $info['License'] .= ' (' . $uri['uri'] . ')';
+            } else {
+                $extra = $obj->getInstalledLocation($info['filesource']);
+                if ($extra) {
+                    $info['License'] .= ' (' . $uri['filesource'] . ')';
+                }
+            }
+        }
+
+        $info['Release Notes'] = $obj->getNotes();
+        if ($compat = $obj->getCompatible()) {
+            if (!isset($compat[0])) {
+                $compat = array($compat);
+            }
+
+            $info['Compatible with'] = '';
+            foreach ($compat as $package) {
+                $info['Compatible with'] .= $package['channel'] . '/' . $package['name'] .
+                    "\nVersions >= " . $package['min'] . ', <= ' . $package['max'];
+                if (isset($package['exclude'])) {
+                    if (is_array($package['exclude'])) {
+                        $package['exclude'] = implode(', ', $package['exclude']);
+                    }
+
+                    if (!isset($info['Not Compatible with'])) {
+                        $info['Not Compatible with'] = '';
+                    } else {
+                        $info['Not Compatible with'] .= "\n";
+                    }
+                    $info['Not Compatible with'] .= $package['channel'] . '/' .
+                        $package['name'] . "\nVersions " . $package['exclude'];
+                }
+            }
+        }
+
+        $usesrole = $obj->getUsesrole();
+        if ($usesrole) {
+            if (!isset($usesrole[0])) {
+                $usesrole = array($usesrole);
+            }
+
+            foreach ($usesrole as $roledata) {
+                if (isset($info['Uses Custom Roles'])) {
+                    $info['Uses Custom Roles'] .= "\n";
+                } else {
+                    $info['Uses Custom Roles'] = '';
+                }
+
+                if (isset($roledata['package'])) {
+                    $rolepackage = $reg->parsedPackageNameToString($roledata, true);
+                } else {
+                    $rolepackage = $roledata['uri'];
+                }
+                $info['Uses Custom Roles'] .= $roledata['role'] . ' (' . $rolepackage . ')';
+            }
+        }
+
+        $usestask = $obj->getUsestask();
+        if ($usestask) {
+            if (!isset($usestask[0])) {
+                $usestask = array($usestask);
+            }
+
+            foreach ($usestask as $taskdata) {
+                if (isset($info['Uses Custom Tasks'])) {
+                    $info['Uses Custom Tasks'] .= "\n";
+                } else {
+                    $info['Uses Custom Tasks'] = '';
+                }
+
+                if (isset($taskdata['package'])) {
+                    $taskpackage = $reg->parsedPackageNameToString($taskdata, true);
+                } else {
+                    $taskpackage = $taskdata['uri'];
+                }
+                $info['Uses Custom Tasks'] .= $taskdata['task'] . ' (' . $taskpackage . ')';
+            }
+        }
+
+        $deps = $obj->getDependencies();
+        $info['Required Dependencies'] = 'PHP version ' . $deps['required']['php']['min'];
+        if (isset($deps['required']['php']['max'])) {
+            $info['Required Dependencies'] .= '-' . $deps['required']['php']['max'] . "\n";
+        } else {
+            $info['Required Dependencies'] .= "\n";
+        }
+
+        if (isset($deps['required']['php']['exclude'])) {
+            if (!isset($info['Not Compatible with'])) {
+                $info['Not Compatible with'] = '';
+            } else {
+                $info['Not Compatible with'] .= "\n";
+            }
+
+            if (is_array($deps['required']['php']['exclude'])) {
+                $deps['required']['php']['exclude'] =
+                    implode(', ', $deps['required']['php']['exclude']);
+            }
+            $info['Not Compatible with'] .= "PHP versions\n  " .
+                $deps['required']['php']['exclude'];
+        }
+
+        $info['Required Dependencies'] .= 'PEAR installer version';
+        if (isset($deps['required']['pearinstaller']['max'])) {
+            $info['Required Dependencies'] .= 's ' .
+                $deps['required']['pearinstaller']['min'] . '-' .
+                $deps['required']['pearinstaller']['max'];
+        } else {
+            $info['Required Dependencies'] .= ' ' .
+                $deps['required']['pearinstaller']['min'] . ' or newer';
+        }
+
+        if (isset($deps['required']['pearinstaller']['exclude'])) {
+            if (!isset($info['Not Compatible with'])) {
+                $info['Not Compatible with'] = '';
+            } else {
+                $info['Not Compatible with'] .= "\n";
+            }
+
+            if (is_array($deps['required']['pearinstaller']['exclude'])) {
+                $deps['required']['pearinstaller']['exclude'] =
+                    implode(', ', $deps['required']['pearinstaller']['exclude']);
+            }
+            $info['Not Compatible with'] .= "PEAR installer\n  Versions " .
+                $deps['required']['pearinstaller']['exclude'];
+        }
+
+        foreach (array('Package', 'Extension') as $type) {
+            $index = strtolower($type);
+            if (isset($deps['required'][$index])) {
+                if (isset($deps['required'][$index]['name'])) {
+                    $deps['required'][$index] = array($deps['required'][$index]);
+                }
+
+                foreach ($deps['required'][$index] as $package) {
+                    if (isset($package['conflicts'])) {
+                        $infoindex = 'Not Compatible with';
+                        if (!isset($info['Not Compatible with'])) {
+                            $info['Not Compatible with'] = '';
+                        } else {
+                            $info['Not Compatible with'] .= "\n";
+                        }
+                    } else {
+                        $infoindex = 'Required Dependencies';
+                        $info[$infoindex] .= "\n";
+                    }
+
+                    if ($index == 'extension') {
+                        $name = $package['name'];
+                    } else {
+                        if (isset($package['channel'])) {
+                            $name = $package['channel'] . '/' . $package['name'];
+                        } else {
+                            $name = '__uri/' . $package['name'] . ' (static URI)';
+                        }
+                    }
+
+                    $info[$infoindex] .= "$type $name";
+                    if (isset($package['uri'])) {
+                        $info[$infoindex] .= "\n  Download URI: $package[uri]";
+                        continue;
+                    }
+
+                    if (isset($package['max']) && isset($package['min'])) {
+                        $info[$infoindex] .= " \n  Versions " .
+                            $package['min'] . '-' . $package['max'];
+                    } elseif (isset($package['min'])) {
+                        $info[$infoindex] .= " \n  Version " .
+                            $package['min'] . ' or newer';
+                    } elseif (isset($package['max'])) {
+                        $info[$infoindex] .= " \n  Version " .
+                            $package['max'] . ' or older';
+                    }
+
+                    if (isset($package['recommended'])) {
+                        $info[$infoindex] .= "\n  Recommended version: $package[recommended]";
+                    }
+
+                    if (isset($package['exclude'])) {
+                        if (!isset($info['Not Compatible with'])) {
+                            $info['Not Compatible with'] = '';
+                        } else {
+                            $info['Not Compatible with'] .= "\n";
+                        }
+
+                        if (is_array($package['exclude'])) {
+                            $package['exclude'] = implode(', ', $package['exclude']);
+                        }
+
+                        $package['package'] = $package['name']; // for parsedPackageNameToString
+                         if (isset($package['conflicts'])) {
+                            $info['Not Compatible with'] .= '=> except ';
+                        }
+                       $info['Not Compatible with'] .= 'Package ' .
+                            $reg->parsedPackageNameToString($package, true);
+                        $info['Not Compatible with'] .= "\n  Versions " . $package['exclude'];
+                    }
+                }
+            }
+        }
+
+        if (isset($deps['required']['os'])) {
+            if (isset($deps['required']['os']['name'])) {
+                $dep['required']['os']['name'] = array($dep['required']['os']['name']);
+            }
+
+            foreach ($dep['required']['os'] as $os) {
+                if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
+                    if (!isset($info['Not Compatible with'])) {
+                        $info['Not Compatible with'] = '';
+                    } else {
+                        $info['Not Compatible with'] .= "\n";
+                    }
+                    $info['Not Compatible with'] .= "$os[name] Operating System";
+                } else {
+                    $info['Required Dependencies'] .= "\n";
+                    $info['Required Dependencies'] .= "$os[name] Operating System";
+                }
+            }
+        }
+
+        if (isset($deps['required']['arch'])) {
+            if (isset($deps['required']['arch']['pattern'])) {
+                $dep['required']['arch']['pattern'] = array($dep['required']['os']['pattern']);
+            }
+
+            foreach ($dep['required']['arch'] as $os) {
+                if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
+                    if (!isset($info['Not Compatible with'])) {
+                        $info['Not Compatible with'] = '';
+                    } else {
+                        $info['Not Compatible with'] .= "\n";
+                    }
+                    $info['Not Compatible with'] .= "OS/Arch matching pattern '/$os[pattern]/'";
+                } else {
+                    $info['Required Dependencies'] .= "\n";
+                    $info['Required Dependencies'] .= "OS/Arch matching pattern '/$os[pattern]/'";
+                }
+            }
+        }
+
+        if (isset($deps['optional'])) {
+            foreach (array('Package', 'Extension') as $type) {
+                $index = strtolower($type);
+                if (isset($deps['optional'][$index])) {
+                    if (isset($deps['optional'][$index]['name'])) {
+                        $deps['optional'][$index] = array($deps['optional'][$index]);
+                    }
+
+                    foreach ($deps['optional'][$index] as $package) {
+                        if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
+                            $infoindex = 'Not Compatible with';
+                            if (!isset($info['Not Compatible with'])) {
+                                $info['Not Compatible with'] = '';
+                            } else {
+                                $info['Not Compatible with'] .= "\n";
+                            }
+                        } else {
+                            $infoindex = 'Optional Dependencies';
+                            if (!isset($info['Optional Dependencies'])) {
+                                $info['Optional Dependencies'] = '';
+                            } else {
+                                $info['Optional Dependencies'] .= "\n";
+                            }
+                        }
+
+                        if ($index == 'extension') {
+                            $name = $package['name'];
+                        } else {
+                            if (isset($package['channel'])) {
+                                $name = $package['channel'] . '/' . $package['name'];
+                            } else {
+                                $name = '__uri/' . $package['name'] . ' (static URI)';
+                            }
+                        }
+
+                        $info[$infoindex] .= "$type $name";
+                        if (isset($package['uri'])) {
+                            $info[$infoindex] .= "\n  Download URI: $package[uri]";
+                            continue;
+                        }
+
+                        if ($infoindex == 'Not Compatible with') {
+                            // conflicts is only used to say that all versions conflict
+                            continue;
+                        }
+
+                        if (isset($package['max']) && isset($package['min'])) {
+                            $info[$infoindex] .= " \n  Versions " .
+                                $package['min'] . '-' . $package['max'];
+                        } elseif (isset($package['min'])) {
+                            $info[$infoindex] .= " \n  Version " .
+                                $package['min'] . ' or newer';
+                        } elseif (isset($package['max'])) {
+                            $info[$infoindex] .= " \n  Version " .
+                                $package['min'] . ' or older';
+                        }
+
+                        if (isset($package['recommended'])) {
+                            $info[$infoindex] .= "\n  Recommended version: $package[recommended]";
+                        }
+
+                        if (isset($package['exclude'])) {
+                            if (!isset($info['Not Compatible with'])) {
+                                $info['Not Compatible with'] = '';
+                            } else {
+                                $info['Not Compatible with'] .= "\n";
+                            }
+
+                            if (is_array($package['exclude'])) {
+                                $package['exclude'] = implode(', ', $package['exclude']);
+                            }
+
+                            $info['Not Compatible with'] .= "Package $package\n  Versions " .
+                                $package['exclude'];
+                        }
+                    }
+                }
+            }
+        }
+
+        if (isset($deps['group'])) {
+            if (!isset($deps['group'][0])) {
+                $deps['group'] = array($deps['group']);
+            }
+
+            foreach ($deps['group'] as $group) {
+                $info['Dependency Group ' . $group['attribs']['name']] = $group['attribs']['hint'];
+                $groupindex = $group['attribs']['name'] . ' Contents';
+                $info[$groupindex] = '';
+                foreach (array('Package', 'Extension') as $type) {
+                    $index = strtolower($type);
+                    if (isset($group[$index])) {
+                        if (isset($group[$index]['name'])) {
+                            $group[$index] = array($group[$index]);
+                        }
+
+                        foreach ($group[$index] as $package) {
+                            if (!empty($info[$groupindex])) {
+                                $info[$groupindex] .= "\n";
+                            }
+
+                            if ($index == 'extension') {
+                                $name = $package['name'];
+                            } else {
+                                if (isset($package['channel'])) {
+                                    $name = $package['channel'] . '/' . $package['name'];
+                                } else {
+                                    $name = '__uri/' . $package['name'] . ' (static URI)';
+                                }
+                            }
+
+                            if (isset($package['uri'])) {
+                                if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
+                                    $info[$groupindex] .= "Not Compatible with $type $name";
+                                } else {
+                                    $info[$groupindex] .= "$type $name";
+                                }
+
+                                $info[$groupindex] .= "\n  Download URI: $package[uri]";
+                                continue;
+                            }
+
+                            if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
+                                $info[$groupindex] .= "Not Compatible with $type $name";
+                                continue;
+                            }
+
+                            $info[$groupindex] .= "$type $name";
+                            if (isset($package['max']) && isset($package['min'])) {
+                                $info[$groupindex] .= " \n  Versions " .
+                                    $package['min'] . '-' . $package['max'];
+                            } elseif (isset($package['min'])) {
+                                $info[$groupindex] .= " \n  Version " .
+                                    $package['min'] . ' or newer';
+                            } elseif (isset($package['max'])) {
+                                $info[$groupindex] .= " \n  Version " .
+                                    $package['min'] . ' or older';
+                            }
+
+                            if (isset($package['recommended'])) {
+                                $info[$groupindex] .= "\n  Recommended version: $package[recommended]";
+                            }
+
+                            if (isset($package['exclude'])) {
+                                if (!isset($info['Not Compatible with'])) {
+                                    $info['Not Compatible with'] = '';
+                                } else {
+                                    $info[$groupindex] .= "Not Compatible with\n";
+                                }
+
+                                if (is_array($package['exclude'])) {
+                                    $package['exclude'] = implode(', ', $package['exclude']);
+                                }
+                                $info[$groupindex] .= "  Package $package\n  Versions " .
+                                    $package['exclude'];
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if ($obj->getPackageType() == 'bundle') {
+            $info['Bundled Packages'] = '';
+            foreach ($obj->getBundledPackages() as $package) {
+                if (!empty($info['Bundled Packages'])) {
+                    $info['Bundled Packages'] .= "\n";
+                }
+
+                if (isset($package['uri'])) {
+                    $info['Bundled Packages'] .= '__uri/' . $package['name'];
+                    $info['Bundled Packages'] .= "\n  (URI: $package[uri]";
+                } else {
+                    $info['Bundled Packages'] .= $package['channel'] . '/' . $package['name'];
+                }
+            }
+        }
+
+        $info['package.xml version'] = '2.0';
+        if ($installed) {
+            if ($obj->getLastModified()) {
+                $info['Last Modified'] = date('Y-m-d H:i', $obj->getLastModified());
+            }
+
+            $v = $obj->getLastInstalledVersion();
+            $info['Previous Installed Version'] = $v ? $v : '- None -';
+        }
+
+        foreach ($info as $key => $value) {
+            $data['data'][] = array($key, $value);
+        }
+
+        $data['raw'] = $obj->getArray(); // no validation needed
+        $this->ui->outputData($data, 'package-info');
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Registry.xml b/lib/php/PEAR/Command/Registry.xml
new file mode 100644
index 00000000..9f4e2149
--- /dev/null
+++ b/lib/php/PEAR/Command/Registry.xml
@@ -0,0 +1,58 @@
+<commands version="1.0">
+ <list>
+  <summary>List Installed Packages In The Default Channel</summary>
+  <function>doList</function>
+  <shortcut>l</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>list installed packages from this channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+   <allchannels>
+    <shortopt>a</shortopt>
+    <doc>list installed packages from all channels</doc>
+   </allchannels>
+   <channelinfo>
+    <shortopt>i</shortopt>
+    <doc>output fully channel-aware data, even on failure</doc>
+   </channelinfo>
+  </options>
+  <doc>&lt;package&gt;
+If invoked without parameters, this command lists the PEAR packages
+installed in your php_dir ({config php_dir}).  With a parameter, it
+lists the files in a package.
+</doc>
+ </list>
+ <list-files>
+  <summary>List Files In Installed Package</summary>
+  <function>doFileList</function>
+  <shortcut>fl</shortcut>
+  <options />
+  <doc>&lt;package&gt;
+List the files in an installed package.
+</doc>
+ </list-files>
+ <shell-test>
+  <summary>Shell Script Test</summary>
+  <function>doShellTest</function>
+  <shortcut>st</shortcut>
+  <options />
+  <doc>&lt;package&gt; [[relation] version]
+Tests if a package is installed in the system. Will exit(1) if it is not.
+   &lt;relation&gt;   The version comparison operator. One of:
+                &lt;, lt, &lt;=, le, &gt;, gt, &gt;=, ge, ==, =, eq, !=, &lt;&gt;, ne
+   &lt;version&gt;    The version to compare with
+</doc>
+ </shell-test>
+ <info>
+  <summary>Display information about a package</summary>
+  <function>doInfo</function>
+  <shortcut>in</shortcut>
+  <options />
+  <doc>&lt;package&gt;
+Displays information about a package. The package argument may be a
+local package file, an URL to a package file, or the name of an
+installed package.</doc>
+ </info>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Remote.php b/lib/php/PEAR/Command/Remote.php
new file mode 100644
index 00000000..6f87e31d
--- /dev/null
+++ b/lib/php/PEAR/Command/Remote.php
@@ -0,0 +1,809 @@
+<?php
+/**
+ * PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
+ * clear-cache commands)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Remote.php 287477 2009-08-19 14:19:43Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+require_once 'PEAR/REST.php';
+
+/**
+ * PEAR commands for remote server querying
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Command_Remote extends PEAR_Command_Common
+{
+    var $commands = array(
+        'remote-info' => array(
+            'summary' => 'Information About Remote Packages',
+            'function' => 'doRemoteInfo',
+            'shortcut' => 'ri',
+            'options' => array(),
+            'doc' => '<package>
+Get details on a package from the server.',
+            ),
+        'list-upgrades' => array(
+            'summary' => 'List Available Upgrades',
+            'function' => 'doListUpgrades',
+            'shortcut' => 'lu',
+            'options' => array(
+                'channelinfo' => array(
+                    'shortopt' => 'i',
+                    'doc' => 'output fully channel-aware data, even on failure',
+                    ),
+            ),
+            'doc' => '[preferred_state]
+List releases on the server of packages you have installed where
+a newer version is available with the same release state (stable etc.)
+or the state passed as the second parameter.'
+            ),
+        'remote-list' => array(
+            'summary' => 'List Remote Packages',
+            'function' => 'doRemoteList',
+            'shortcut' => 'rl',
+            'options' => array(
+                'channel' =>
+                    array(
+                    'shortopt' => 'c',
+                    'doc' => 'specify a channel other than the default channel',
+                    'arg' => 'CHAN',
+                    )
+                ),
+            'doc' => '
+Lists the packages available on the configured server along with the
+latest stable release of each package.',
+            ),
+        'search' => array(
+            'summary' => 'Search remote package database',
+            'function' => 'doSearch',
+            'shortcut' => 'sp',
+            'options' => array(
+                'channel' =>
+                    array(
+                    'shortopt' => 'c',
+                    'doc' => 'specify a channel other than the default channel',
+                    'arg' => 'CHAN',
+                    ),
+                'allchannels' => array(
+                    'shortopt' => 'a',
+                    'doc' => 'search packages from all known channels',
+                    ),
+                'channelinfo' => array(
+                    'shortopt' => 'i',
+                    'doc' => 'output fully channel-aware data, even on failure',
+                    ),
+                ),
+            'doc' => '[packagename] [packageinfo]
+Lists all packages which match the search parameters.  The first
+parameter is a fragment of a packagename.  The default channel
+will be used unless explicitly overridden.  The second parameter
+will be used to match any portion of the summary/description',
+            ),
+        'list-all' => array(
+            'summary' => 'List All Packages',
+            'function' => 'doListAll',
+            'shortcut' => 'la',
+            'options' => array(
+                'channel' =>
+                    array(
+                    'shortopt' => 'c',
+                    'doc' => 'specify a channel other than the default channel',
+                    'arg' => 'CHAN',
+                    ),
+                'channelinfo' => array(
+                    'shortopt' => 'i',
+                    'doc' => 'output fully channel-aware data, even on failure',
+                    ),
+                ),
+            'doc' => '
+Lists the packages available on the configured server along with the
+latest stable release of each package.',
+            ),
+        'download' => array(
+            'summary' => 'Download Package',
+            'function' => 'doDownload',
+            'shortcut' => 'd',
+            'options' => array(
+                'nocompress' => array(
+                    'shortopt' => 'Z',
+                    'doc' => 'download an uncompressed (.tar) file',
+                    ),
+                ),
+            'doc' => '<package>...
+Download package tarballs.  The files will be named as suggested by the
+server, for example if you download the DB package and the latest stable
+version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.',
+            ),
+        'clear-cache' => array(
+            'summary' => 'Clear Web Services Cache',
+            'function' => 'doClearCache',
+            'shortcut' => 'cc',
+            'options' => array(),
+            'doc' => '
+Clear the XML-RPC/REST cache.  See also the cache_ttl configuration
+parameter.
+',
+            ),
+        );
+
+    /**
+     * PEAR_Command_Remote constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Remote(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    function _checkChannelForStatus($channel, $chan)
+    {
+        if (PEAR::isError($chan)) {
+            $this->raiseError($chan);
+        }
+        if (!is_a($chan, 'PEAR_ChannelFile')) {
+            return $this->raiseError('Internal corruption error: invalid channel "' .
+                $channel . '"');
+        }
+        $rest = new PEAR_REST($this->config);
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $mirror = $this->config->get('preferred_mirror', null,
+                                     $channel);
+        $a = $rest->downloadHttp('http://' . $channel .
+            '/channel.xml', $chan->lastModified());
+        PEAR::staticPopErrorHandling();
+        if (!PEAR::isError($a) && $a) {
+            $this->ui->outputData('WARNING: channel "' . $channel . '" has ' .
+                'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $channel .
+                '" to update');
+        }
+    }
+
+    function doRemoteInfo($command, $options, $params)
+    {
+        if (sizeof($params) != 1) {
+            return $this->raiseError("$command expects one param: the remote package name");
+        }
+        $savechannel = $channel = $this->config->get('default_channel');
+        $reg = &$this->config->getRegistry();
+        $package = $params[0];
+        $parsed = $reg->parsePackageName($package, $channel);
+        if (PEAR::isError($parsed)) {
+            return $this->raiseError('Invalid package name "' . $package . '"');
+        }
+
+        $channel = $parsed['channel'];
+        $this->config->set('default_channel', $channel);
+        $chan = $reg->getChannel($channel);
+        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
+            return $e;
+        }
+
+        $mirror = $this->config->get('preferred_mirror');
+        if ($chan->supportsREST($mirror) && $base = $chan->getBaseURL('REST1.0', $mirror)) {
+            $rest = &$this->config->getREST('1.0', array());
+            $info = $rest->packageInfo($base, $parsed['package'], $channel);
+        }
+
+        if (!isset($info)) {
+            return $this->raiseError('No supported protocol was found');
+        }
+
+        if (PEAR::isError($info)) {
+            $this->config->set('default_channel', $savechannel);
+            return $this->raiseError($info);
+        }
+
+        if (!isset($info['name'])) {
+            return $this->raiseError('No remote package "' . $package . '" was found');
+        }
+
+        $installed = $reg->packageInfo($info['name'], null, $channel);
+        $info['installed'] = $installed['version'] ? $installed['version'] : '- no -';
+        if (is_array($info['installed'])) {
+            $info['installed'] = $info['installed']['release'];
+        }
+
+        $this->ui->outputData($info, $command);
+        $this->config->set('default_channel', $savechannel);
+
+        return true;
+    }
+
+    function doRemoteList($command, $options, $params)
+    {
+        $savechannel = $channel = $this->config->get('default_channel');
+        $reg = &$this->config->getRegistry();
+        if (isset($options['channel'])) {
+            $channel = $options['channel'];
+            if (!$reg->channelExists($channel)) {
+                return $this->raiseError('Channel "' . $channel . '" does not exist');
+            }
+
+            $this->config->set('default_channel', $channel);
+        }
+
+        $chan = $reg->getChannel($channel);
+        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
+            return $e;
+        }
+
+        $list_options = false;
+        if ($this->config->get('preferred_state') == 'stable') {
+            $list_options = true;
+        }
+
+        $available = array();
+        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
+              $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))
+        ) {
+            // use faster list-all if available
+            $rest = &$this->config->getREST('1.1', array());
+            $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
+        } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
+              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
+            $rest = &$this->config->getREST('1.0', array());
+            $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
+        }
+
+        if (PEAR::isError($available)) {
+            $this->config->set('default_channel', $savechannel);
+            return $this->raiseError($available);
+        }
+
+        $i = $j = 0;
+        $data = array(
+            'caption' => 'Channel ' . $channel . ' Available packages:',
+            'border' => true,
+            'headline' => array('Package', 'Version'),
+            'channel' => $channel
+            );
+
+        if (count($available) == 0) {
+            $data = '(no packages available yet)';
+        } else {
+            foreach ($available as $name => $info) {
+                $version = (isset($info['stable']) && $info['stable']) ? $info['stable'] : '-n/a-';
+                $data['data'][] = array($name, $version);
+            }
+        }
+        $this->ui->outputData($data, $command);
+        $this->config->set('default_channel', $savechannel);
+        return true;
+    }
+
+    function doListAll($command, $options, $params)
+    {
+        $savechannel = $channel = $this->config->get('default_channel');
+        $reg = &$this->config->getRegistry();
+        if (isset($options['channel'])) {
+            $channel = $options['channel'];
+            if (!$reg->channelExists($channel)) {
+                return $this->raiseError("Channel \"$channel\" does not exist");
+            }
+
+            $this->config->set('default_channel', $channel);
+        }
+
+        $list_options = false;
+        if ($this->config->get('preferred_state') == 'stable') {
+            $list_options = true;
+        }
+
+        $chan = $reg->getChannel($channel);
+        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
+            return $e;
+        }
+
+        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
+              $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
+            // use faster list-all if available
+            $rest = &$this->config->getREST('1.1', array());
+            $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
+        } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
+              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
+            $rest = &$this->config->getREST('1.0', array());
+            $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
+        }
+
+        if (PEAR::isError($available)) {
+            $this->config->set('default_channel', $savechannel);
+            return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")');
+        }
+
+        $data = array(
+            'caption' => 'All packages [Channel ' . $channel . ']:',
+            'border' => true,
+            'headline' => array('Package', 'Latest', 'Local'),
+            'channel' => $channel,
+            );
+
+        if (isset($options['channelinfo'])) {
+            // add full channelinfo
+            $data['caption'] = 'Channel ' . $channel . ' All packages:';
+            $data['headline'] = array('Channel', 'Package', 'Latest', 'Local',
+                'Description', 'Dependencies');
+        }
+        $local_pkgs = $reg->listPackages($channel);
+
+        foreach ($available as $name => $info) {
+            $installed = $reg->packageInfo($name, null, $channel);
+            if (is_array($installed['version'])) {
+                $installed['version'] = $installed['version']['release'];
+            }
+            $desc = $info['summary'];
+            if (isset($params[$name])) {
+                $desc .= "\n\n".$info['description'];
+            }
+            if (isset($options['mode']))
+            {
+                if ($options['mode'] == 'installed' && !isset($installed['version'])) {
+                    continue;
+                }
+                if ($options['mode'] == 'notinstalled' && isset($installed['version'])) {
+                    continue;
+                }
+                if ($options['mode'] == 'upgrades'
+                      && (!isset($installed['version']) || version_compare($installed['version'],
+                      $info['stable'], '>='))) {
+                    continue;
+                }
+            }
+            $pos = array_search(strtolower($name), $local_pkgs);
+            if ($pos !== false) {
+                unset($local_pkgs[$pos]);
+            }
+
+            if (isset($info['stable']) && !$info['stable']) {
+                $info['stable'] = null;
+            }
+
+            if (isset($options['channelinfo'])) {
+                // add full channelinfo
+                if ($info['stable'] === $info['unstable']) {
+                    $state = $info['state'];
+                } else {
+                    $state = 'stable';
+                }
+                $latest = $info['stable'].' ('.$state.')';
+                $local = '';
+                if (isset($installed['version'])) {
+                    $inst_state = $reg->packageInfo($name, 'release_state', $channel);
+                    $local = $installed['version'].' ('.$inst_state.')';
+                }
+
+                $packageinfo = array(
+                    $channel,
+                    $name,
+                    $latest,
+                    $local,
+                    isset($desc) ? $desc : null,
+                    isset($info['deps']) ? $info['deps'] : null,
+                );
+            } else {
+                $packageinfo = array(
+                    $reg->channelAlias($channel) . '/' . $name,
+                    isset($info['stable']) ? $info['stable'] : null,
+                    isset($installed['version']) ? $installed['version'] : null,
+                    isset($desc) ? $desc : null,
+                    isset($info['deps']) ? $info['deps'] : null,
+                );
+            }
+            $data['data'][$info['category']][] = $packageinfo;
+        }
+
+        if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) {
+            $this->config->set('default_channel', $savechannel);
+            $this->ui->outputData($data, $command);
+            return true;
+        }
+
+        foreach ($local_pkgs as $name) {
+            $info = &$reg->getPackage($name, $channel);
+            $data['data']['Local'][] = array(
+                $reg->channelAlias($channel) . '/' . $info->getPackage(),
+                '',
+                $info->getVersion(),
+                $info->getSummary(),
+                $info->getDeps()
+                );
+        }
+
+        $this->config->set('default_channel', $savechannel);
+        $this->ui->outputData($data, $command);
+        return true;
+    }
+
+    function doSearch($command, $options, $params)
+    {
+        if ((!isset($params[0]) || empty($params[0]))
+            && (!isset($params[1]) || empty($params[1])))
+        {
+            return $this->raiseError('no valid search string supplied');
+        }
+
+        $channelinfo = isset($options['channelinfo']);
+        $reg = &$this->config->getRegistry();
+        if (isset($options['allchannels'])) {
+            // search all channels
+            unset($options['allchannels']);
+            $channels = $reg->getChannels();
+            $errors = array();
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            foreach ($channels as $channel) {
+                if ($channel->getName() != '__uri') {
+                    $options['channel'] = $channel->getName();
+                    $ret = $this->doSearch($command, $options, $params);
+                    if (PEAR::isError($ret)) {
+                        $errors[] = $ret;
+                    }
+                }
+            }
+
+            PEAR::staticPopErrorHandling();
+            if (count($errors) !== 0) {
+                // for now, only give first error
+                return PEAR::raiseError($errors[0]);
+            }
+
+            return true;
+        }
+
+        $savechannel = $channel = $this->config->get('default_channel');
+        $package = strtolower($params[0]);
+        $summary = isset($params[1]) ? $params[1] : false;
+        if (isset($options['channel'])) {
+            $reg = &$this->config->getRegistry();
+            $channel = $options['channel'];
+            if (!$reg->channelExists($channel)) {
+                return $this->raiseError('Channel "' . $channel . '" does not exist');
+            }
+
+            $this->config->set('default_channel', $channel);
+        }
+
+        $chan = $reg->getChannel($channel);
+        if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
+            return $e;
+        }
+
+        if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
+              $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
+            $rest = &$this->config->getREST('1.0', array());
+            $available = $rest->listAll($base, false, false, $package, $summary, $chan->getName());
+        }
+
+        if (PEAR::isError($available)) {
+            $this->config->set('default_channel', $savechannel);
+            return $this->raiseError($available);
+        }
+
+        if (!$available && !$channelinfo) {
+            // clean exit when not found, no error !
+            $data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.';
+            $this->ui->outputData($data);
+            $this->config->set('default_channel', $channel);
+            return true;
+        }
+
+        if ($channelinfo) {
+            $data = array(
+                'caption' => 'Matched packages, channel ' . $channel . ':',
+                'border' => true,
+                'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'),
+                'channel' => $channel
+                );
+        } else {
+            $data = array(
+                'caption' => 'Matched packages, channel ' . $channel . ':',
+                'border' => true,
+                'headline' => array('Package', 'Stable/(Latest)', 'Local'),
+                'channel' => $channel
+                );
+        }
+
+        if (!$available && $channelinfo) {
+            unset($data['headline']);
+            $data['data'] = 'No packages found that match pattern "' . $package . '".';
+            $available = array();
+        }
+
+        foreach ($available as $name => $info) {
+            $installed = $reg->packageInfo($name, null, $channel);
+            $desc = $info['summary'];
+            if (isset($params[$name]))
+                $desc .= "\n\n".$info['description'];
+
+            if (!isset($info['stable']) || !$info['stable']) {
+                $version_remote = 'none';
+            } else {
+                if ($info['unstable']) {
+                    $version_remote = $info['unstable'];
+                } else {
+                    $version_remote = $info['stable'];
+                }
+                $version_remote .= ' ('.$info['state'].')';
+            }
+            $version = is_array($installed['version']) ? $installed['version']['release'] :
+                $installed['version'];
+            if ($channelinfo) {
+                $packageinfo = array(
+                    $channel,
+                    $name,
+                    $version_remote,
+                    $version,
+                    $desc,
+                );
+            } else {
+                $packageinfo = array(
+                    $name,
+                    $version_remote,
+                    $version,
+                    $desc,
+                );
+            }
+            $data['data'][$info['category']][] = $packageinfo;
+        }
+
+        $this->ui->outputData($data, $command);
+        $this->config->set('default_channel', $channel);
+        return true;
+    }
+
+    function &getDownloader($options)
+    {
+        if (!class_exists('PEAR_Downloader')) {
+            require_once 'PEAR/Downloader.php';
+        }
+        $a = &new PEAR_Downloader($this->ui, $options, $this->config);
+        return $a;
+    }
+
+    function doDownload($command, $options, $params)
+    {
+        // make certain that dependencies are ignored
+        $options['downloadonly'] = 1;
+
+        // eliminate error messages for preferred_state-related errors
+        /* TODO: Should be an option, but until now download does respect
+           prefered state */
+        /* $options['ignorepreferred_state'] = 1; */
+        // eliminate error messages for preferred_state-related errors
+
+        $downloader = &$this->getDownloader($options);
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $e = $downloader->setDownloadDir(getcwd());
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($e)) {
+            return $this->raiseError('Current directory is not writeable, cannot download');
+        }
+
+        $errors = array();
+        $downloaded = array();
+        $err = $downloader->download($params);
+        if (PEAR::isError($err)) {
+            return $err;
+        }
+
+        $errors = $downloader->getErrorMsgs();
+        if (count($errors)) {
+            foreach ($errors as $error) {
+                if ($error !== null) {
+                    $this->ui->outputData($error);
+                }
+            }
+
+            return $this->raiseError("$command failed");
+        }
+
+        $downloaded = $downloader->getDownloadedPackages();
+        foreach ($downloaded as $pkg) {
+            $this->ui->outputData("File $pkg[file] downloaded", $command);
+        }
+
+        return true;
+    }
+
+    function downloadCallback($msg, $params = null)
+    {
+        if ($msg == 'done') {
+            $this->bytes_downloaded = $params;
+        }
+    }
+
+    function doListUpgrades($command, $options, $params)
+    {
+        require_once 'PEAR/Common.php';
+        if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) {
+            return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"');
+        }
+
+        $savechannel = $channel = $this->config->get('default_channel');
+        $reg = &$this->config->getRegistry();
+        foreach ($reg->listChannels() as $channel) {
+            $inst = array_flip($reg->listPackages($channel));
+            if (!count($inst)) {
+                continue;
+            }
+
+            if ($channel == '__uri') {
+                continue;
+            }
+
+            $this->config->set('default_channel', $channel);
+            $state = empty($params[0]) ? $this->config->get('preferred_state') : $params[0];
+
+            $caption = $channel . ' Available Upgrades';
+            $chan = $reg->getChannel($channel);
+            if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
+                return $e;
+            }
+
+            $latest = array();
+            $base2  = false;
+            $preferred_mirror = $this->config->get('preferred_mirror');
+            if ($chan->supportsREST($preferred_mirror) &&
+                (
+                   //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) ||
+                   ($base  = $chan->getBaseURL('REST1.0', $preferred_mirror))
+                )
+
+            ) {
+                if ($base2) {
+                    $rest = &$this->config->getREST('1.4', array());
+                    $base = $base2;
+                } else {
+                    $rest = &$this->config->getREST('1.0', array());
+                }
+
+                if (empty($state) || $state == 'any') {
+                    $state = false;
+                } else {
+                    $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
+                }
+
+                PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                $latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg);
+                PEAR::staticPopErrorHandling();
+            }
+
+            if (PEAR::isError($latest)) {
+                $this->ui->outputData($latest->getMessage());
+                continue;
+            }
+
+            $caption .= ':';
+            if (PEAR::isError($latest)) {
+                $this->config->set('default_channel', $savechannel);
+                return $latest;
+            }
+
+            $data = array(
+                'caption' => $caption,
+                'border' => 1,
+                'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'),
+                'channel' => $channel
+                );
+
+            foreach ((array)$latest as $pkg => $info) {
+                $package = strtolower($pkg);
+                if (!isset($inst[$package])) {
+                    // skip packages we don't have installed
+                    continue;
+                }
+
+                extract($info);
+                $inst_version = $reg->packageInfo($package, 'version', $channel);
+                $inst_state   = $reg->packageInfo($package, 'release_state', $channel);
+                if (version_compare("$version", "$inst_version", "le")) {
+                    // installed version is up-to-date
+                    continue;
+                }
+
+                if ($filesize >= 20480) {
+                    $filesize += 1024 - ($filesize % 1024);
+                    $fs = sprintf("%dkB", $filesize / 1024);
+                } elseif ($filesize > 0) {
+                    $filesize += 103 - ($filesize % 103);
+                    $fs = sprintf("%.1fkB", $filesize / 1024.0);
+                } else {
+                    $fs = "  -"; // XXX center instead
+                }
+
+                $data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
+            }
+
+            if (isset($options['channelinfo'])) {
+                if (empty($data['data'])) {
+                    unset($data['headline']);
+                    if (count($inst) == 0) {
+                        $data['data'] = '(no packages installed)';
+                    } else {
+                        $data['data'] = '(no upgrades available)';
+                    }
+                }
+                $this->ui->outputData($data, $command);
+            } else {
+                if (empty($data['data'])) {
+                    $this->ui->outputData('Channel ' . $channel . ': No upgrades available');
+                } else {
+                    $this->ui->outputData($data, $command);
+                }
+            }
+        }
+
+        $this->config->set('default_channel', $savechannel);
+        return true;
+    }
+
+    function doClearCache($command, $options, $params)
+    {
+        $cache_dir = $this->config->get('cache_dir');
+        $verbose   = $this->config->get('verbose');
+        $output = '';
+        if (!file_exists($cache_dir) || !is_dir($cache_dir)) {
+            return $this->raiseError("$cache_dir does not exist or is not a directory");
+        }
+
+        if (!($dp = @opendir($cache_dir))) {
+            return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
+        }
+
+        if ($verbose >= 1) {
+            $output .= "reading directory $cache_dir\n";
+        }
+        $num = 0;
+        while ($ent = readdir($dp)) {
+            if (preg_match('/rest.cache(file|id)\\z/', $ent)) {
+                $path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
+                if (file_exists($path)) {
+                    $ok = @unlink($path);
+                } else {
+                    $ok = false;
+                    $php_errormsg = '';
+                }
+
+                if ($ok) {
+                    if ($verbose >= 2) {
+                        $output .= "deleted $path\n";
+                    }
+                    $num++;
+                } elseif ($verbose >= 1) {
+                    $output .= "failed to delete $path $php_errormsg\n";
+                }
+            }
+        }
+
+        closedir($dp);
+        if ($verbose >= 1) {
+            $output .= "$num cache entries cleared\n";
+        }
+
+        $this->ui->outputData(rtrim($output), $command);
+        return $num;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Remote.xml b/lib/php/PEAR/Command/Remote.xml
new file mode 100644
index 00000000..b4f6100c
--- /dev/null
+++ b/lib/php/PEAR/Command/Remote.xml
@@ -0,0 +1,109 @@
+<commands version="1.0">
+ <remote-info>
+  <summary>Information About Remote Packages</summary>
+  <function>doRemoteInfo</function>
+  <shortcut>ri</shortcut>
+  <options />
+  <doc>&lt;package&gt;
+Get details on a package from the server.</doc>
+ </remote-info>
+ <list-upgrades>
+  <summary>List Available Upgrades</summary>
+  <function>doListUpgrades</function>
+  <shortcut>lu</shortcut>
+  <options>
+   <channelinfo>
+    <shortopt>i</shortopt>
+    <doc>output fully channel-aware data, even on failure</doc>
+   </channelinfo>
+  </options>
+  <doc>[preferred_state]
+List releases on the server of packages you have installed where
+a newer version is available with the same release state (stable etc.)
+or the state passed as the second parameter.</doc>
+ </list-upgrades>
+ <remote-list>
+  <summary>List Remote Packages</summary>
+  <function>doRemoteList</function>
+  <shortcut>rl</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>specify a channel other than the default channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+  </options>
+  <doc>
+Lists the packages available on the configured server along with the
+latest stable release of each package.</doc>
+ </remote-list>
+ <search>
+  <summary>Search remote package database</summary>
+  <function>doSearch</function>
+  <shortcut>sp</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>specify a channel other than the default channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+   <allchannels>
+    <shortopt>a</shortopt>
+    <doc>search packages from all known channels</doc>
+   </allchannels>
+   <channelinfo>
+    <shortopt>i</shortopt>
+    <doc>output fully channel-aware data, even on failure</doc>
+   </channelinfo>
+  </options>
+  <doc>[packagename] [packageinfo]
+Lists all packages which match the search parameters.  The first
+parameter is a fragment of a packagename.  The default channel
+will be used unless explicitly overridden.  The second parameter
+will be used to match any portion of the summary/description</doc>
+ </search>
+ <list-all>
+  <summary>List All Packages</summary>
+  <function>doListAll</function>
+  <shortcut>la</shortcut>
+  <options>
+   <channel>
+    <shortopt>c</shortopt>
+    <doc>specify a channel other than the default channel</doc>
+    <arg>CHAN</arg>
+   </channel>
+   <channelinfo>
+    <shortopt>i</shortopt>
+    <doc>output fully channel-aware data, even on failure</doc>
+   </channelinfo>
+  </options>
+  <doc>
+Lists the packages available on the configured server along with the
+latest stable release of each package.</doc>
+ </list-all>
+ <download>
+  <summary>Download Package</summary>
+  <function>doDownload</function>
+  <shortcut>d</shortcut>
+  <options>
+   <nocompress>
+    <shortopt>Z</shortopt>
+    <doc>download an uncompressed (.tar) file</doc>
+   </nocompress>
+  </options>
+  <doc>&lt;package&gt;...
+Download package tarballs.  The files will be named as suggested by the
+server, for example if you download the DB package and the latest stable
+version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.</doc>
+ </download>
+ <clear-cache>
+  <summary>Clear Web Services Cache</summary>
+  <function>doClearCache</function>
+  <shortcut>cc</shortcut>
+  <options />
+  <doc>
+Clear the XML-RPC/REST cache.  See also the cache_ttl configuration
+parameter.
+</doc>
+ </clear-cache>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Test.php b/lib/php/PEAR/Command/Test.php
new file mode 100644
index 00000000..3715859f
--- /dev/null
+++ b/lib/php/PEAR/Command/Test.php
@@ -0,0 +1,337 @@
+<?php
+/**
+ * PEAR_Command_Test (run-tests)
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Test.php 279072 2009-04-20 19:57:41Z cellog $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Command/Common.php';
+
+/**
+ * PEAR commands for login/logout
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+
+class PEAR_Command_Test extends PEAR_Command_Common
+{
+    var $commands = array(
+        'run-tests' => array(
+            'summary' => 'Run Regression Tests',
+            'function' => 'doRunTests',
+            'shortcut' => 'rt',
+            'options' => array(
+                'recur' => array(
+                    'shortopt' => 'r',
+                    'doc' => 'Run tests in child directories, recursively.  4 dirs deep maximum',
+                ),
+                'ini' => array(
+                    'shortopt' => 'i',
+                    'doc' => 'actual string of settings to pass to php in format " -d setting=blah"',
+                    'arg' => 'SETTINGS'
+                ),
+                'realtimelog' => array(
+                    'shortopt' => 'l',
+                    'doc' => 'Log test runs/results as they are run',
+                ),
+                'quiet' => array(
+                    'shortopt' => 'q',
+                    'doc' => 'Only display detail for failed tests',
+                ),
+                'simple' => array(
+                    'shortopt' => 's',
+                    'doc' => 'Display simple output for all tests',
+                ),
+                'package' => array(
+                    'shortopt' => 'p',
+                    'doc' => 'Treat parameters as installed packages from which to run tests',
+                ),
+                'phpunit' => array(
+                    'shortopt' => 'u',
+                    'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests
+If none is found, all .phpt tests will be tried instead.',
+                ),
+                'tapoutput' => array(
+                    'shortopt' => 't',
+                    'doc' => 'Output run-tests.log in TAP-compliant format',
+                ),
+                'cgi' => array(
+                    'shortopt' => 'c',
+                    'doc' => 'CGI php executable (needed for tests with POST/GET section)',
+                    'arg' => 'PHPCGI',
+                ),
+                'coverage' => array(
+                    'shortopt' => 'x',
+                    'doc'      => 'Generate a code coverage report (requires Xdebug 2.0.0+)',
+                ),
+            ),
+            'doc' => '[testfile|dir ...]
+Run regression tests with PHP\'s regression testing script (run-tests.php).',
+            ),
+        );
+
+    var $output;
+
+    /**
+     * PEAR_Command_Test constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Test(&$ui, &$config)
+    {
+        parent::PEAR_Command_Common($ui, $config);
+    }
+
+    function doRunTests($command, $options, $params)
+    {
+        if (isset($options['phpunit']) && isset($options['tapoutput'])) {
+            return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time');
+        }
+
+        require_once 'PEAR/Common.php';
+        require_once 'System.php';
+        $log = new PEAR_Common;
+        $log->ui = &$this->ui; // slightly hacky, but it will work
+        $tests = array();
+        $depth = isset($options['recur']) ? 14 : 1;
+
+        if (!count($params)) {
+            $params[] = '.';
+        }
+
+        if (isset($options['package'])) {
+            $oldparams = $params;
+            $params = array();
+            $reg = &$this->config->getRegistry();
+            foreach ($oldparams as $param) {
+                $pname = $reg->parsePackageName($param, $this->config->get('default_channel'));
+                if (PEAR::isError($pname)) {
+                    return $this->raiseError($pname);
+                }
+
+                $package = &$reg->getPackage($pname['package'], $pname['channel']);
+                if (!$package) {
+                    return PEAR::raiseError('Unknown package "' .
+                        $reg->parsedPackageNameToString($pname) . '"');
+                }
+
+                $filelist = $package->getFilelist();
+                foreach ($filelist as $name => $atts) {
+                    if (isset($atts['role']) && $atts['role'] != 'test') {
+                        continue;
+                    }
+
+                    if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) {
+                        $params[] = $atts['installed_as'];
+                        continue;
+                    } elseif (!preg_match('/\.phpt\\z/', $name)) {
+                        continue;
+                    }
+                    $params[] = $atts['installed_as'];
+                }
+            }
+        }
+
+        foreach ($params as $p) {
+            if (is_dir($p)) {
+                if (isset($options['phpunit'])) {
+                    $dir = System::find(array($p, '-type', 'f',
+                                                '-maxdepth', $depth,
+                                                '-name', 'AllTests.php'));
+                    if (count($dir)) {
+                        foreach ($dir as $p) {
+                            $p = realpath($p);
+                            if (!count($tests) ||
+                                  (count($tests) && strlen($p) < strlen($tests[0]))) {
+                                // this is in a higher-level directory, use this one instead.
+                                $tests = array($p);
+                            }
+                        }
+                    }
+                    continue;
+                }
+
+                $args  = array($p, '-type', 'f', '-name', '*.phpt');
+            } else {
+                if (isset($options['phpunit'])) {
+                    if (preg_match('/AllTests\.php\\z/i', $p)) {
+                        $p = realpath($p);
+                        if (!count($tests) ||
+                              (count($tests) && strlen($p) < strlen($tests[0]))) {
+                            // this is in a higher-level directory, use this one instead.
+                            $tests = array($p);
+                        }
+                    }
+                    continue;
+                }
+
+                if (file_exists($p) && preg_match('/\.phpt$/', $p)) {
+                    $tests[] = $p;
+                    continue;
+                }
+
+                if (!preg_match('/\.phpt\\z/', $p)) {
+                    $p .= '.phpt';
+                }
+
+                $args  = array(dirname($p), '-type', 'f', '-name', $p);
+            }
+
+            if (!isset($options['recur'])) {
+                $args[] = '-maxdepth';
+                $args[] = 1;
+            }
+
+            $dir   = System::find($args);
+            $tests = array_merge($tests, $dir);
+        }
+
+        $ini_settings = '';
+        if (isset($options['ini'])) {
+            $ini_settings .= $options['ini'];
+        }
+
+        if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) {
+            $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}";
+        }
+
+        if ($ini_settings) {
+            $this->ui->outputData('Using INI settings: "' . $ini_settings . '"');
+        }
+
+        $skipped = $passed = $failed = array();
+        $tests_count = count($tests);
+        $this->ui->outputData('Running ' . $tests_count . ' tests', $command);
+        $start = time();
+        if (isset($options['realtimelog']) && file_exists('run-tests.log')) {
+            unlink('run-tests.log');
+        }
+
+        if (isset($options['tapoutput'])) {
+            $tap = '1..' . $tests_count . "\n";
+        }
+
+        require_once 'PEAR/RunTest.php';
+        $run = new PEAR_RunTest($log, $options);
+        $run->tests_count = $tests_count;
+
+        if (isset($options['coverage']) && extension_loaded('xdebug')){
+            $run->xdebug_loaded = true;
+        } else {
+            $run->xdebug_loaded = false;
+        }
+
+        $j = $i = 1;
+        foreach ($tests as $t) {
+            if (isset($options['realtimelog'])) {
+                $fp = @fopen('run-tests.log', 'a');
+                if ($fp) {
+                    fwrite($fp, "Running test [$i / $tests_count] $t...");
+                    fclose($fp);
+                }
+            }
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            if (isset($options['phpunit'])) {
+                $result = $run->runPHPUnit($t, $ini_settings);
+            } else {
+                $result = $run->run($t, $ini_settings, $j);
+            }
+            PEAR::staticPopErrorHandling();
+            if (PEAR::isError($result)) {
+                $this->ui->log($result->getMessage());
+                continue;
+            }
+
+            if (isset($options['tapoutput'])) {
+                $tap .= $result[0] . ' ' . $i . $result[1] . "\n";
+                continue;
+            }
+
+            if (isset($options['realtimelog'])) {
+                $fp = @fopen('run-tests.log', 'a');
+                if ($fp) {
+                    fwrite($fp, "$result\n");
+                    fclose($fp);
+                }
+            }
+
+            if ($result == 'FAILED') {
+                $failed[] = $t;
+            }
+            if ($result == 'PASSED') {
+                $passed[] = $t;
+            }
+            if ($result == 'SKIPPED') {
+                $skipped[] = $t;
+            }
+
+            $j++;
+        }
+
+        $total = date('i:s', time() - $start);
+        if (isset($options['tapoutput'])) {
+            $fp = @fopen('run-tests.log', 'w');
+            if ($fp) {
+                fwrite($fp, $tap, strlen($tap));
+                fclose($fp);
+                $this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') .
+                    '"', $command);
+            }
+        } else {
+            if (count($failed)) {
+                $output = "TOTAL TIME: $total\n";
+                $output .= count($passed) . " PASSED TESTS\n";
+                $output .= count($skipped) . " SKIPPED TESTS\n";
+                $output .= count($failed) . " FAILED TESTS:\n";
+                foreach ($failed as $failure) {
+                    $output .= $failure . "\n";
+                }
+
+                $mode = isset($options['realtimelog']) ? 'a' : 'w';
+                $fp   = @fopen('run-tests.log', $mode);
+
+                if ($fp) {
+                    fwrite($fp, $output, strlen($output));
+                    fclose($fp);
+                    $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command);
+                }
+            } elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) {
+                @unlink('run-tests.log');
+            }
+        }
+        $this->ui->outputData('TOTAL TIME: ' . $total);
+        $this->ui->outputData(count($passed) . ' PASSED TESTS', $command);
+        $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command);
+        if (count($failed)) {
+            $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command);
+            foreach ($failed as $failure) {
+                $this->ui->outputData($failure, $command);
+            }
+        }
+
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Command/Test.xml b/lib/php/PEAR/Command/Test.xml
new file mode 100644
index 00000000..bbe9fccc
--- /dev/null
+++ b/lib/php/PEAR/Command/Test.xml
@@ -0,0 +1,54 @@
+<commands version="1.0">
+ <run-tests>
+  <summary>Run Regression Tests</summary>
+  <function>doRunTests</function>
+  <shortcut>rt</shortcut>
+  <options>
+   <recur>
+    <shortopt>r</shortopt>
+    <doc>Run tests in child directories, recursively.  4 dirs deep maximum</doc>
+   </recur>
+   <ini>
+    <shortopt>i</shortopt>
+    <doc>actual string of settings to pass to php in format &quot; -d setting=blah&quot;</doc>
+    <arg>SETTINGS</arg>
+   </ini>
+   <realtimelog>
+    <shortopt>l</shortopt>
+    <doc>Log test runs/results as they are run</doc>
+   </realtimelog>
+   <quiet>
+    <shortopt>q</shortopt>
+    <doc>Only display detail for failed tests</doc>
+   </quiet>
+   <simple>
+    <shortopt>s</shortopt>
+    <doc>Display simple output for all tests</doc>
+   </simple>
+   <package>
+    <shortopt>p</shortopt>
+    <doc>Treat parameters as installed packages from which to run tests</doc>
+   </package>
+   <phpunit>
+    <shortopt>u</shortopt>
+    <doc>Search parameters for AllTests.php, and use that to run phpunit-based tests
+If none is found, all .phpt tests will be tried instead.</doc>
+   </phpunit>
+   <tapoutput>
+    <shortopt>t</shortopt>
+    <doc>Output run-tests.log in TAP-compliant format</doc>
+   </tapoutput>
+   <cgi>
+    <shortopt>c</shortopt>
+    <doc>CGI php executable (needed for tests with POST/GET section)</doc>
+    <arg>PHPCGI</arg>
+   </cgi>
+   <coverage>
+    <shortopt>x</shortopt>
+    <doc>Generate a code coverage report (requires Xdebug 2.0.0+)</doc>
+   </coverage>
+  </options>
+  <doc>[testfile|dir ...]
+Run regression tests with PHP&#039;s regression testing script (run-tests.php).</doc>
+ </run-tests>
+</commands>
\ No newline at end of file
diff --git a/lib/php/PEAR/Common.php b/lib/php/PEAR/Common.php
new file mode 100644
index 00000000..52764416
--- /dev/null
+++ b/lib/php/PEAR/Common.php
@@ -0,0 +1,837 @@
+<?php
+/**
+ * PEAR_Common, the base class for the PEAR Installer
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Common.php 282969 2009-06-28 23:09:27Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1.0
+ * @deprecated File deprecated since Release 1.4.0a1
+ */
+
+/**
+ * Include error handling
+ */
+require_once 'PEAR.php';
+
+/**
+ * PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode()
+ */
+define('PEAR_COMMON_ERROR_INVALIDPHP', 1);
+define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+');
+define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/');
+
+// this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1
+define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?');
+define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '\\z/i');
+
+// XXX far from perfect :-)
+define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG .
+    ')(-([.0-9a-zA-Z]+))?');
+define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG .
+    '\\z/');
+
+define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+');
+define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/');
+
+// this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED
+define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*');
+define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '\\z/i');
+
+define('_PEAR_CHANNELS_PACKAGE_PREG',  '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/('
+         . _PEAR_COMMON_PACKAGE_NAME_PREG . ')');
+define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/i');
+
+define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::('
+    . _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?');
+define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '\\z/');
+
+/**
+ * List of temporary files and directories registered by
+ * PEAR_Common::addTempFile().
+ * @var array
+ */
+$GLOBALS['_PEAR_Common_tempfiles'] = array();
+
+/**
+ * Valid maintainer roles
+ * @var array
+ */
+$GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper');
+
+/**
+ * Valid release states
+ * @var array
+ */
+$GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel');
+
+/**
+ * Valid dependency types
+ * @var array
+ */
+$GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi');
+
+/**
+ * Valid dependency relations
+ * @var array
+ */
+$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne');
+
+/**
+ * Valid file roles
+ * @var array
+ */
+$GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script');
+
+/**
+ * Valid replacement types
+ * @var array
+ */
+$GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info');
+
+/**
+ * Valid "provide" types
+ * @var array
+ */
+$GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api');
+
+/**
+ * Valid "provide" types
+ * @var array
+ */
+$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup');
+
+/**
+ * Class providing common functionality for PEAR administration classes.
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ * @deprecated This class will disappear, and its components will be spread
+ *             into smaller classes, like the AT&T breakup, as of Release 1.4.0a1
+ */
+class PEAR_Common extends PEAR
+{
+    /**
+     * User Interface object (PEAR_Frontend_* class).  If null,
+     * the log() method uses print.
+     * @var object
+     */
+    var $ui = null;
+
+    /**
+     * Configuration object (PEAR_Config).
+     * @var PEAR_Config
+     */
+    var $config = null;
+
+    /** stack of elements, gives some sort of XML context */
+    var $element_stack = array();
+
+    /** name of currently parsed XML element */
+    var $current_element;
+
+    /** array of attributes of the currently parsed XML element */
+    var $current_attributes = array();
+
+    /** assoc with information about a package */
+    var $pkginfo = array();
+
+    var $current_path = null;
+
+    /**
+     * Flag variable used to mark a valid package file
+     * @var boolean
+     * @access private
+     */
+    var $_validPackageFile;
+
+    /**
+     * PEAR_Common constructor
+     *
+     * @access public
+     */
+    function PEAR_Common()
+    {
+        parent::PEAR();
+        $this->config = &PEAR_Config::singleton();
+        $this->debug = $this->config->get('verbose');
+    }
+
+    /**
+     * PEAR_Common destructor
+     *
+     * @access private
+     */
+    function _PEAR_Common()
+    {
+        // doesn't work due to bug #14744
+        //$tempfiles = $this->_tempfiles;
+        $tempfiles =& $GLOBALS['_PEAR_Common_tempfiles'];
+        while ($file = array_shift($tempfiles)) {
+            if (@is_dir($file)) {
+                if (!class_exists('System')) {
+                    require_once 'System.php';
+                }
+
+                System::rm(array('-rf', $file));
+            } elseif (file_exists($file)) {
+                unlink($file);
+            }
+        }
+    }
+
+    /**
+     * Register a temporary file or directory.  When the destructor is
+     * executed, all registered temporary files and directories are
+     * removed.
+     *
+     * @param string  $file  name of file or directory
+     *
+     * @return void
+     *
+     * @access public
+     */
+    function addTempFile($file)
+    {
+        if (!class_exists('PEAR_Frontend')) {
+            require_once 'PEAR/Frontend.php';
+        }
+        PEAR_Frontend::addTempFile($file);
+    }
+
+    /**
+     * Wrapper to System::mkDir(), creates a directory as well as
+     * any necessary parent directories.
+     *
+     * @param string  $dir  directory name
+     *
+     * @return bool TRUE on success, or a PEAR error
+     *
+     * @access public
+     */
+    function mkDirHier($dir)
+    {
+        // Only used in Installer - move it there ?
+        $this->log(2, "+ create dir $dir");
+        if (!class_exists('System')) {
+            require_once 'System.php';
+        }
+        return System::mkDir(array('-p', $dir));
+    }
+
+    /**
+     * Logging method.
+     *
+     * @param int    $level  log level (0 is quiet, higher is noisier)
+     * @param string $msg    message to write to the log
+     *
+     * @return void
+     *
+     * @access public
+     * @static
+     */
+    function log($level, $msg, $append_crlf = true)
+    {
+        if ($this->debug >= $level) {
+            if (!class_exists('PEAR_Frontend')) {
+                require_once 'PEAR/Frontend.php';
+            }
+
+            $ui = &PEAR_Frontend::singleton();
+            if (is_a($ui, 'PEAR_Frontend')) {
+                $ui->log($msg, $append_crlf);
+            } else {
+                print "$msg\n";
+            }
+        }
+    }
+
+    /**
+     * Create and register a temporary directory.
+     *
+     * @param string $tmpdir (optional) Directory to use as tmpdir.
+     *                       Will use system defaults (for example
+     *                       /tmp or c:\windows\temp) if not specified
+     *
+     * @return string name of created directory
+     *
+     * @access public
+     */
+    function mkTempDir($tmpdir = '')
+    {
+        $topt = $tmpdir ? array('-t', $tmpdir) : array();
+        $topt = array_merge($topt, array('-d', 'pear'));
+        if (!class_exists('System')) {
+            require_once 'System.php';
+        }
+
+        if (!$tmpdir = System::mktemp($topt)) {
+            return false;
+        }
+
+        $this->addTempFile($tmpdir);
+        return $tmpdir;
+    }
+
+    /**
+     * Set object that represents the frontend to be used.
+     *
+     * @param  object Reference of the frontend object
+     * @return void
+     * @access public
+     */
+    function setFrontendObject(&$ui)
+    {
+        $this->ui = &$ui;
+    }
+
+    /**
+     * Return an array containing all of the states that are more stable than
+     * or equal to the passed in state
+     *
+     * @param string Release state
+     * @param boolean Determines whether to include $state in the list
+     * @return false|array False if $state is not a valid release state
+     */
+    function betterStates($state, $include = false)
+    {
+        static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
+        $i = array_search($state, $states);
+        if ($i === false) {
+            return false;
+        }
+        if ($include) {
+            $i--;
+        }
+        return array_slice($states, $i + 1);
+    }
+
+    /**
+     * Get the valid roles for a PEAR package maintainer
+     *
+     * @return array
+     * @static
+     */
+    function getUserRoles()
+    {
+        return $GLOBALS['_PEAR_Common_maintainer_roles'];
+    }
+
+    /**
+     * Get the valid package release states of packages
+     *
+     * @return array
+     * @static
+     */
+    function getReleaseStates()
+    {
+        return $GLOBALS['_PEAR_Common_release_states'];
+    }
+
+    /**
+     * Get the implemented dependency types (php, ext, pkg etc.)
+     *
+     * @return array
+     * @static
+     */
+    function getDependencyTypes()
+    {
+        return $GLOBALS['_PEAR_Common_dependency_types'];
+    }
+
+    /**
+     * Get the implemented dependency relations (has, lt, ge etc.)
+     *
+     * @return array
+     * @static
+     */
+    function getDependencyRelations()
+    {
+        return $GLOBALS['_PEAR_Common_dependency_relations'];
+    }
+
+    /**
+     * Get the implemented file roles
+     *
+     * @return array
+     * @static
+     */
+    function getFileRoles()
+    {
+        return $GLOBALS['_PEAR_Common_file_roles'];
+    }
+
+    /**
+     * Get the implemented file replacement types in
+     *
+     * @return array
+     * @static
+     */
+    function getReplacementTypes()
+    {
+        return $GLOBALS['_PEAR_Common_replacement_types'];
+    }
+
+    /**
+     * Get the implemented file replacement types in
+     *
+     * @return array
+     * @static
+     */
+    function getProvideTypes()
+    {
+        return $GLOBALS['_PEAR_Common_provide_types'];
+    }
+
+    /**
+     * Get the implemented file replacement types in
+     *
+     * @return array
+     * @static
+     */
+    function getScriptPhases()
+    {
+        return $GLOBALS['_PEAR_Common_script_phases'];
+    }
+
+    /**
+     * Test whether a string contains a valid package name.
+     *
+     * @param string $name the package name to test
+     *
+     * @return bool
+     *
+     * @access public
+     */
+    function validPackageName($name)
+    {
+        return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name);
+    }
+
+    /**
+     * Test whether a string contains a valid package version.
+     *
+     * @param string $ver the package version to test
+     *
+     * @return bool
+     *
+     * @access public
+     */
+    function validPackageVersion($ver)
+    {
+        return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
+    }
+
+    /**
+     * @param string $path relative or absolute include path
+     * @return boolean
+     * @static
+     */
+    function isIncludeable($path)
+    {
+        if (file_exists($path) && is_readable($path)) {
+            return true;
+        }
+
+        $ipath = explode(PATH_SEPARATOR, ini_get('include_path'));
+        foreach ($ipath as $include) {
+            $test = realpath($include . DIRECTORY_SEPARATOR . $path);
+            if (file_exists($test) && is_readable($test)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    function _postProcessChecks($pf)
+    {
+        if (!PEAR::isError($pf)) {
+            return $this->_postProcessValidPackagexml($pf);
+        }
+
+        $errs = $pf->getUserinfo();
+        if (is_array($errs)) {
+            foreach ($errs as $error) {
+                $e = $this->raiseError($error['message'], $error['code'], null, null, $error);
+            }
+        }
+
+        return $pf;
+    }
+
+    /**
+     * Returns information about a package file.  Expects the name of
+     * a gzipped tar file as input.
+     *
+     * @param string  $file  name of .tgz file
+     *
+     * @return array  array with package information
+     *
+     * @access public
+     * @deprecated use PEAR_PackageFile->fromTgzFile() instead
+     *
+     */
+    function infoFromTgzFile($file)
+    {
+        $packagefile = &new PEAR_PackageFile($this->config);
+        $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL);
+        return $this->_postProcessChecks($pf);
+    }
+
+    /**
+     * Returns information about a package file.  Expects the name of
+     * a package xml file as input.
+     *
+     * @param string  $descfile  name of package xml file
+     *
+     * @return array  array with package information
+     *
+     * @access public
+     * @deprecated use PEAR_PackageFile->fromPackageFile() instead
+     *
+     */
+    function infoFromDescriptionFile($descfile)
+    {
+        $packagefile = &new PEAR_PackageFile($this->config);
+        $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
+        return $this->_postProcessChecks($pf);
+    }
+
+    /**
+     * Returns information about a package file.  Expects the contents
+     * of a package xml file as input.
+     *
+     * @param string  $data  contents of package.xml file
+     *
+     * @return array   array with package information
+     *
+     * @access public
+     * @deprecated use PEAR_PackageFile->fromXmlstring() instead
+     *
+     */
+    function infoFromString($data)
+    {
+        $packagefile = &new PEAR_PackageFile($this->config);
+        $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false);
+        return $this->_postProcessChecks($pf);
+    }
+
+    /**
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @return array
+     */
+    function _postProcessValidPackagexml(&$pf)
+    {
+        if (!is_a($pf, 'PEAR_PackageFile_v2')) {
+            $this->pkginfo = $pf->toArray();
+            return $this->pkginfo;
+        }
+
+        // sort of make this into a package.xml 1.0-style array
+        // changelog is not converted to old format.
+        $arr = $pf->toArray(true);
+        $arr = array_merge($arr, $arr['old']);
+        unset($arr['old'], $arr['xsdversion'], $arr['contents'], $arr['compatible'],
+              $arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'],
+              $arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'],
+              $arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'],
+              $arr['helper'], $arr['contributor']);
+        $arr['filelist'] = $pf->getFilelist();
+        $this->pkginfo = $arr;
+        return $arr;
+    }
+
+    /**
+     * Returns package information from different sources
+     *
+     * This method is able to extract information about a package
+     * from a .tgz archive or from a XML package definition file.
+     *
+     * @access public
+     * @param  string Filename of the source ('package.xml', '<package>.tgz')
+     * @return string
+     * @deprecated use PEAR_PackageFile->fromAnyFile() instead
+     */
+    function infoFromAny($info)
+    {
+        if (is_string($info) && file_exists($info)) {
+            $packagefile = &new PEAR_PackageFile($this->config);
+            $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL);
+            if (PEAR::isError($pf)) {
+                $errs = $pf->getUserinfo();
+                if (is_array($errs)) {
+                    foreach ($errs as $error) {
+                        $e = $this->raiseError($error['message'], $error['code'], null, null, $error);
+                    }
+                }
+
+                return $pf;
+            }
+
+            return $this->_postProcessValidPackagexml($pf);
+        }
+
+        return $info;
+    }
+
+    /**
+     * Return an XML document based on the package info (as returned
+     * by the PEAR_Common::infoFrom* methods).
+     *
+     * @param array  $pkginfo  package info
+     *
+     * @return string XML data
+     *
+     * @access public
+     * @deprecated use a PEAR_PackageFile_v* object's generator instead
+     */
+    function xmlFromInfo($pkginfo)
+    {
+        $config      = &PEAR_Config::singleton();
+        $packagefile = &new PEAR_PackageFile($config);
+        $pf = &$packagefile->fromArray($pkginfo);
+        $gen = &$pf->getDefaultGenerator();
+        return $gen->toXml(PEAR_VALIDATE_PACKAGING);
+    }
+
+    /**
+     * Validate XML package definition file.
+     *
+     * @param  string $info Filename of the package archive or of the
+     *                package definition file
+     * @param  array $errors Array that will contain the errors
+     * @param  array $warnings Array that will contain the warnings
+     * @param  string $dir_prefix (optional) directory where source files
+     *                may be found, or empty if they are not available
+     * @access public
+     * @return boolean
+     * @deprecated use the validation of PEAR_PackageFile objects
+     */
+    function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '')
+    {
+        $config      = &PEAR_Config::singleton();
+        $packagefile = &new PEAR_PackageFile($config);
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        if (strpos($info, '<?xml') !== false) {
+            $pf = &$packagefile->fromXmlString($info, PEAR_VALIDATE_NORMAL, '');
+        } else {
+            $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL);
+        }
+
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($pf)) {
+            $errs = $pf->getUserinfo();
+            if (is_array($errs)) {
+                foreach ($errs as $error) {
+                    if ($error['level'] == 'error') {
+                        $errors[] = $error['message'];
+                    } else {
+                        $warnings[] = $error['message'];
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Build a "provides" array from data returned by
+     * analyzeSourceCode().  The format of the built array is like
+     * this:
+     *
+     *  array(
+     *    'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
+     *    ...
+     *  )
+     *
+     *
+     * @param array $srcinfo array with information about a source file
+     * as returned by the analyzeSourceCode() method.
+     *
+     * @return void
+     *
+     * @access public
+     *
+     */
+    function buildProvidesArray($srcinfo)
+    {
+        $file = basename($srcinfo['source_file']);
+        $pn = '';
+        if (isset($this->_packageName)) {
+            $pn = $this->_packageName;
+        }
+
+        $pnl = strlen($pn);
+        foreach ($srcinfo['declared_classes'] as $class) {
+            $key = "class;$class";
+            if (isset($this->pkginfo['provides'][$key])) {
+                continue;
+            }
+
+            $this->pkginfo['provides'][$key] =
+                array('file'=> $file, 'type' => 'class', 'name' => $class);
+            if (isset($srcinfo['inheritance'][$class])) {
+                $this->pkginfo['provides'][$key]['extends'] =
+                    $srcinfo['inheritance'][$class];
+            }
+        }
+
+        foreach ($srcinfo['declared_methods'] as $class => $methods) {
+            foreach ($methods as $method) {
+                $function = "$class::$method";
+                $key = "function;$function";
+                if ($method{0} == '_' || !strcasecmp($method, $class) ||
+                    isset($this->pkginfo['provides'][$key])) {
+                    continue;
+                }
+
+                $this->pkginfo['provides'][$key] =
+                    array('file'=> $file, 'type' => 'function', 'name' => $function);
+            }
+        }
+
+        foreach ($srcinfo['declared_functions'] as $function) {
+            $key = "function;$function";
+            if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) {
+                continue;
+            }
+
+            if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
+                $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
+            }
+
+            $this->pkginfo['provides'][$key] =
+                array('file'=> $file, 'type' => 'function', 'name' => $function);
+        }
+    }
+
+    /**
+     * Analyze the source code of the given PHP file
+     *
+     * @param  string Filename of the PHP file
+     * @return mixed
+     * @access public
+     */
+    function analyzeSourceCode($file)
+    {
+        if (!class_exists('PEAR_PackageFile_v2_Validator')) {
+            require_once 'PEAR/PackageFile/v2/Validator.php';
+        }
+
+        $a = new PEAR_PackageFile_v2_Validator;
+        return $a->analyzeSourceCode($file);
+    }
+
+    function detectDependencies($any, $status_callback = null)
+    {
+        if (!function_exists("token_get_all")) {
+            return false;
+        }
+
+        if (PEAR::isError($info = $this->infoFromAny($any))) {
+            return $this->raiseError($info);
+        }
+
+        if (!is_array($info)) {
+            return false;
+        }
+
+        $deps = array();
+        $used_c = $decl_c = $decl_f = $decl_m = array();
+        foreach ($info['filelist'] as $file => $fa) {
+            $tmp = $this->analyzeSourceCode($file);
+            $used_c = @array_merge($used_c, $tmp['used_classes']);
+            $decl_c = @array_merge($decl_c, $tmp['declared_classes']);
+            $decl_f = @array_merge($decl_f, $tmp['declared_functions']);
+            $decl_m = @array_merge($decl_m, $tmp['declared_methods']);
+            $inheri = @array_merge($inheri, $tmp['inheritance']);
+        }
+
+        $used_c = array_unique($used_c);
+        $decl_c = array_unique($decl_c);
+        $undecl_c = array_diff($used_c, $decl_c);
+
+        return array('used_classes' => $used_c,
+                     'declared_classes' => $decl_c,
+                     'declared_methods' => $decl_m,
+                     'declared_functions' => $decl_f,
+                     'undeclared_classes' => $undecl_c,
+                     'inheritance' => $inheri,
+                     );
+    }
+
+    /**
+     * Download a file through HTTP.  Considers suggested file name in
+     * Content-disposition: header and can run a callback function for
+     * different events.  The callback will be called with two
+     * parameters: the callback type, and parameters.  The implemented
+     * callback types are:
+     *
+     *  'setup'       called at the very beginning, parameter is a UI object
+     *                that should be used for all output
+     *  'message'     the parameter is a string with an informational message
+     *  'saveas'      may be used to save with a different file name, the
+     *                parameter is the filename that is about to be used.
+     *                If a 'saveas' callback returns a non-empty string,
+     *                that file name will be used as the filename instead.
+     *                Note that $save_dir will not be affected by this, only
+     *                the basename of the file.
+     *  'start'       download is starting, parameter is number of bytes
+     *                that are expected, or -1 if unknown
+     *  'bytesread'   parameter is the number of bytes read so far
+     *  'done'        download is complete, parameter is the total number
+     *                of bytes read
+     *  'connfailed'  if the TCP connection fails, this callback is called
+     *                with array(host,port,errno,errmsg)
+     *  'writefailed' if writing to disk fails, this callback is called
+     *                with array(destfile,errmsg)
+     *
+     * If an HTTP proxy has been configured (http_proxy PEAR_Config
+     * setting), the proxy will be used.
+     *
+     * @param string  $url       the URL to download
+     * @param object  $ui        PEAR_Frontend_* instance
+     * @param object  $config    PEAR_Config instance
+     * @param string  $save_dir  (optional) directory to save file in
+     * @param mixed   $callback  (optional) function/method to call for status
+     *                           updates
+     *
+     * @return string  Returns the full path of the downloaded file or a PEAR
+     *                 error on failure.  If the error is caused by
+     *                 socket-related errors, the error object will
+     *                 have the fsockopen error code available through
+     *                 getCode().
+     *
+     * @access public
+     * @deprecated in favor of PEAR_Downloader::downloadHttp()
+     */
+    function downloadHttp($url, &$ui, $save_dir = '.', $callback = null)
+    {
+        if (!class_exists('PEAR_Downloader')) {
+            require_once 'PEAR/Downloader.php';
+        }
+        return PEAR_Downloader::downloadHttp($url, $ui, $save_dir, $callback);
+    }
+}
+
+require_once 'PEAR/Config.php';
+require_once 'PEAR/PackageFile.php';
\ No newline at end of file
diff --git a/lib/php/PEAR/Config.php b/lib/php/PEAR/Config.php
new file mode 100644
index 00000000..f47f3c08
--- /dev/null
+++ b/lib/php/PEAR/Config.php
@@ -0,0 +1,2097 @@
+<?php
+/**
+ * PEAR_Config, customized configuration handling for the PEAR Installer
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Config.php 286480 2009-07-29 02:50:02Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * Required for error handling
+ */
+require_once 'PEAR.php';
+require_once 'PEAR/Registry.php';
+require_once 'PEAR/Installer/Role.php';
+require_once 'System.php';
+
+/**
+ * Last created PEAR_Config instance.
+ * @var object
+ */
+$GLOBALS['_PEAR_Config_instance'] = null;
+if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) {
+    $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear';
+} else {
+    $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR;
+}
+
+// Below we define constants with default values for all configuration
+// parameters except username/password.  All of them can have their
+// defaults set through environment variables.  The reason we use the
+// PHP_ prefix is for some security, PHP protects environment
+// variables starting with PHP_*.
+
+// default channel and preferred mirror is based on whether we are invoked through
+// the "pear" or the "pecl" command
+if (!defined('PEAR_RUNTYPE')) {
+    define('PEAR_RUNTYPE', 'pear');
+}
+
+if (PEAR_RUNTYPE == 'pear') {
+    define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net');
+} else {
+    define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net');
+}
+
+if (getenv('PHP_PEAR_SYSCONF_DIR')) {
+    define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR'));
+} elseif (getenv('SystemRoot')) {
+    define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot'));
+} else {
+    define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR);
+}
+
+// Default for master_server
+if (getenv('PHP_PEAR_MASTER_SERVER')) {
+    define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net');
+}
+
+// Default for http_proxy
+if (getenv('PHP_PEAR_HTTP_PROXY')) {
+    define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY'));
+} elseif (getenv('http_proxy')) {
+    define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', '');
+}
+
+// Default for php_dir
+if (getenv('PHP_PEAR_INSTALL_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR'));
+} else {
+    if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) {
+        define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
+    } else {
+        define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
+    }
+}
+
+// Default for ext_dir
+if (getenv('PHP_PEAR_EXTENSION_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR'));
+} else {
+    if (ini_get('extension_dir')) {
+        define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir'));
+    } elseif (defined('PEAR_EXTENSION_DIR') &&
+              file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) {
+        define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR);
+    } elseif (defined('PHP_EXTENSION_DIR')) {
+        define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR);
+    } else {
+        define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.');
+    }
+}
+
+// Default for doc_dir
+if (getenv('PHP_PEAR_DOC_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_DOC_DIR',
+           $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs');
+}
+
+// Default for bin_dir
+if (getenv('PHP_PEAR_BIN_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR);
+}
+
+// Default for data_dir
+if (getenv('PHP_PEAR_DATA_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_DATA_DIR',
+           $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data');
+}
+
+// Default for cfg_dir
+if (getenv('PHP_PEAR_CFG_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_CFG_DIR',
+           $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg');
+}
+
+// Default for www_dir
+if (getenv('PHP_PEAR_WWW_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_WWW_DIR',
+           $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www');
+}
+
+// Default for test_dir
+if (getenv('PHP_PEAR_TEST_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_TEST_DIR',
+           $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests');
+}
+
+// Default for temp_dir
+if (getenv('PHP_PEAR_TEMP_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_TEMP_DIR',
+           System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
+           DIRECTORY_SEPARATOR . 'temp');
+}
+
+// Default for cache_dir
+if (getenv('PHP_PEAR_CACHE_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_CACHE_DIR',
+           System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
+           DIRECTORY_SEPARATOR . 'cache');
+}
+
+// Default for download_dir
+if (getenv('PHP_PEAR_DOWNLOAD_DIR')) {
+    define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR',
+           System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' .
+           DIRECTORY_SEPARATOR . 'download');
+}
+
+// Default for php_bin
+if (getenv('PHP_PEAR_PHP_BIN')) {
+    define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR.
+           DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : ''));
+}
+
+// Default for verbose
+if (getenv('PHP_PEAR_VERBOSE')) {
+    define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_VERBOSE', 1);
+}
+
+// Default for preferred_state
+if (getenv('PHP_PEAR_PREFERRED_STATE')) {
+    define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable');
+}
+
+// Default for umask
+if (getenv('PHP_PEAR_UMASK')) {
+    define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask()));
+}
+
+// Default for cache_ttl
+if (getenv('PHP_PEAR_CACHE_TTL')) {
+    define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600);
+}
+
+// Default for sig_type
+if (getenv('PHP_PEAR_SIG_TYPE')) {
+    define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg');
+}
+
+// Default for sig_bin
+if (getenv('PHP_PEAR_SIG_BIN')) {
+    define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_SIG_BIN',
+           System::which(
+               'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg'));
+}
+
+// Default for sig_keydir
+if (getenv('PHP_PEAR_SIG_KEYDIR')) {
+    define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR'));
+} else {
+    define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR',
+           PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys');
+}
+
+/**
+ * This is a class for storing configuration data, keeping track of
+ * which are system-defined, user-defined or defaulted.
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Config extends PEAR
+{
+    /**
+     * Array of config files used.
+     *
+     * @var array layer => config file
+     */
+    var $files = array(
+        'system' => '',
+        'user' => '',
+        );
+
+    var $layers = array();
+
+    /**
+     * Configuration data, two-dimensional array where the first
+     * dimension is the config layer ('user', 'system' and 'default'),
+     * and the second dimension is keyname => value.
+     *
+     * The order in the first dimension is important!  Earlier
+     * layers will shadow later ones when a config value is
+     * requested (if a 'user' value exists, it will be returned first,
+     * then 'system' and finally 'default').
+     *
+     * @var array layer => array(keyname => value, ...)
+     */
+    var $configuration = array(
+        'user' => array(),
+        'system' => array(),
+        'default' => array(),
+        );
+
+    /**
+     * Configuration values that can be set for a channel
+     *
+     * All other configuration values can only have a global value
+     * @var array
+     * @access private
+     */
+    var $_channelConfigInfo = array(
+        'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir',
+        'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username',
+        'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini'
+        );
+
+    /**
+     * Channels that can be accessed
+     * @see setChannels()
+     * @var array
+     * @access private
+     */
+    var $_channels = array('pear.php.net', 'pecl.php.net', '__uri');
+
+    /**
+     * This variable is used to control the directory values returned
+     * @see setInstallRoot();
+     * @var string|false
+     * @access private
+     */
+    var $_installRoot = false;
+
+    /**
+     * If requested, this will always refer to the registry
+     * contained in php_dir
+     * @var PEAR_Registry
+     */
+    var $_registry = array();
+
+    /**
+     * @var array
+     * @access private
+     */
+    var $_regInitialized = array();
+
+    /**
+     * @var bool
+     * @access private
+     */
+    var $_noRegistry = false;
+
+    /**
+     * amount of errors found while parsing config
+     * @var integer
+     * @access private
+     */
+    var $_errorsFound = 0;
+    var $_lastError = null;
+
+    /**
+     * Information about the configuration data.  Stores the type,
+     * default value and a documentation string for each configuration
+     * value.
+     *
+     * @var array layer => array(infotype => value, ...)
+     */
+    var $configuration_info = array(
+        // Channels/Internet Access
+        'default_channel' => array(
+            'type' => 'string',
+            'default' => PEAR_CONFIG_DEFAULT_CHANNEL,
+            'doc' => 'the default channel to use for all non explicit commands',
+            'prompt' => 'Default Channel',
+            'group' => 'Internet Access',
+            ),
+        'preferred_mirror' => array(
+            'type' => 'string',
+            'default' => PEAR_CONFIG_DEFAULT_CHANNEL,
+            'doc' => 'the default server or mirror to use for channel actions',
+            'prompt' => 'Default Channel Mirror',
+            'group' => 'Internet Access',
+            ),
+        'remote_config' => array(
+            'type' => 'password',
+            'default' => '',
+            'doc' => 'ftp url of remote configuration file to use for synchronized install',
+            'prompt' => 'Remote Configuration File',
+            'group' => 'Internet Access',
+            ),
+        'auto_discover' => array(
+            'type' => 'integer',
+            'default' => 0,
+            'doc' => 'whether to automatically discover new channels',
+            'prompt' => 'Auto-discover new Channels',
+            'group' => 'Internet Access',
+            ),
+        // Internet Access
+        'master_server' => array(
+            'type' => 'string',
+            'default' => 'pear.php.net',
+            'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]',
+            'prompt' => 'PEAR server [DEPRECATED]',
+            'group' => 'Internet Access',
+            ),
+        'http_proxy' => array(
+            'type' => 'string',
+            'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY,
+            'doc' => 'HTTP proxy (host:port) to use when downloading packages',
+            'prompt' => 'HTTP Proxy Server Address',
+            'group' => 'Internet Access',
+            ),
+        // File Locations
+        'php_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_PHP_DIR,
+            'doc' => 'directory where .php files are installed',
+            'prompt' => 'PEAR directory',
+            'group' => 'File Locations',
+            ),
+        'ext_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_EXT_DIR,
+            'doc' => 'directory where loadable extensions are installed',
+            'prompt' => 'PHP extension directory',
+            'group' => 'File Locations',
+            ),
+        'doc_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_DOC_DIR,
+            'doc' => 'directory where documentation is installed',
+            'prompt' => 'PEAR documentation directory',
+            'group' => 'File Locations',
+            ),
+        'bin_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_BIN_DIR,
+            'doc' => 'directory where executables are installed',
+            'prompt' => 'PEAR executables directory',
+            'group' => 'File Locations',
+            ),
+        'data_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_DATA_DIR,
+            'doc' => 'directory where data files are installed',
+            'prompt' => 'PEAR data directory',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'cfg_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_CFG_DIR,
+            'doc' => 'directory where modifiable configuration files are installed',
+            'prompt' => 'PEAR configuration file directory',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'www_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_WWW_DIR,
+            'doc' => 'directory where www frontend files (html/js) are installed',
+            'prompt' => 'PEAR www files directory',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'test_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_TEST_DIR,
+            'doc' => 'directory where regression tests are installed',
+            'prompt' => 'PEAR test directory',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'cache_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR,
+            'doc' => 'directory which is used for web service cache',
+            'prompt' => 'PEAR Installer cache directory',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'temp_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR,
+            'doc' => 'directory which is used for all temp files',
+            'prompt' => 'PEAR Installer temp directory',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'download_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR,
+            'doc' => 'directory which is used for all downloaded files',
+            'prompt' => 'PEAR Installer download directory',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'php_bin' => array(
+            'type' => 'file',
+            'default' => PEAR_CONFIG_DEFAULT_PHP_BIN,
+            'doc' => 'PHP CLI/CGI binary for executing scripts',
+            'prompt' => 'PHP CLI/CGI binary',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'php_prefix' => array(
+            'type' => 'string',
+            'default' => '',
+            'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs',
+            'prompt' => '--program-prefix passed to PHP\'s ./configure',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'php_suffix' => array(
+            'type' => 'string',
+            'default' => '',
+            'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs',
+            'prompt' => '--program-suffix passed to PHP\'s ./configure',
+            'group' => 'File Locations (Advanced)',
+            ),
+        'php_ini' => array(
+            'type' => 'file',
+            'default' => '',
+            'doc' => 'location of php.ini in which to enable PECL extensions on install',
+            'prompt' => 'php.ini location',
+            'group' => 'File Locations (Advanced)',
+            ),
+        // Maintainers
+        'username' => array(
+            'type' => 'string',
+            'default' => '',
+            'doc' => '(maintainers) your PEAR account name',
+            'prompt' => 'PEAR username (for maintainers)',
+            'group' => 'Maintainers',
+            ),
+        'password' => array(
+            'type' => 'password',
+            'default' => '',
+            'doc' => '(maintainers) your PEAR account password',
+            'prompt' => 'PEAR password (for maintainers)',
+            'group' => 'Maintainers',
+            ),
+        // Advanced
+        'verbose' => array(
+            'type' => 'integer',
+            'default' => PEAR_CONFIG_DEFAULT_VERBOSE,
+            'doc' => 'verbosity level
+0: really quiet
+1: somewhat quiet
+2: verbose
+3: debug',
+            'prompt' => 'Debug Log Level',
+            'group' => 'Advanced',
+            ),
+        'preferred_state' => array(
+            'type' => 'set',
+            'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE,
+            'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified',
+            'valid_set' => array(
+                'stable', 'beta', 'alpha', 'devel', 'snapshot'),
+            'prompt' => 'Preferred Package State',
+            'group' => 'Advanced',
+            ),
+        'umask' => array(
+            'type' => 'mask',
+            'default' => PEAR_CONFIG_DEFAULT_UMASK,
+            'doc' => 'umask used when creating files (Unix-like systems only)',
+            'prompt' => 'Unix file mask',
+            'group' => 'Advanced',
+            ),
+        'cache_ttl' => array(
+            'type' => 'integer',
+            'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL,
+            'doc' => 'amount of secs where the local cache is used and not updated',
+            'prompt' => 'Cache TimeToLive',
+            'group' => 'Advanced',
+            ),
+        'sig_type' => array(
+            'type' => 'set',
+            'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE,
+            'doc' => 'which package signature mechanism to use',
+            'valid_set' => array('gpg'),
+            'prompt' => 'Package Signature Type',
+            'group' => 'Maintainers',
+            ),
+        'sig_bin' => array(
+            'type' => 'string',
+            'default' => PEAR_CONFIG_DEFAULT_SIG_BIN,
+            'doc' => 'which package signature mechanism to use',
+            'prompt' => 'Signature Handling Program',
+            'group' => 'Maintainers',
+            ),
+        'sig_keyid' => array(
+            'type' => 'string',
+            'default' => '',
+            'doc' => 'which key to use for signing with',
+            'prompt' => 'Signature Key Id',
+            'group' => 'Maintainers',
+            ),
+        'sig_keydir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR,
+            'doc' => 'directory where signature keys are located',
+            'prompt' => 'Signature Key Directory',
+            'group' => 'Maintainers',
+            ),
+        // __channels is reserved - used for channel-specific configuration
+        );
+
+    /**
+     * Constructor.
+     *
+     * @param string file to read user-defined options from
+     * @param string file to read system-wide defaults from
+     * @param bool   determines whether a registry object "follows"
+     *               the value of php_dir (is automatically created
+     *               and moved when php_dir is changed)
+     * @param bool   if true, fails if configuration files cannot be loaded
+     *
+     * @access public
+     *
+     * @see PEAR_Config::singleton
+     */
+    function PEAR_Config($user_file = '', $system_file = '', $ftp_file = false,
+                         $strict = true)
+    {
+        $this->PEAR();
+        PEAR_Installer_Role::initializeConfig($this);
+        $sl = DIRECTORY_SEPARATOR;
+        if (empty($user_file)) {
+            if (OS_WINDOWS) {
+                $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini';
+            } else {
+                $user_file = getenv('HOME') . $sl . '.pearrc';
+            }
+        }
+
+        if (empty($system_file)) {
+            $system_file = PEAR_CONFIG_SYSCONFDIR . $sl;
+            if (OS_WINDOWS) {
+                $system_file .= 'pearsys.ini';
+            } else {
+                $system_file .= 'pear.conf';
+            }
+        }
+
+        $this->layers = array_keys($this->configuration);
+        $this->files['user']   = $user_file;
+        $this->files['system'] = $system_file;
+        if ($user_file && file_exists($user_file)) {
+            $this->pushErrorHandling(PEAR_ERROR_RETURN);
+            $this->readConfigFile($user_file, 'user', $strict);
+            $this->popErrorHandling();
+            if ($this->_errorsFound > 0) {
+                return;
+            }
+        }
+
+        if ($system_file && @file_exists($system_file)) {
+            $this->mergeConfigFile($system_file, false, 'system', $strict);
+            if ($this->_errorsFound > 0) {
+                return;
+            }
+
+        }
+
+        if (!$ftp_file) {
+            $ftp_file = $this->get('remote_config');
+        }
+
+        if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) {
+            $this->readFTPConfigFile($ftp_file);
+        }
+
+        foreach ($this->configuration_info as $key => $info) {
+            $this->configuration['default'][$key] = $info['default'];
+        }
+
+        $this->_registry['default'] = &new PEAR_Registry($this->configuration['default']['php_dir']);
+        $this->_registry['default']->setConfig($this, false);
+        $this->_regInitialized['default'] = false;
+        //$GLOBALS['_PEAR_Config_instance'] = &$this;
+    }
+
+    /**
+     * Return the default locations of user and system configuration files
+     * @static
+     */
+    function getDefaultConfigFiles()
+    {
+        $sl = DIRECTORY_SEPARATOR;
+        if (OS_WINDOWS) {
+            return array(
+                'user'   => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini',
+                'system' =>  PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini'
+            );
+        }
+
+        return array(
+            'user'   => getenv('HOME') . $sl . '.pearrc',
+            'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf'
+        );
+    }
+
+    /**
+     * Static singleton method.  If you want to keep only one instance
+     * of this class in use, this method will give you a reference to
+     * the last created PEAR_Config object if one exists, or create a
+     * new object.
+     *
+     * @param string (optional) file to read user-defined options from
+     * @param string (optional) file to read system-wide defaults from
+     *
+     * @return object an existing or new PEAR_Config instance
+     *
+     * @access public
+     *
+     * @see PEAR_Config::PEAR_Config
+     */
+    function &singleton($user_file = '', $system_file = '', $strict = true)
+    {
+        if (is_object($GLOBALS['_PEAR_Config_instance'])) {
+            return $GLOBALS['_PEAR_Config_instance'];
+        }
+
+        $t_conf = &new PEAR_Config($user_file, $system_file, false, $strict);
+        if ($t_conf->_errorsFound > 0) {
+             return $t_conf->lastError;
+        }
+
+        $GLOBALS['_PEAR_Config_instance'] = &$t_conf;
+        return $GLOBALS['_PEAR_Config_instance'];
+    }
+
+    /**
+     * Determine whether any configuration files have been detected, and whether a
+     * registry object can be retrieved from this configuration.
+     * @return bool
+     * @since PEAR 1.4.0a1
+     */
+    function validConfiguration()
+    {
+        if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Reads configuration data from a file.  All existing values in
+     * the config layer are discarded and replaced with data from the
+     * file.
+     * @param string file to read from, if NULL or not specified, the
+     *               last-used file for the same layer (second param) is used
+     * @param string config layer to insert data into ('user' or 'system')
+     * @return bool TRUE on success or a PEAR error on failure
+     */
+    function readConfigFile($file = null, $layer = 'user', $strict = true)
+    {
+        if (empty($this->files[$layer])) {
+            return $this->raiseError("unknown config layer `$layer'");
+        }
+
+        if ($file === null) {
+            $file = $this->files[$layer];
+        }
+
+        $data = $this->_readConfigDataFrom($file);
+        if (PEAR::isError($data)) {
+            if (!$strict) {
+                return true;
+            }
+
+            $this->_errorsFound++;
+            $this->lastError = $data;
+
+            return $data;
+        }
+
+        $this->files[$layer] = $file;
+        $this->_decodeInput($data);
+        $this->configuration[$layer] = $data;
+        $this->_setupChannels();
+        if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
+            $this->_registry[$layer] = &new PEAR_Registry($phpdir);
+            $this->_registry[$layer]->setConfig($this, false);
+            $this->_regInitialized[$layer] = false;
+        } else {
+            unset($this->_registry[$layer]);
+        }
+        return true;
+    }
+
+    /**
+     * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini
+     * @return true|PEAR_Error
+     */
+    function readFTPConfigFile($path)
+    {
+        do { // poor man's try
+            if (!class_exists('PEAR_FTP')) {
+                if (!class_exists('PEAR_Common')) {
+                    require_once 'PEAR/Common.php';
+                }
+                if (PEAR_Common::isIncludeable('PEAR/FTP.php')) {
+                    require_once 'PEAR/FTP.php';
+                }
+            }
+
+            if (!class_exists('PEAR_FTP')) {
+                return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config');
+            }
+
+            $this->_ftp = &new PEAR_FTP;
+            $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN);
+            $e = $this->_ftp->init($path);
+            if (PEAR::isError($e)) {
+                $this->_ftp->popErrorHandling();
+                return $e;
+            }
+
+            $tmp = System::mktemp('-d');
+            PEAR_Common::addTempFile($tmp);
+            $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR .
+                'pear.ini', false, FTP_BINARY);
+            if (PEAR::isError($e)) {
+                $this->_ftp->popErrorHandling();
+                return $e;
+            }
+
+            PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini');
+            $this->_ftp->disconnect();
+            $this->_ftp->popErrorHandling();
+            $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini';
+            $e = $this->readConfigFile(null, 'ftp');
+            if (PEAR::isError($e)) {
+                return $e;
+            }
+
+            $fail = array();
+            foreach ($this->configuration_info as $key => $val) {
+                if (in_array($this->getGroup($key),
+                      array('File Locations', 'File Locations (Advanced)')) &&
+                      $this->getType($key) == 'directory') {
+                    // any directory configs must be set for this to work
+                    if (!isset($this->configuration['ftp'][$key])) {
+                        $fail[] = $key;
+                    }
+                }
+            }
+
+            if (!count($fail)) {
+                return true;
+            }
+
+            $fail = '"' . implode('", "', $fail) . '"';
+            unset($this->files['ftp']);
+            unset($this->configuration['ftp']);
+            return PEAR::raiseError('ERROR: Ftp configuration file must set all ' .
+                'directory configuration variables.  These variables were not set: ' .
+                $fail);
+        } while (false); // poor man's catch
+        unset($this->files['ftp']);
+        return PEAR::raiseError('no remote host specified');
+    }
+
+    /**
+     * Reads the existing configurations and creates the _channels array from it
+     */
+    function _setupChannels()
+    {
+        $set = array_flip(array_values($this->_channels));
+        foreach ($this->configuration as $layer => $data) {
+            $i = 1000;
+            if (isset($data['__channels']) && is_array($data['__channels'])) {
+                foreach ($data['__channels'] as $channel => $info) {
+                    $set[$channel] = $i++;
+                }
+            }
+        }
+        $this->_channels = array_values(array_flip($set));
+        $this->setChannels($this->_channels);
+    }
+
+    function deleteChannel($channel)
+    {
+        $ch = strtolower($channel);
+        foreach ($this->configuration as $layer => $data) {
+            if (isset($data['__channels']) && isset($data['__channels'][$ch])) {
+                unset($this->configuration[$layer]['__channels'][$ch]);
+            }
+        }
+
+        $this->_channels = array_flip($this->_channels);
+        unset($this->_channels[$ch]);
+        $this->_channels = array_flip($this->_channels);
+    }
+
+    /**
+     * Merges data into a config layer from a file.  Does the same
+     * thing as readConfigFile, except it does not replace all
+     * existing values in the config layer.
+     * @param string file to read from
+     * @param bool whether to overwrite existing data (default TRUE)
+     * @param string config layer to insert data into ('user' or 'system')
+     * @param string if true, errors are returned if file opening fails
+     * @return bool TRUE on success or a PEAR error on failure
+     */
+    function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true)
+    {
+        if (empty($this->files[$layer])) {
+            return $this->raiseError("unknown config layer `$layer'");
+        }
+
+        if ($file === null) {
+            $file = $this->files[$layer];
+        }
+
+        $data = $this->_readConfigDataFrom($file);
+        if (PEAR::isError($data)) {
+            if (!$strict) {
+                return true;
+            }
+
+            $this->_errorsFound++;
+            $this->lastError = $data;
+
+            return $data;
+        }
+
+        $this->_decodeInput($data);
+        if ($override) {
+            $this->configuration[$layer] =
+                PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data);
+        } else {
+            $this->configuration[$layer] =
+                PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]);
+        }
+
+        $this->_setupChannels();
+        if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
+            $this->_registry[$layer] = &new PEAR_Registry($phpdir);
+            $this->_registry[$layer]->setConfig($this, false);
+            $this->_regInitialized[$layer] = false;
+        } else {
+            unset($this->_registry[$layer]);
+        }
+        return true;
+    }
+
+    /**
+     * @param array
+     * @param array
+     * @return array
+     * @static
+     */
+    function arrayMergeRecursive($arr2, $arr1)
+    {
+        $ret = array();
+        foreach ($arr2 as $key => $data) {
+            if (!isset($arr1[$key])) {
+                $ret[$key] = $data;
+                unset($arr1[$key]);
+                continue;
+            }
+            if (is_array($data)) {
+                if (!is_array($arr1[$key])) {
+                    $ret[$key] = $arr1[$key];
+                    unset($arr1[$key]);
+                    continue;
+                }
+                $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]);
+                unset($arr1[$key]);
+            }
+        }
+
+        return array_merge($ret, $arr1);
+    }
+
+    /**
+     * Writes data into a config layer from a file.
+     *
+     * @param string|null file to read from, or null for default
+     * @param string config layer to insert data into ('user' or
+     *               'system')
+     * @param string|null data to write to config file or null for internal data [DEPRECATED]
+     * @return bool TRUE on success or a PEAR error on failure
+     */
+    function writeConfigFile($file = null, $layer = 'user', $data = null)
+    {
+        $this->_lazyChannelSetup($layer);
+        if ($layer == 'both' || $layer == 'all') {
+            foreach ($this->files as $type => $file) {
+                $err = $this->writeConfigFile($file, $type, $data);
+                if (PEAR::isError($err)) {
+                    return $err;
+                }
+            }
+            return true;
+        }
+
+        if (empty($this->files[$layer])) {
+            return $this->raiseError("unknown config file type `$layer'");
+        }
+
+        if ($file === null) {
+            $file = $this->files[$layer];
+        }
+
+        $data = ($data === null) ? $this->configuration[$layer] : $data;
+        $this->_encodeOutput($data);
+        $opt = array('-p', dirname($file));
+        if (!@System::mkDir($opt)) {
+            return $this->raiseError("could not create directory: " . dirname($file));
+        }
+
+        if (file_exists($file) && is_file($file) && !is_writeable($file)) {
+            return $this->raiseError("no write access to $file!");
+        }
+
+        $fp = @fopen($file, "w");
+        if (!$fp) {
+            return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)");
+        }
+
+        $contents = "#PEAR_Config 0.9\n" . serialize($data);
+        if (!@fwrite($fp, $contents)) {
+            return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)");
+        }
+        return true;
+    }
+
+    /**
+     * Reads configuration data from a file and returns the parsed data
+     * in an array.
+     *
+     * @param string file to read from
+     * @return array configuration data or a PEAR error on failure
+     * @access private
+     */
+    function _readConfigDataFrom($file)
+    {
+        $fp = false;
+        if (file_exists($file)) {
+            $fp = @fopen($file, "r");
+        }
+
+        if (!$fp) {
+            return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed");
+        }
+
+        $size = filesize($file);
+        $rt = get_magic_quotes_runtime();
+        set_magic_quotes_runtime(0);
+        fclose($fp);
+        $contents = file_get_contents($file);
+        if (empty($contents)) {
+            return $this->raiseError('Configuration file "' . $file . '" is empty');
+        }
+
+        set_magic_quotes_runtime($rt);
+
+        $version = false;
+        if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) {
+            $version = $matches[1];
+            $contents = substr($contents, strlen($matches[0]));
+        } else {
+            // Museum config file
+            if (substr($contents,0,2) == 'a:') {
+                $version = '0.1';
+            }
+        }
+
+        if ($version && version_compare("$version", '1', '<')) {
+            // no '@', it is possible that unserialize
+            // raises a notice but it seems to block IO to
+            // STDOUT if a '@' is used and a notice is raise
+            $data = unserialize($contents);
+
+            if (!is_array($data) && !$data) {
+                if ($contents == serialize(false)) {
+                    $data = array();
+                } else {
+                    $err = $this->raiseError("PEAR_Config: bad data in $file");
+                    return $err;
+                }
+            }
+            if (!is_array($data)) {
+                if (strlen(trim($contents)) > 0) {
+                    $error = "PEAR_Config: bad data in $file";
+                    $err = $this->raiseError($error);
+                    return $err;
+                }
+
+                $data = array();
+            }
+        // add parsing of newer formats here...
+        } else {
+            $err = $this->raiseError("$file: unknown version `$version'");
+            return $err;
+        }
+
+        return $data;
+    }
+
+    /**
+    * Gets the file used for storing the config for a layer
+    *
+    * @param string $layer 'user' or 'system'
+    */
+    function getConfFile($layer)
+    {
+        return $this->files[$layer];
+    }
+
+    /**
+     * @param string Configuration class name, used for detecting duplicate calls
+     * @param array information on a role as parsed from its xml file
+     * @return true|PEAR_Error
+     * @access private
+     */
+    function _addConfigVars($class, $vars)
+    {
+        static $called = array();
+        if (isset($called[$class])) {
+            return;
+        }
+
+        $called[$class] = 1;
+        if (count($vars) > 3) {
+            return $this->raiseError('Roles can only define 3 new config variables or less');
+        }
+
+        foreach ($vars as $name => $var) {
+            if (!is_array($var)) {
+                return $this->raiseError('Configuration information must be an array');
+            }
+
+            if (!isset($var['type'])) {
+                return $this->raiseError('Configuration information must contain a type');
+            } elseif (!in_array($var['type'],
+                    array('string', 'mask', 'password', 'directory', 'file', 'set'))) {
+                  return $this->raiseError(
+                      'Configuration type must be one of directory, file, string, ' .
+                      'mask, set, or password');
+            }
+            if (!isset($var['default'])) {
+                return $this->raiseError(
+                    'Configuration information must contain a default value ("default" index)');
+            }
+
+            if (is_array($var['default'])) {
+                $real_default = '';
+                foreach ($var['default'] as $config_var => $val) {
+                    if (strpos($config_var, 'text') === 0) {
+                        $real_default .= $val;
+                    } elseif (strpos($config_var, 'constant') === 0) {
+                        if (!defined($val)) {
+                            return $this->raiseError(
+                                'Unknown constant "' . $val . '" requested in ' .
+                                'default value for configuration variable "' .
+                                $name . '"');
+                        }
+
+                        $real_default .= constant($val);
+                    } elseif (isset($this->configuration_info[$config_var])) {
+                        $real_default .=
+                            $this->configuration_info[$config_var]['default'];
+                    } else {
+                        return $this->raiseError(
+                            'Unknown request for "' . $config_var . '" value in ' .
+                            'default value for configuration variable "' .
+                            $name . '"');
+                    }
+                }
+                $var['default'] = $real_default;
+            }
+
+            if ($var['type'] == 'integer') {
+                $var['default'] = (integer) $var['default'];
+            }
+
+            if (!isset($var['doc'])) {
+                return $this->raiseError(
+                    'Configuration information must contain a summary ("doc" index)');
+            }
+
+            if (!isset($var['prompt'])) {
+                return $this->raiseError(
+                    'Configuration information must contain a simple prompt ("prompt" index)');
+            }
+
+            if (!isset($var['group'])) {
+                return $this->raiseError(
+                    'Configuration information must contain a simple group ("group" index)');
+            }
+
+            if (isset($this->configuration_info[$name])) {
+                return $this->raiseError('Configuration variable "' . $name .
+                    '" already exists');
+            }
+
+            $this->configuration_info[$name] = $var;
+            // fix bug #7351: setting custom config variable in a channel fails
+            $this->_channelConfigInfo[] = $name;
+        }
+
+        return true;
+    }
+
+    /**
+     * Encodes/scrambles configuration data before writing to files.
+     * Currently, 'password' values will be base64-encoded as to avoid
+     * that people spot cleartext passwords by accident.
+     *
+     * @param array (reference) array to encode values in
+     * @return bool TRUE on success
+     * @access private
+     */
+    function _encodeOutput(&$data)
+    {
+        foreach ($data as $key => $value) {
+            if ($key == '__channels') {
+                foreach ($data['__channels'] as $channel => $blah) {
+                    $this->_encodeOutput($data['__channels'][$channel]);
+                }
+            }
+
+            if (!isset($this->configuration_info[$key])) {
+                continue;
+            }
+
+            $type = $this->configuration_info[$key]['type'];
+            switch ($type) {
+                // we base64-encode passwords so they are at least
+                // not shown in plain by accident
+                case 'password': {
+                    $data[$key] = base64_encode($data[$key]);
+                    break;
+                }
+                case 'mask': {
+                    $data[$key] = octdec($data[$key]);
+                    break;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Decodes/unscrambles configuration data after reading from files.
+     *
+     * @param array (reference) array to encode values in
+     * @return bool TRUE on success
+     * @access private
+     *
+     * @see PEAR_Config::_encodeOutput
+     */
+    function _decodeInput(&$data)
+    {
+        if (!is_array($data)) {
+            return true;
+        }
+
+        foreach ($data as $key => $value) {
+            if ($key == '__channels') {
+                foreach ($data['__channels'] as $channel => $blah) {
+                    $this->_decodeInput($data['__channels'][$channel]);
+                }
+            }
+
+            if (!isset($this->configuration_info[$key])) {
+                continue;
+            }
+
+            $type = $this->configuration_info[$key]['type'];
+            switch ($type) {
+                case 'password': {
+                    $data[$key] = base64_decode($data[$key]);
+                    break;
+                }
+                case 'mask': {
+                    $data[$key] = decoct($data[$key]);
+                    break;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Retrieve the default channel.
+     *
+     * On startup, channels are not initialized, so if the default channel is not
+     * pear.php.net, then initialize the config.
+     * @param string registry layer
+     * @return string|false
+     */
+    function getDefaultChannel($layer = null)
+    {
+        $ret = false;
+        if ($layer === null) {
+            foreach ($this->layers as $layer) {
+                if (isset($this->configuration[$layer]['default_channel'])) {
+                    $ret = $this->configuration[$layer]['default_channel'];
+                    break;
+                }
+            }
+        } elseif (isset($this->configuration[$layer]['default_channel'])) {
+            $ret = $this->configuration[$layer]['default_channel'];
+        }
+
+        if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') {
+            $ret = 'pecl.php.net';
+        }
+
+        if ($ret) {
+            if ($ret != 'pear.php.net') {
+                $this->_lazyChannelSetup();
+            }
+
+            return $ret;
+        }
+
+        return PEAR_CONFIG_DEFAULT_CHANNEL;
+    }
+
+    /**
+     * Returns a configuration value, prioritizing layers as per the
+     * layers property.
+     *
+     * @param string config key
+     * @return mixed the config value, or NULL if not found
+     * @access public
+     */
+    function get($key, $layer = null, $channel = false)
+    {
+        if (!isset($this->configuration_info[$key])) {
+            return null;
+        }
+
+        if ($key == '__channels') {
+            return null;
+        }
+
+        if ($key == 'default_channel') {
+            return $this->getDefaultChannel($layer);
+        }
+
+        if (!$channel) {
+            $channel = $this->getDefaultChannel();
+        } elseif ($channel != 'pear.php.net') {
+            $this->_lazyChannelSetup();
+        }
+        $channel = strtolower($channel);
+
+        $test = (in_array($key, $this->_channelConfigInfo)) ?
+            $this->_getChannelValue($key, $layer, $channel) :
+            null;
+        if ($test !== null) {
+            if ($this->_installRoot) {
+                if (in_array($this->getGroup($key),
+                      array('File Locations', 'File Locations (Advanced)')) &&
+                      $this->getType($key) == 'directory') {
+                    return $this->_prependPath($test, $this->_installRoot);
+                }
+            }
+            return $test;
+        }
+
+        if ($layer === null) {
+            foreach ($this->layers as $layer) {
+                if (isset($this->configuration[$layer][$key])) {
+                    $test = $this->configuration[$layer][$key];
+                    if ($this->_installRoot) {
+                        if (in_array($this->getGroup($key),
+                              array('File Locations', 'File Locations (Advanced)')) &&
+                              $this->getType($key) == 'directory') {
+                            return $this->_prependPath($test, $this->_installRoot);
+                        }
+                    }
+
+                    if ($key == 'preferred_mirror') {
+                        $reg = &$this->getRegistry();
+                        if (is_object($reg)) {
+                            $chan = &$reg->getChannel($channel);
+                            if (PEAR::isError($chan)) {
+                                return $channel;
+                            }
+
+                            if (!$chan->getMirror($test) && $chan->getName() != $test) {
+                                return $channel; // mirror does not exist
+                            }
+                        }
+                    }
+                    return $test;
+                }
+            }
+        } elseif (isset($this->configuration[$layer][$key])) {
+            $test = $this->configuration[$layer][$key];
+            if ($this->_installRoot) {
+                if (in_array($this->getGroup($key),
+                      array('File Locations', 'File Locations (Advanced)')) &&
+                      $this->getType($key) == 'directory') {
+                    return $this->_prependPath($test, $this->_installRoot);
+                }
+            }
+
+            if ($key == 'preferred_mirror') {
+                $reg = &$this->getRegistry();
+                if (is_object($reg)) {
+                    $chan = &$reg->getChannel($channel);
+                    if (PEAR::isError($chan)) {
+                        return $channel;
+                    }
+
+                    if (!$chan->getMirror($test) && $chan->getName() != $test) {
+                        return $channel; // mirror does not exist
+                    }
+                }
+            }
+
+            return $test;
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns a channel-specific configuration value, prioritizing layers as per the
+     * layers property.
+     *
+     * @param string config key
+     * @return mixed the config value, or NULL if not found
+     * @access private
+     */
+    function _getChannelValue($key, $layer, $channel)
+    {
+        if ($key == '__channels' || $channel == 'pear.php.net') {
+            return null;
+        }
+
+        $ret = null;
+        if ($layer === null) {
+            foreach ($this->layers as $ilayer) {
+                if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) {
+                    $ret = $this->configuration[$ilayer]['__channels'][$channel][$key];
+                    break;
+                }
+            }
+        } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
+            $ret = $this->configuration[$layer]['__channels'][$channel][$key];
+        }
+
+        if ($key != 'preferred_mirror') {
+            return $ret;
+        }
+
+
+        if ($ret !== null) {
+            $reg = &$this->getRegistry($layer);
+            if (is_object($reg)) {
+                $chan = &$reg->getChannel($channel);
+                if (PEAR::isError($chan)) {
+                    return $channel;
+                }
+
+                if (!$chan->getMirror($ret) && $chan->getName() != $ret) {
+                    return $channel; // mirror does not exist
+                }
+            }
+
+            return $ret;
+        }
+
+        if ($channel != $this->getDefaultChannel($layer)) {
+            return $channel; // we must use the channel name as the preferred mirror
+                             // if the user has not chosen an alternate
+        }
+
+        return $this->getDefaultChannel($layer);
+    }
+
+    /**
+     * Set a config value in a specific layer (defaults to 'user').
+     * Enforces the types defined in the configuration_info array.  An
+     * integer config variable will be cast to int, and a set config
+     * variable will be validated against its legal values.
+     *
+     * @param string config key
+     * @param string config value
+     * @param string (optional) config layer
+     * @param string channel to set this value for, or null for global value
+     * @return bool TRUE on success, FALSE on failure
+     */
+    function set($key, $value, $layer = 'user', $channel = false)
+    {
+        if ($key == '__channels') {
+            return false;
+        }
+
+        if (!isset($this->configuration[$layer])) {
+            return false;
+        }
+
+        if ($key == 'default_channel') {
+            // can only set this value globally
+            $channel = 'pear.php.net';
+            if ($value != 'pear.php.net') {
+                $this->_lazyChannelSetup($layer);
+            }
+        }
+
+        if ($key == 'preferred_mirror') {
+            if ($channel == '__uri') {
+                return false; // can't set the __uri pseudo-channel's mirror
+            }
+
+            $reg = &$this->getRegistry($layer);
+            if (is_object($reg)) {
+                $chan = &$reg->getChannel($channel ? $channel : 'pear.php.net');
+                if (PEAR::isError($chan)) {
+                    return false;
+                }
+
+                if (!$chan->getMirror($value) && $chan->getName() != $value) {
+                    return false; // mirror does not exist
+                }
+            }
+        }
+
+        if (!isset($this->configuration_info[$key])) {
+            return false;
+        }
+
+        extract($this->configuration_info[$key]);
+        switch ($type) {
+            case 'integer':
+                $value = (int)$value;
+                break;
+            case 'set': {
+                // If a valid_set is specified, require the value to
+                // be in the set.  If there is no valid_set, accept
+                // any value.
+                if ($valid_set) {
+                    reset($valid_set);
+                    if ((key($valid_set) === 0 && !in_array($value, $valid_set)) ||
+                        (key($valid_set) !== 0 && empty($valid_set[$value])))
+                    {
+                        return false;
+                    }
+                }
+                break;
+            }
+        }
+
+        if (!$channel) {
+            $channel = $this->get('default_channel', null, 'pear.php.net');
+        }
+
+        if (!in_array($channel, $this->_channels)) {
+            $this->_lazyChannelSetup($layer);
+            $reg = &$this->getRegistry($layer);
+            if ($reg) {
+                $channel = $reg->channelName($channel);
+            }
+
+            if (!in_array($channel, $this->_channels)) {
+                return false;
+            }
+        }
+
+        if ($channel != 'pear.php.net') {
+            if (in_array($key, $this->_channelConfigInfo)) {
+                $this->configuration[$layer]['__channels'][$channel][$key] = $value;
+                return true;
+            }
+
+            return false;
+        }
+
+        if ($key == 'default_channel') {
+            if (!isset($reg)) {
+                $reg = &$this->getRegistry($layer);
+                if (!$reg) {
+                    $reg = &$this->getRegistry();
+                }
+            }
+
+            if ($reg) {
+                $value = $reg->channelName($value);
+            }
+
+            if (!$value) {
+                return false;
+            }
+        }
+
+        $this->configuration[$layer][$key] = $value;
+        if ($key == 'php_dir' && !$this->_noRegistry) {
+            if (!isset($this->_registry[$layer]) ||
+                  $value != $this->_registry[$layer]->install_dir) {
+                $this->_registry[$layer] = &new PEAR_Registry($value);
+                $this->_regInitialized[$layer] = false;
+                $this->_registry[$layer]->setConfig($this, false);
+            }
+        }
+
+        return true;
+    }
+
+    function _lazyChannelSetup($uselayer = false)
+    {
+        if ($this->_noRegistry) {
+            return;
+        }
+
+        $merge = false;
+        foreach ($this->_registry as $layer => $p) {
+            if ($uselayer && $uselayer != $layer) {
+                continue;
+            }
+
+            if (!$this->_regInitialized[$layer]) {
+                if ($layer == 'default' && isset($this->_registry['user']) ||
+                      isset($this->_registry['system'])) {
+                    // only use the default registry if there are no alternatives
+                    continue;
+                }
+
+                if (!is_object($this->_registry[$layer])) {
+                    if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) {
+                        $this->_registry[$layer] = &new PEAR_Registry($phpdir);
+                        $this->_registry[$layer]->setConfig($this, false);
+                        $this->_regInitialized[$layer] = false;
+                    } else {
+                        unset($this->_registry[$layer]);
+                        return;
+                    }
+                }
+
+                $this->setChannels($this->_registry[$layer]->listChannels(), $merge);
+                $this->_regInitialized[$layer] = true;
+                $merge = true;
+            }
+        }
+    }
+
+    /**
+     * Set the list of channels.
+     *
+     * This should be set via a call to {@link PEAR_Registry::listChannels()}
+     * @param array
+     * @param bool
+     * @return bool success of operation
+     */
+    function setChannels($channels, $merge = false)
+    {
+        if (!is_array($channels)) {
+            return false;
+        }
+
+        if ($merge) {
+            $this->_channels = array_merge($this->_channels, $channels);
+        } else {
+            $this->_channels = $channels;
+        }
+
+        foreach ($channels as $channel) {
+            $channel = strtolower($channel);
+            if ($channel == 'pear.php.net') {
+                continue;
+            }
+
+            foreach ($this->layers as $layer) {
+                if (!isset($this->configuration[$layer]['__channels'])) {
+                    $this->configuration[$layer]['__channels'] = array();
+                }
+                if (!isset($this->configuration[$layer]['__channels'][$channel])
+                      || !is_array($this->configuration[$layer]['__channels'][$channel])) {
+                    $this->configuration[$layer]['__channels'][$channel] = array();
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Get the type of a config value.
+     *
+     * @param string  config key
+     *
+     * @return string type, one of "string", "integer", "file",
+     * "directory", "set" or "password".
+     *
+     * @access public
+     *
+     */
+    function getType($key)
+    {
+        if (isset($this->configuration_info[$key])) {
+            return $this->configuration_info[$key]['type'];
+        }
+        return false;
+    }
+
+    /**
+     * Get the documentation for a config value.
+     *
+     * @param string  config key
+     * @return string documentation string
+     *
+     * @access public
+     *
+     */
+    function getDocs($key)
+    {
+        if (isset($this->configuration_info[$key])) {
+            return $this->configuration_info[$key]['doc'];
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the short documentation for a config value.
+     *
+     * @param string  config key
+     * @return string short documentation string
+     *
+     * @access public
+     *
+     */
+    function getPrompt($key)
+    {
+        if (isset($this->configuration_info[$key])) {
+            return $this->configuration_info[$key]['prompt'];
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the parameter group for a config key.
+     *
+     * @param string  config key
+     * @return string parameter group
+     *
+     * @access public
+     *
+     */
+    function getGroup($key)
+    {
+        if (isset($this->configuration_info[$key])) {
+            return $this->configuration_info[$key]['group'];
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the list of parameter groups.
+     *
+     * @return array list of parameter groups
+     *
+     * @access public
+     *
+     */
+    function getGroups()
+    {
+        $tmp = array();
+        foreach ($this->configuration_info as $key => $info) {
+            $tmp[$info['group']] = 1;
+        }
+
+        return array_keys($tmp);
+    }
+
+    /**
+     * Get the list of the parameters in a group.
+     *
+     * @param string $group parameter group
+     * @return array list of parameters in $group
+     *
+     * @access public
+     *
+     */
+    function getGroupKeys($group)
+    {
+        $keys = array();
+        foreach ($this->configuration_info as $key => $info) {
+            if ($info['group'] == $group) {
+                $keys[] = $key;
+            }
+        }
+
+        return $keys;
+    }
+
+    /**
+     * Get the list of allowed set values for a config value.  Returns
+     * NULL for config values that are not sets.
+     *
+     * @param string  config key
+     * @return array enumerated array of set values, or NULL if the
+     *               config key is unknown or not a set
+     *
+     * @access public
+     *
+     */
+    function getSetValues($key)
+    {
+        if (isset($this->configuration_info[$key]) &&
+            isset($this->configuration_info[$key]['type']) &&
+            $this->configuration_info[$key]['type'] == 'set')
+        {
+            $valid_set = $this->configuration_info[$key]['valid_set'];
+            reset($valid_set);
+            if (key($valid_set) === 0) {
+                return $valid_set;
+            }
+
+            return array_keys($valid_set);
+        }
+
+        return null;
+    }
+
+    /**
+     * Get all the current config keys.
+     *
+     * @return array simple array of config keys
+     *
+     * @access public
+     */
+    function getKeys()
+    {
+        $keys = array();
+        foreach ($this->layers as $layer) {
+            $test = $this->configuration[$layer];
+            if (isset($test['__channels'])) {
+                foreach ($test['__channels'] as $channel => $configs) {
+                    $keys = array_merge($keys, $configs);
+                }
+            }
+
+            unset($test['__channels']);
+            $keys = array_merge($keys, $test);
+
+        }
+        return array_keys($keys);
+    }
+
+    /**
+     * Remove the a config key from a specific config layer.
+     *
+     * @param string config key
+     * @param string (optional) config layer
+     * @param string (optional) channel (defaults to default channel)
+     * @return bool TRUE on success, FALSE on failure
+     *
+     * @access public
+     */
+    function remove($key, $layer = 'user', $channel = null)
+    {
+        if ($channel === null) {
+            $channel = $this->getDefaultChannel();
+        }
+
+        if ($channel !== 'pear.php.net') {
+            if (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
+                unset($this->configuration[$layer]['__channels'][$channel][$key]);
+                return true;
+            }
+        }
+
+        if (isset($this->configuration[$layer][$key])) {
+            unset($this->configuration[$layer][$key]);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Temporarily remove an entire config layer.  USE WITH CARE!
+     *
+     * @param string config key
+     * @param string (optional) config layer
+     * @return bool TRUE on success, FALSE on failure
+     *
+     * @access public
+     */
+    function removeLayer($layer)
+    {
+        if (isset($this->configuration[$layer])) {
+            $this->configuration[$layer] = array();
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Stores configuration data in a layer.
+     *
+     * @param string config layer to store
+     * @return bool TRUE on success, or PEAR error on failure
+     *
+     * @access public
+     */
+    function store($layer = 'user', $data = null)
+    {
+        return $this->writeConfigFile(null, $layer, $data);
+    }
+
+    /**
+     * Tells what config layer that gets to define a key.
+     *
+     * @param string config key
+     * @param boolean return the defining channel
+     *
+     * @return string|array the config layer, or an empty string if not found.
+     *
+     *         if $returnchannel, the return is an array array('layer' => layername,
+     *         'channel' => channelname), or an empty string if not found
+     *
+     * @access public
+     */
+    function definedBy($key, $returnchannel = false)
+    {
+        foreach ($this->layers as $layer) {
+            $channel = $this->getDefaultChannel();
+            if ($channel !== 'pear.php.net') {
+                if (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
+                    if ($returnchannel) {
+                        return array('layer' => $layer, 'channel' => $channel);
+                    }
+                    return $layer;
+                }
+            }
+
+            if (isset($this->configuration[$layer][$key])) {
+                if ($returnchannel) {
+                    return array('layer' => $layer, 'channel' => 'pear.php.net');
+                }
+                return $layer;
+            }
+        }
+
+        return '';
+    }
+
+    /**
+     * Tells whether a given key exists as a config value.
+     *
+     * @param string config key
+     * @return bool whether <config key> exists in this object
+     *
+     * @access public
+     */
+    function isDefined($key)
+    {
+        foreach ($this->layers as $layer) {
+            if (isset($this->configuration[$layer][$key])) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Tells whether a given config layer exists.
+     *
+     * @param string config layer
+     * @return bool whether <config layer> exists in this object
+     *
+     * @access public
+     */
+    function isDefinedLayer($layer)
+    {
+        return isset($this->configuration[$layer]);
+    }
+
+    /**
+     * Returns the layers defined (except the 'default' one)
+     *
+     * @return array of the defined layers
+     */
+    function getLayers()
+    {
+        $cf = $this->configuration;
+        unset($cf['default']);
+        return array_keys($cf);
+    }
+
+    function apiVersion()
+    {
+        return '1.1';
+    }
+
+    /**
+     * @return PEAR_Registry
+     */
+    function &getRegistry($use = null)
+    {
+        $layer = $use === null ? 'user' : $use;
+        if (isset($this->_registry[$layer])) {
+            return $this->_registry[$layer];
+        } elseif ($use === null && isset($this->_registry['system'])) {
+            return $this->_registry['system'];
+        } elseif ($use === null && isset($this->_registry['default'])) {
+            return $this->_registry['default'];
+        } elseif ($use) {
+            $a = false;
+            return $a;
+        }
+
+        // only go here if null was passed in
+        echo "CRITICAL ERROR: Registry could not be initialized from any value";
+        exit(1);
+    }
+
+    /**
+     * This is to allow customization like the use of installroot
+     * @param PEAR_Registry
+     * @return bool
+     */
+    function setRegistry(&$reg, $layer = 'user')
+    {
+        if ($this->_noRegistry) {
+            return false;
+        }
+
+        if (!in_array($layer, array('user', 'system'))) {
+            return false;
+        }
+
+        $this->_registry[$layer] = &$reg;
+        if (is_object($reg)) {
+            $this->_registry[$layer]->setConfig($this, false);
+        }
+
+        return true;
+    }
+
+    function noRegistry()
+    {
+        $this->_noRegistry = true;
+    }
+
+    /**
+     * @return PEAR_REST
+     */
+    function &getREST($version, $options = array())
+    {
+        $version = str_replace('.', '', $version);
+        if (!class_exists($class = 'PEAR_REST_' . $version)) {
+            require_once 'PEAR/REST/' . $version . '.php';
+        }
+
+        $remote = &new $class($this, $options);
+        return $remote;
+    }
+
+    /**
+     * The ftp server is set in {@link readFTPConfigFile()}.  It exists only if a
+     * remote configuration file has been specified
+     * @return PEAR_FTP|false
+     */
+    function &getFTP()
+    {
+        if (isset($this->_ftp)) {
+            return $this->_ftp;
+        }
+
+        $a = false;
+        return $a;
+    }
+
+    function _prependPath($path, $prepend)
+    {
+        if (strlen($prepend) > 0) {
+            if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) {
+                if (preg_match('/^[a-z]:/i', $prepend)) {
+                    $prepend = substr($prepend, 2);
+                } elseif ($prepend{0} != '\\') {
+                    $prepend = "\\$prepend";
+                }
+                $path = substr($path, 0, 2) . $prepend . substr($path, 2);
+            } else {
+                $path = $prepend . $path;
+            }
+        }
+        return $path;
+    }
+
+    /**
+     * @param string|false installation directory to prepend to all _dir variables, or false to
+     *                     disable
+     */
+    function setInstallRoot($root)
+    {
+        if (substr($root, -1) == DIRECTORY_SEPARATOR) {
+            $root = substr($root, 0, -1);
+        }
+        $old = $this->_installRoot;
+        $this->_installRoot = $root;
+        if (($old != $root) && !$this->_noRegistry) {
+            foreach (array_keys($this->_registry) as $layer) {
+                if ($layer == 'ftp' || !isset($this->_registry[$layer])) {
+                    continue;
+                }
+                $this->_registry[$layer] =
+                    &new PEAR_Registry($this->get('php_dir', $layer, 'pear.php.net'));
+                $this->_registry[$layer]->setConfig($this, false);
+                $this->_regInitialized[$layer] = false;
+            }
+        }
+    }
+}
diff --git a/lib/php/PEAR/Dependency2.php b/lib/php/PEAR/Dependency2.php
new file mode 100644
index 00000000..ce51ed19
--- /dev/null
+++ b/lib/php/PEAR/Dependency2.php
@@ -0,0 +1,1358 @@
+<?php
+/**
+ * PEAR_Dependency2, advanced dependency validation
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Dependency2.php 286494 2009-07-29 06:57:11Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * Required for the PEAR_VALIDATE_* constants
+ */
+require_once 'PEAR/Validate.php';
+
+/**
+ * Dependency check for PEAR packages
+ *
+ * This class handles both version 1.0 and 2.0 dependencies
+ * WARNING: *any* changes to this class must be duplicated in the
+ * test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc,
+ * or unit tests will not actually validate the changes
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Dependency2
+{
+    /**
+     * One of the PEAR_VALIDATE_* states
+     * @see PEAR_VALIDATE_NORMAL
+     * @var integer
+     */
+    var $_state;
+
+    /**
+     * Command-line options to install/upgrade/uninstall commands
+     * @param array
+     */
+    var $_options;
+
+    /**
+     * @var OS_Guess
+     */
+    var $_os;
+
+    /**
+     * @var PEAR_Registry
+     */
+    var $_registry;
+
+    /**
+     * @var PEAR_Config
+     */
+    var $_config;
+
+    /**
+     * @var PEAR_DependencyDB
+     */
+    var $_dependencydb;
+
+    /**
+     * Output of PEAR_Registry::parsedPackageName()
+     * @var array
+     */
+    var $_currentPackage;
+
+    /**
+     * @param PEAR_Config
+     * @param array installation options
+     * @param array format of PEAR_Registry::parsedPackageName()
+     * @param int installation state (one of PEAR_VALIDATE_*)
+     */
+    function PEAR_Dependency2(&$config, $installoptions, $package,
+                              $state = PEAR_VALIDATE_INSTALLING)
+    {
+        $this->_config = &$config;
+        if (!class_exists('PEAR_DependencyDB')) {
+            require_once 'PEAR/DependencyDB.php';
+        }
+
+        if (isset($installoptions['packagingroot'])) {
+            // make sure depdb is in the right location
+            $config->setInstallRoot($installoptions['packagingroot']);
+        }
+
+        $this->_registry = &$config->getRegistry();
+        $this->_dependencydb = &PEAR_DependencyDB::singleton($config);
+        if (isset($installoptions['packagingroot'])) {
+            $config->setInstallRoot(false);
+        }
+
+        $this->_options = $installoptions;
+        $this->_state = $state;
+        if (!class_exists('OS_Guess')) {
+            require_once 'OS/Guess.php';
+        }
+
+        $this->_os = new OS_Guess;
+        $this->_currentPackage = $package;
+    }
+
+    function _getExtraString($dep)
+    {
+        $extra = ' (';
+        if (isset($dep['uri'])) {
+            return '';
+        }
+
+        if (isset($dep['recommended'])) {
+            $extra .= 'recommended version ' . $dep['recommended'];
+        } else {
+            if (isset($dep['min'])) {
+                $extra .= 'version >= ' . $dep['min'];
+            }
+
+            if (isset($dep['max'])) {
+                if ($extra != ' (') {
+                    $extra .= ', ';
+                }
+                $extra .= 'version <= ' . $dep['max'];
+            }
+
+            if (isset($dep['exclude'])) {
+                if (!is_array($dep['exclude'])) {
+                    $dep['exclude'] = array($dep['exclude']);
+                }
+
+                if ($extra != ' (') {
+                    $extra .= ', ';
+                }
+
+                $extra .= 'excluded versions: ';
+                foreach ($dep['exclude'] as $i => $exclude) {
+                    if ($i) {
+                        $extra .= ', ';
+                    }
+                    $extra .= $exclude;
+                }
+            }
+        }
+
+        $extra .= ')';
+        if ($extra == ' ()') {
+            $extra = '';
+        }
+
+        return $extra;
+    }
+
+    /**
+     * This makes unit-testing a heck of a lot easier
+     */
+    function getPHP_OS()
+    {
+        return PHP_OS;
+    }
+
+    /**
+     * This makes unit-testing a heck of a lot easier
+     */
+    function getsysname()
+    {
+        return $this->_os->getSysname();
+    }
+
+    /**
+     * Specify a dependency on an OS.  Use arch for detailed os/processor information
+     *
+     * There are two generic OS dependencies that will be the most common, unix and windows.
+     * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix
+     */
+    function validateOsDependency($dep)
+    {
+        if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) {
+            return true;
+        }
+
+        if ($dep['name'] == '*') {
+            return true;
+        }
+
+        $not = isset($dep['conflicts']) ? true : false;
+        switch (strtolower($dep['name'])) {
+            case 'windows' :
+                if ($not) {
+                    if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') {
+                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                            return $this->raiseError("Cannot install %s on Windows");
+                        }
+
+                        return $this->warning("warning: Cannot install %s on Windows");
+                    }
+                } else {
+                    if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') {
+                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                            return $this->raiseError("Can only install %s on Windows");
+                        }
+
+                        return $this->warning("warning: Can only install %s on Windows");
+                    }
+                }
+            break;
+            case 'unix' :
+                $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix');
+                if ($not) {
+                    if (in_array($this->getSysname(), $unices)) {
+                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                            return $this->raiseError("Cannot install %s on any Unix system");
+                        }
+
+                        return $this->warning( "warning: Cannot install %s on any Unix system");
+                    }
+                } else {
+                    if (!in_array($this->getSysname(), $unices)) {
+                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                            return $this->raiseError("Can only install %s on a Unix system");
+                        }
+
+                        return $this->warning("warning: Can only install %s on a Unix system");
+                    }
+                }
+            break;
+            default :
+                if ($not) {
+                    if (strtolower($dep['name']) == strtolower($this->getSysname())) {
+                        if (!isset($this->_options['nodeps']) &&
+                              !isset($this->_options['force'])) {
+                            return $this->raiseError('Cannot install %s on ' . $dep['name'] .
+                                ' operating system');
+                        }
+
+                        return $this->warning('warning: Cannot install %s on ' .
+                            $dep['name'] . ' operating system');
+                    }
+                } else {
+                    if (strtolower($dep['name']) != strtolower($this->getSysname())) {
+                        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                            return $this->raiseError('Cannot install %s on ' .
+                                $this->getSysname() .
+                                ' operating system, can only install on ' . $dep['name']);
+                        }
+
+                        return $this->warning('warning: Cannot install %s on ' .
+                            $this->getSysname() .
+                            ' operating system, can only install on ' . $dep['name']);
+                    }
+                }
+        }
+        return true;
+    }
+
+    /**
+     * This makes unit-testing a heck of a lot easier
+     */
+    function matchSignature($pattern)
+    {
+        return $this->_os->matchSignature($pattern);
+    }
+
+    /**
+     * Specify a complex dependency on an OS/processor/kernel version,
+     * Use OS for simple operating system dependency.
+     *
+     * This is the only dependency that accepts an eregable pattern.  The pattern
+     * will be matched against the php_uname() output parsed by OS_Guess
+     */
+    function validateArchDependency($dep)
+    {
+        if ($this->_state != PEAR_VALIDATE_INSTALLING) {
+            return true;
+        }
+
+        $not = isset($dep['conflicts']) ? true : false;
+        if (!$this->matchSignature($dep['pattern'])) {
+            if (!$not) {
+                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                    return $this->raiseError('%s Architecture dependency failed, does not ' .
+                        'match "' . $dep['pattern'] . '"');
+                }
+
+                return $this->warning('warning: %s Architecture dependency failed, does ' .
+                    'not match "' . $dep['pattern'] . '"');
+            }
+
+            return true;
+        }
+
+        if ($not) {
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                return $this->raiseError('%s Architecture dependency failed, required "' .
+                    $dep['pattern'] . '"');
+            }
+
+            return $this->warning('warning: %s Architecture dependency failed, ' .
+                'required "' . $dep['pattern'] . '"');
+        }
+
+        return true;
+    }
+
+    /**
+     * This makes unit-testing a heck of a lot easier
+     */
+    function extension_loaded($name)
+    {
+        return extension_loaded($name);
+    }
+
+    /**
+     * This makes unit-testing a heck of a lot easier
+     */
+    function phpversion($name = null)
+    {
+        if ($name !== null) {
+            return phpversion($name);
+        }
+
+        return phpversion();
+    }
+
+    function validateExtensionDependency($dep, $required = true)
+    {
+        if ($this->_state != PEAR_VALIDATE_INSTALLING &&
+              $this->_state != PEAR_VALIDATE_DOWNLOADING) {
+            return true;
+        }
+
+        $loaded = $this->extension_loaded($dep['name']);
+        $extra  = $this->_getExtraString($dep);
+        if (isset($dep['exclude'])) {
+            if (!is_array($dep['exclude'])) {
+                $dep['exclude'] = array($dep['exclude']);
+            }
+        }
+
+        if (!isset($dep['min']) && !isset($dep['max']) &&
+            !isset($dep['recommended']) && !isset($dep['exclude'])
+        ) {
+            if ($loaded) {
+                if (isset($dep['conflicts'])) {
+                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                        return $this->raiseError('%s conflicts with PHP extension "' .
+                            $dep['name'] . '"' . $extra);
+                    }
+
+                    return $this->warning('warning: %s conflicts with PHP extension "' .
+                        $dep['name'] . '"' . $extra);
+                }
+
+                return true;
+            }
+
+            if (isset($dep['conflicts'])) {
+                return true;
+            }
+
+            if ($required) {
+                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                    return $this->raiseError('%s requires PHP extension "' .
+                        $dep['name'] . '"' . $extra);
+                }
+
+                return $this->warning('warning: %s requires PHP extension "' .
+                    $dep['name'] . '"' . $extra);
+            }
+
+            return $this->warning('%s can optionally use PHP extension "' .
+                $dep['name'] . '"' . $extra);
+        }
+
+        if (!$loaded) {
+            if (isset($dep['conflicts'])) {
+                return true;
+            }
+
+            if (!$required) {
+                return $this->warning('%s can optionally use PHP extension "' .
+                    $dep['name'] . '"' . $extra);
+            }
+
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                return $this->raiseError('%s requires PHP extension "' . $dep['name'] .
+                    '"' . $extra);
+            }
+
+            return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
+                    '"' . $extra);
+        }
+
+        $version = (string) $this->phpversion($dep['name']);
+        if (empty($version)) {
+            $version = '0';
+        }
+
+        $fail = false;
+        if (isset($dep['min']) && !version_compare($version, $dep['min'], '>=')) {
+            $fail = true;
+        }
+
+        if (isset($dep['max']) && !version_compare($version, $dep['max'], '<=')) {
+            $fail = true;
+        }
+
+        if ($fail && !isset($dep['conflicts'])) {
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                return $this->raiseError('%s requires PHP extension "' . $dep['name'] .
+                    '"' . $extra . ', installed version is ' . $version);
+            }
+
+            return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
+                '"' . $extra . ', installed version is ' . $version);
+        } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) {
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                return $this->raiseError('%s conflicts with PHP extension "' .
+                    $dep['name'] . '"' . $extra . ', installed version is ' . $version);
+            }
+
+            return $this->warning('warning: %s conflicts with PHP extension "' .
+                $dep['name'] . '"' . $extra . ', installed version is ' . $version);
+        }
+
+        if (isset($dep['exclude'])) {
+            foreach ($dep['exclude'] as $exclude) {
+                if (version_compare($version, $exclude, '==')) {
+                    if (isset($dep['conflicts'])) {
+                        continue;
+                    }
+
+                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                        return $this->raiseError('%s is not compatible with PHP extension "' .
+                            $dep['name'] . '" version ' .
+                            $exclude);
+                    }
+
+                    return $this->warning('warning: %s is not compatible with PHP extension "' .
+                        $dep['name'] . '" version ' .
+                        $exclude);
+                } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) {
+                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                        return $this->raiseError('%s conflicts with PHP extension "' .
+                            $dep['name'] . '"' . $extra . ', installed version is ' . $version);
+                    }
+
+                    return $this->warning('warning: %s conflicts with PHP extension "' .
+                        $dep['name'] . '"' . $extra . ', installed version is ' . $version);
+                }
+            }
+        }
+
+        if (isset($dep['recommended'])) {
+            if (version_compare($version, $dep['recommended'], '==')) {
+                return true;
+            }
+
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] .
+                    ' version "' . $version . '"' .
+                    ' is not the recommended version "' . $dep['recommended'] .
+                    '", but may be compatible, use --force to install');
+            }
+
+            return $this->warning('warning: %s dependency: PHP extension ' .
+                $dep['name'] . ' version "' . $version . '"' .
+                ' is not the recommended version "' . $dep['recommended'].'"');
+        }
+
+        return true;
+    }
+
+    function validatePhpDependency($dep)
+    {
+        if ($this->_state != PEAR_VALIDATE_INSTALLING &&
+              $this->_state != PEAR_VALIDATE_DOWNLOADING) {
+            return true;
+        }
+
+        $version = $this->phpversion();
+        $extra   = $this->_getExtraString($dep);
+        if (isset($dep['exclude'])) {
+            if (!is_array($dep['exclude'])) {
+                $dep['exclude'] = array($dep['exclude']);
+            }
+        }
+
+        if (isset($dep['min'])) {
+            if (!version_compare($version, $dep['min'], '>=')) {
+                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                    return $this->raiseError('%s requires PHP' .
+                        $extra . ', installed version is ' . $version);
+                }
+
+                return $this->warning('warning: %s requires PHP' .
+                    $extra . ', installed version is ' . $version);
+            }
+        }
+
+        if (isset($dep['max'])) {
+            if (!version_compare($version, $dep['max'], '<=')) {
+                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                    return $this->raiseError('%s requires PHP' .
+                        $extra . ', installed version is ' . $version);
+                }
+
+                return $this->warning('warning: %s requires PHP' .
+                    $extra . ', installed version is ' . $version);
+            }
+        }
+
+        if (isset($dep['exclude'])) {
+            foreach ($dep['exclude'] as $exclude) {
+                if (version_compare($version, $exclude, '==')) {
+                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                        return $this->raiseError('%s is not compatible with PHP version ' .
+                            $exclude);
+                    }
+
+                    return $this->warning(
+                        'warning: %s is not compatible with PHP version ' .
+                        $exclude);
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * This makes unit-testing a heck of a lot easier
+     */
+    function getPEARVersion()
+    {
+        return '1.9.0';
+    }
+
+    function validatePearinstallerDependency($dep)
+    {
+        $pearversion = $this->getPEARVersion();
+        $extra = $this->_getExtraString($dep);
+        if (isset($dep['exclude'])) {
+            if (!is_array($dep['exclude'])) {
+                $dep['exclude'] = array($dep['exclude']);
+            }
+        }
+
+        if (version_compare($pearversion, $dep['min'], '<')) {
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                return $this->raiseError('%s requires PEAR Installer' . $extra .
+                    ', installed version is ' . $pearversion);
+            }
+
+            return $this->warning('warning: %s requires PEAR Installer' . $extra .
+                ', installed version is ' . $pearversion);
+        }
+
+        if (isset($dep['max'])) {
+            if (version_compare($pearversion, $dep['max'], '>')) {
+                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                    return $this->raiseError('%s requires PEAR Installer' . $extra .
+                        ', installed version is ' . $pearversion);
+                }
+
+                return $this->warning('warning: %s requires PEAR Installer' . $extra .
+                    ', installed version is ' . $pearversion);
+            }
+        }
+
+        if (isset($dep['exclude'])) {
+            if (!isset($dep['exclude'][0])) {
+                $dep['exclude'] = array($dep['exclude']);
+            }
+
+            foreach ($dep['exclude'] as $exclude) {
+                if (version_compare($exclude, $pearversion, '==')) {
+                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                        return $this->raiseError('%s is not compatible with PEAR Installer ' .
+                            'version ' . $exclude);
+                    }
+
+                    return $this->warning('warning: %s is not compatible with PEAR ' .
+                        'Installer version ' . $exclude);
+                }
+            }
+        }
+
+        return true;
+    }
+
+    function validateSubpackageDependency($dep, $required, $params)
+    {
+        return $this->validatePackageDependency($dep, $required, $params);
+    }
+
+    /**
+     * @param array dependency information (2.0 format)
+     * @param boolean whether this is a required dependency
+     * @param array a list of downloaded packages to be installed, if any
+     * @param boolean if true, then deps on pear.php.net that fail will also check
+     *                against pecl.php.net packages to accomodate extensions that have
+     *                moved to pecl.php.net from pear.php.net
+     */
+    function validatePackageDependency($dep, $required, $params, $depv1 = false)
+    {
+        if ($this->_state != PEAR_VALIDATE_INSTALLING &&
+              $this->_state != PEAR_VALIDATE_DOWNLOADING) {
+            return true;
+        }
+
+        if (isset($dep['providesextension'])) {
+            if ($this->extension_loaded($dep['providesextension'])) {
+                $save = $dep;
+                $subdep = $dep;
+                $subdep['name'] = $subdep['providesextension'];
+                PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                $ret = $this->validateExtensionDependency($subdep, $required);
+                PEAR::popErrorHandling();
+                if (!PEAR::isError($ret)) {
+                    return true;
+                }
+            }
+        }
+
+        if ($this->_state == PEAR_VALIDATE_INSTALLING) {
+            return $this->_validatePackageInstall($dep, $required, $depv1);
+        }
+
+        if ($this->_state == PEAR_VALIDATE_DOWNLOADING) {
+            return $this->_validatePackageDownload($dep, $required, $params, $depv1);
+        }
+    }
+
+    function _validatePackageDownload($dep, $required, $params, $depv1 = false)
+    {
+        $dep['package'] = $dep['name'];
+        if (isset($dep['uri'])) {
+            $dep['channel'] = '__uri';
+        }
+
+        $depname = $this->_registry->parsedPackageNameToString($dep, true);
+        $found = false;
+        foreach ($params as $param) {
+            if ($param->isEqual(
+                  array('package' => $dep['name'],
+                        'channel' => $dep['channel']))) {
+                $found = true;
+                break;
+            }
+
+            if ($depv1 && $dep['channel'] == 'pear.php.net') {
+                if ($param->isEqual(
+                  array('package' => $dep['name'],
+                        'channel' => 'pecl.php.net'))) {
+                    $found = true;
+                    break;
+                }
+            }
+        }
+
+        if (!$found && isset($dep['providesextension'])) {
+            foreach ($params as $param) {
+                if ($param->isExtension($dep['providesextension'])) {
+                    $found = true;
+                    break;
+                }
+            }
+        }
+
+        if ($found) {
+            $version = $param->getVersion();
+            $installed = false;
+            $downloaded = true;
+        } else {
+            if ($this->_registry->packageExists($dep['name'], $dep['channel'])) {
+                $installed = true;
+                $downloaded = false;
+                $version = $this->_registry->packageinfo($dep['name'], 'version',
+                    $dep['channel']);
+            } else {
+                if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'],
+                      'pear.php.net')) {
+                    $installed = true;
+                    $downloaded = false;
+                    $version = $this->_registry->packageinfo($dep['name'], 'version',
+                        'pear.php.net');
+                } else {
+                    $version = 'not installed or downloaded';
+                    $installed = false;
+                    $downloaded = false;
+                }
+            }
+        }
+
+        $extra = $this->_getExtraString($dep);
+        if (isset($dep['exclude']) && !is_array($dep['exclude'])) {
+            $dep['exclude'] = array($dep['exclude']);
+        }
+
+        if (!isset($dep['min']) && !isset($dep['max']) &&
+              !isset($dep['recommended']) && !isset($dep['exclude'])
+        ) {
+            if ($installed || $downloaded) {
+                $installed = $installed ? 'installed' : 'downloaded';
+                if (isset($dep['conflicts'])) {
+                    $rest = '';
+                    if ($version) {
+                        $rest = ", $installed version is " . $version;
+                    }
+
+                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                        return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest);
+                    }
+
+                    return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest);
+                }
+
+                return true;
+            }
+
+            if (isset($dep['conflicts'])) {
+                return true;
+            }
+
+            if ($required) {
+                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                    return $this->raiseError('%s requires package "' . $depname . '"' . $extra);
+                }
+
+                return $this->warning('warning: %s requires package "' . $depname . '"' . $extra);
+            }
+
+            return $this->warning('%s can optionally use package "' . $depname . '"' . $extra);
+        }
+
+        if (!$installed && !$downloaded) {
+            if (isset($dep['conflicts'])) {
+                return true;
+            }
+
+            if ($required) {
+                if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                    return $this->raiseError('%s requires package "' . $depname . '"' . $extra);
+                }
+
+                return $this->warning('warning: %s requires package "' . $depname . '"' . $extra);
+            }
+
+            return $this->warning('%s can optionally use package "' . $depname . '"' . $extra);
+        }
+
+        $fail = false;
+        if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) {
+            $fail = true;
+        }
+
+        if (isset($dep['max']) && version_compare($version, $dep['max'], '>')) {
+            $fail = true;
+        }
+
+        if ($fail && !isset($dep['conflicts'])) {
+            $installed = $installed ? 'installed' : 'downloaded';
+            $dep['package'] = $dep['name'];
+            $dep = $this->_registry->parsedPackageNameToString($dep, true);
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                return $this->raiseError('%s requires package "' . $depname . '"' .
+                    $extra . ", $installed version is " . $version);
+            }
+
+            return $this->warning('warning: %s requires package "' . $depname . '"' .
+                $extra . ", $installed version is " . $version);
+        } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail &&
+              isset($dep['conflicts']) && !isset($dep['exclude'])) {
+            $installed = $installed ? 'installed' : 'downloaded';
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra .
+                    ", $installed version is " . $version);
+            }
+
+            return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
+                $extra . ", $installed version is " . $version);
+        }
+
+        if (isset($dep['exclude'])) {
+            $installed = $installed ? 'installed' : 'downloaded';
+            foreach ($dep['exclude'] as $exclude) {
+                if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) {
+                    if (!isset($this->_options['nodeps']) &&
+                          !isset($this->_options['force'])
+                    ) {
+                        return $this->raiseError('%s is not compatible with ' .
+                            $installed . ' package "' .
+                            $depname . '" version ' .
+                            $exclude);
+                    }
+
+                    return $this->warning('warning: %s is not compatible with ' .
+                        $installed . ' package "' .
+                        $depname . '" version ' .
+                        $exclude);
+                } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) {
+                    $installed = $installed ? 'installed' : 'downloaded';
+                    if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                        return $this->raiseError('%s conflicts with package "' . $depname . '"' .
+                            $extra . ", $installed version is " . $version);
+                    }
+
+                    return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
+                        $extra . ", $installed version is " . $version);
+                }
+            }
+        }
+
+        if (isset($dep['recommended'])) {
+            $installed = $installed ? 'installed' : 'downloaded';
+            if (version_compare($version, $dep['recommended'], '==')) {
+                return true;
+            }
+
+            if (!$found && $installed) {
+                $param = $this->_registry->getPackage($dep['name'], $dep['channel']);
+            }
+
+            if ($param) {
+                $found = false;
+                foreach ($params as $parent) {
+                    if ($parent->isEqual($this->_currentPackage)) {
+                        $found = true;
+                        break;
+                    }
+                }
+
+                if ($found) {
+                    if ($param->isCompatible($parent)) {
+                        return true;
+                    }
+                } else { // this is for validPackage() calls
+                    $parent = $this->_registry->getPackage($this->_currentPackage['package'],
+                        $this->_currentPackage['channel']);
+                    if ($parent !== null && $param->isCompatible($parent)) {
+                        return true;
+                    }
+                }
+            }
+
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) &&
+                  !isset($this->_options['loose'])
+            ) {
+                return $this->raiseError('%s dependency package "' . $depname .
+                    '" ' . $installed . ' version ' . $version .
+                    ' is not the recommended version ' . $dep['recommended'] .
+                    ', but may be compatible, use --force to install');
+            }
+
+            return $this->warning('warning: %s dependency package "' . $depname .
+                '" ' . $installed . ' version ' . $version .
+                ' is not the recommended version ' . $dep['recommended']);
+        }
+
+        return true;
+    }
+
+    function _validatePackageInstall($dep, $required, $depv1 = false)
+    {
+        return $this->_validatePackageDownload($dep, $required, array(), $depv1);
+    }
+
+    /**
+     * Verify that uninstalling packages passed in to command line is OK.
+     *
+     * @param PEAR_Installer $dl
+     * @return PEAR_Error|true
+     */
+    function validatePackageUninstall(&$dl)
+    {
+        if (PEAR::isError($this->_dependencydb)) {
+            return $this->_dependencydb;
+        }
+
+        $params = array();
+        // construct an array of "downloaded" packages to fool the package dependency checker
+        // into using these to validate uninstalls of circular dependencies
+        $downloaded = &$dl->getUninstallPackages();
+        foreach ($downloaded as $i => $pf) {
+            if (!class_exists('PEAR_Downloader_Package')) {
+                require_once 'PEAR/Downloader/Package.php';
+            }
+            $dp = &new PEAR_Downloader_Package($dl);
+            $dp->setPackageFile($downloaded[$i]);
+            $params[$i] = &$dp;
+        }
+
+        // check cache
+        $memyselfandI = strtolower($this->_currentPackage['channel']) . '/' .
+            strtolower($this->_currentPackage['package']);
+        if (isset($dl->___uninstall_package_cache)) {
+            $badpackages = $dl->___uninstall_package_cache;
+            if (isset($badpackages[$memyselfandI]['warnings'])) {
+                foreach ($badpackages[$memyselfandI]['warnings'] as $warning) {
+                    $dl->log(0, $warning[0]);
+                }
+            }
+
+            if (isset($badpackages[$memyselfandI]['errors'])) {
+                foreach ($badpackages[$memyselfandI]['errors'] as $error) {
+                    if (is_array($error)) {
+                        $dl->log(0, $error[0]);
+                    } else {
+                        $dl->log(0, $error->getMessage());
+                    }
+                }
+
+                if (isset($this->_options['nodeps']) || isset($this->_options['force'])) {
+                    return $this->warning(
+                        'warning: %s should not be uninstalled, other installed packages depend ' .
+                        'on this package');
+                }
+
+                return $this->raiseError(
+                    '%s cannot be uninstalled, other installed packages depend on this package');
+            }
+
+            return true;
+        }
+
+        // first, list the immediate parents of each package to be uninstalled
+        $perpackagelist = array();
+        $allparents = array();
+        foreach ($params as $i => $param) {
+            $a = array(
+                'channel' => strtolower($param->getChannel()),
+                'package' => strtolower($param->getPackage())
+            );
+
+            $deps = $this->_dependencydb->getDependentPackages($a);
+            if ($deps) {
+                foreach ($deps as $d) {
+                    $pardeps = $this->_dependencydb->getDependencies($d);
+                    foreach ($pardeps as $dep) {
+                        if (strtolower($dep['dep']['channel']) == $a['channel'] &&
+                              strtolower($dep['dep']['name']) == $a['package']) {
+                            if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) {
+                                $perpackagelist[$a['channel'] . '/' . $a['package']] = array();
+                            }
+                            $perpackagelist[$a['channel'] . '/' . $a['package']][]
+                                = array($d['channel'] . '/' . $d['package'], $dep);
+                            if (!isset($allparents[$d['channel'] . '/' . $d['package']])) {
+                                $allparents[$d['channel'] . '/' . $d['package']] = array();
+                            }
+                            if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) {
+                                $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array();
+                            }
+                            $allparents[$d['channel'] . '/' . $d['package']]
+                                       [$a['channel'] . '/' . $a['package']][]
+                                = array($d, $dep);
+                        }
+                    }
+                }
+            }
+        }
+
+        // next, remove any packages from the parents list that are not installed
+        $remove = array();
+        foreach ($allparents as $parent => $d1) {
+            foreach ($d1 as $d) {
+                if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) {
+                    continue;
+                }
+                $remove[$parent] = true;
+            }
+        }
+
+        // next remove any packages from the parents list that are not passed in for
+        // uninstallation
+        foreach ($allparents as $parent => $d1) {
+            foreach ($d1 as $d) {
+                foreach ($params as $param) {
+                    if (strtolower($param->getChannel()) == $d[0][0]['channel'] &&
+                          strtolower($param->getPackage()) == $d[0][0]['package']) {
+                        // found it
+                        continue 3;
+                    }
+                }
+                $remove[$parent] = true;
+            }
+        }
+
+        // remove all packages whose dependencies fail
+        // save which ones failed for error reporting
+        $badchildren = array();
+        do {
+            $fail = false;
+            foreach ($remove as $package => $unused) {
+                if (!isset($allparents[$package])) {
+                    continue;
+                }
+
+                foreach ($allparents[$package] as $kid => $d1) {
+                    foreach ($d1 as $depinfo) {
+                        if ($depinfo[1]['type'] != 'optional') {
+                            if (isset($badchildren[$kid])) {
+                                continue;
+                            }
+                            $badchildren[$kid] = true;
+                            $remove[$kid] = true;
+                            $fail = true;
+                            continue 2;
+                        }
+                    }
+                }
+                if ($fail) {
+                    // start over, we removed some children
+                    continue 2;
+                }
+            }
+        } while ($fail);
+
+        // next, construct the list of packages that can't be uninstalled
+        $badpackages = array();
+        $save = $this->_currentPackage;
+        foreach ($perpackagelist as $package => $packagedeps) {
+            foreach ($packagedeps as $parent) {
+                if (!isset($remove[$parent[0]])) {
+                    continue;
+                }
+
+                $packagename = $this->_registry->parsePackageName($parent[0]);
+                $packagename['channel'] = $this->_registry->channelAlias($packagename['channel']);
+                $pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']);
+                $packagename['package'] = $pa->getPackage();
+                $this->_currentPackage = $packagename;
+                // parent is not present in uninstall list, make sure we can actually
+                // uninstall it (parent dep is optional)
+                $parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']);
+                $pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']);
+                $parentname['package'] = $pa->getPackage();
+                $parent[1]['dep']['package'] = $parentname['package'];
+                $parent[1]['dep']['channel'] = $parentname['channel'];
+                if ($parent[1]['type'] == 'optional') {
+                    $test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl);
+                    if ($test !== true) {
+                        $badpackages[$package]['warnings'][] = $test;
+                    }
+                } else {
+                    $test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl);
+                    if ($test !== true) {
+                        $badpackages[$package]['errors'][] = $test;
+                    }
+                }
+            }
+        }
+
+        $this->_currentPackage          = $save;
+        $dl->___uninstall_package_cache = $badpackages;
+        if (isset($badpackages[$memyselfandI])) {
+            if (isset($badpackages[$memyselfandI]['warnings'])) {
+                foreach ($badpackages[$memyselfandI]['warnings'] as $warning) {
+                    $dl->log(0, $warning[0]);
+                }
+            }
+
+            if (isset($badpackages[$memyselfandI]['errors'])) {
+                foreach ($badpackages[$memyselfandI]['errors'] as $error) {
+                    if (is_array($error)) {
+                        $dl->log(0, $error[0]);
+                    } else {
+                        $dl->log(0, $error->getMessage());
+                    }
+                }
+
+                if (isset($this->_options['nodeps']) || isset($this->_options['force'])) {
+                    return $this->warning(
+                        'warning: %s should not be uninstalled, other installed packages depend ' .
+                        'on this package');
+                }
+
+                return $this->raiseError(
+                    '%s cannot be uninstalled, other installed packages depend on this package');
+            }
+        }
+
+        return true;
+    }
+
+    function _validatePackageUninstall($dep, $required, $dl)
+    {
+        $depname = $this->_registry->parsedPackageNameToString($dep, true);
+        $version = $this->_registry->packageinfo($dep['package'], 'version', $dep['channel']);
+        if (!$version) {
+            return true;
+        }
+
+        $extra = $this->_getExtraString($dep);
+        if (isset($dep['exclude']) && !is_array($dep['exclude'])) {
+            $dep['exclude'] = array($dep['exclude']);
+        }
+
+        if (isset($dep['conflicts'])) {
+            return true; // uninstall OK - these packages conflict (probably installed with --force)
+        }
+
+        if (!isset($dep['min']) && !isset($dep['max'])) {
+            if (!$required) {
+                return $this->warning('"' . $depname . '" can be optionally used by ' .
+                        'installed package %s' . $extra);
+            }
+
+            if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+                return $this->raiseError('"' . $depname . '" is required by ' .
+                    'installed package %s' . $extra);
+            }
+
+            return $this->warning('warning: "' . $depname . '" is required by ' .
+                'installed package %s' . $extra);
+        }
+
+        $fail = false;
+        if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) {
+            $fail = true;
+        }
+
+        if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) {
+            $fail = true;
+        }
+
+        // we re-use this variable, preserve the original value
+        $saverequired = $required;
+        if (!$required) {
+            return $this->warning($depname . $extra . ' can be optionally used by installed package' .
+                    ' "%s"');
+        }
+
+        if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
+            return $this->raiseError($depname . $extra . ' is required by installed package' .
+                ' "%s"');
+        }
+
+        return $this->raiseError('warning: ' . $depname . $extra .
+            ' is required by installed package "%s"');
+    }
+
+    /**
+     * validate a downloaded package against installed packages
+     *
+     * As of PEAR 1.4.3, this will only validate
+     *
+     * @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     *              $pkg package identifier (either
+     *                   array('package' => blah, 'channel' => blah) or an array with
+     *                   index 'info' referencing an object)
+     * @param PEAR_Downloader $dl
+     * @param array $params full list of packages to install
+     * @return true|PEAR_Error
+     */
+    function validatePackage($pkg, &$dl, $params = array())
+    {
+        if (is_array($pkg) && isset($pkg['info'])) {
+            $deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']);
+        } else {
+            $deps = $this->_dependencydb->getDependentPackageDependencies($pkg);
+        }
+
+        $fail = false;
+        if ($deps) {
+            if (!class_exists('PEAR_Downloader_Package')) {
+                require_once 'PEAR/Downloader/Package.php';
+            }
+
+            $dp = &new PEAR_Downloader_Package($dl);
+            if (is_object($pkg)) {
+                $dp->setPackageFile($pkg);
+            } else {
+                $dp->setDownloadURL($pkg);
+            }
+
+            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+            foreach ($deps as $channel => $info) {
+                foreach ($info as $package => $ds) {
+                    foreach ($params as $packd) {
+                        if (strtolower($packd->getPackage()) == strtolower($package) &&
+                              $packd->getChannel() == $channel) {
+                            $dl->log(3, 'skipping installed package check of "' .
+                                        $this->_registry->parsedPackageNameToString(
+                                            array('channel' => $channel, 'package' => $package),
+                                            true) .
+                                        '", version "' . $packd->getVersion() . '" will be ' .
+                                        'downloaded and installed');
+                            continue 2; // jump to next package
+                        }
+                    }
+
+                    foreach ($ds as $d) {
+                        $checker = &new PEAR_Dependency2($this->_config, $this->_options,
+                            array('channel' => $channel, 'package' => $package), $this->_state);
+                        $dep = $d['dep'];
+                        $required = $d['type'] == 'required';
+                        $ret = $checker->_validatePackageDownload($dep, $required, array(&$dp));
+                        if (is_array($ret)) {
+                            $dl->log(0, $ret[0]);
+                        } elseif (PEAR::isError($ret)) {
+                            $dl->log(0, $ret->getMessage());
+                            $fail = true;
+                        }
+                    }
+                }
+            }
+            PEAR::popErrorHandling();
+        }
+
+        if ($fail) {
+            return $this->raiseError(
+                '%s cannot be installed, conflicts with installed packages');
+        }
+
+        return true;
+    }
+
+    /**
+     * validate a package.xml 1.0 dependency
+     */
+    function validateDependency1($dep, $params = array())
+    {
+        if (!isset($dep['optional'])) {
+            $dep['optional'] = 'no';
+        }
+
+        list($newdep, $type) = $this->normalizeDep($dep);
+        if (!$newdep) {
+            return $this->raiseError("Invalid Dependency");
+        }
+
+        if (method_exists($this, "validate{$type}Dependency")) {
+            return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no',
+                $params, true);
+        }
+    }
+
+    /**
+     * Convert a 1.0 dep into a 2.0 dep
+     */
+    function normalizeDep($dep)
+    {
+        $types = array(
+            'pkg' => 'Package',
+            'ext' => 'Extension',
+            'os' => 'Os',
+            'php' => 'Php'
+        );
+
+        if (!isset($types[$dep['type']])) {
+            return array(false, false);
+        }
+
+        $type = $types[$dep['type']];
+
+        $newdep = array();
+        switch ($type) {
+            case 'Package' :
+                $newdep['channel'] = 'pear.php.net';
+            case 'Extension' :
+            case 'Os' :
+                $newdep['name'] = $dep['name'];
+            break;
+        }
+
+        $dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']);
+        switch ($dep['rel']) {
+            case 'has' :
+                return array($newdep, $type);
+            break;
+            case 'not' :
+                $newdep['conflicts'] = true;
+            break;
+            case '>=' :
+            case '>' :
+                $newdep['min'] = $dep['version'];
+                if ($dep['rel'] == '>') {
+                    $newdep['exclude'] = $dep['version'];
+                }
+            break;
+            case '<=' :
+            case '<' :
+                $newdep['max'] = $dep['version'];
+                if ($dep['rel'] == '<') {
+                    $newdep['exclude'] = $dep['version'];
+                }
+            break;
+            case 'ne' :
+            case '!=' :
+                $newdep['min'] = '0';
+                $newdep['max'] = '100000';
+                $newdep['exclude'] = $dep['version'];
+            break;
+            case '==' :
+                $newdep['min'] = $dep['version'];
+                $newdep['max'] = $dep['version'];
+            break;
+        }
+        if ($type == 'Php') {
+            if (!isset($newdep['min'])) {
+                $newdep['min'] = '4.4.0';
+            }
+
+            if (!isset($newdep['max'])) {
+                $newdep['max'] = '6.0.0';
+            }
+        }
+        return array($newdep, $type);
+    }
+
+    /**
+     * Converts text comparing operators to them sign equivalents
+     *
+     * Example: 'ge' to '>='
+     *
+     * @access public
+     * @param  string Operator
+     * @return string Sign equivalent
+     */
+    function signOperator($operator)
+    {
+        switch($operator) {
+            case 'lt': return '<';
+            case 'le': return '<=';
+            case 'gt': return '>';
+            case 'ge': return '>=';
+            case 'eq': return '==';
+            case 'ne': return '!=';
+            default:
+                return $operator;
+        }
+    }
+
+    function raiseError($msg)
+    {
+        if (isset($this->_options['ignore-errors'])) {
+            return $this->warning($msg);
+        }
+
+        return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString(
+            $this->_currentPackage, true)));
+    }
+
+    function warning($msg)
+    {
+        return array(sprintf($msg, $this->_registry->parsedPackageNameToString(
+            $this->_currentPackage, true)));
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/DependencyDB.php b/lib/php/PEAR/DependencyDB.php
new file mode 100644
index 00000000..4e2de4c6
--- /dev/null
+++ b/lib/php/PEAR/DependencyDB.php
@@ -0,0 +1,769 @@
+<?php
+/**
+ * PEAR_DependencyDB, advanced installed packages dependency database
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: DependencyDB.php 286686 2009-08-02 17:38:57Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * Needed for error handling
+ */
+require_once 'PEAR.php';
+require_once 'PEAR/Config.php';
+
+$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array();
+/**
+ * Track dependency relationships between installed packages
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @author     Tomas V.V.Cox <cox@idec.net.com>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_DependencyDB
+{
+    // {{{ properties
+
+    /**
+     * This is initialized by {@link setConfig()}
+     * @var PEAR_Config
+     * @access private
+     */
+    var $_config;
+    /**
+     * This is initialized by {@link setConfig()}
+     * @var PEAR_Registry
+     * @access private
+     */
+    var $_registry;
+    /**
+     * Filename of the dependency DB (usually .depdb)
+     * @var string
+     * @access private
+     */
+    var $_depdb = false;
+    /**
+     * File name of the lockfile (usually .depdblock)
+     * @var string
+     * @access private
+     */
+    var $_lockfile = false;
+    /**
+     * Open file resource for locking the lockfile
+     * @var resource|false
+     * @access private
+     */
+    var $_lockFp = false;
+    /**
+     * API version of this class, used to validate a file on-disk
+     * @var string
+     * @access private
+     */
+    var $_version = '1.0';
+    /**
+     * Cached dependency database file
+     * @var array|null
+     * @access private
+     */
+    var $_cache;
+
+    // }}}
+    // {{{ & singleton()
+
+    /**
+     * Get a raw dependency database.  Calls setConfig() and assertDepsDB()
+     * @param PEAR_Config
+     * @param string|false full path to the dependency database, or false to use default
+     * @return PEAR_DependencyDB|PEAR_Error
+     * @static
+     */
+    function &singleton(&$config, $depdb = false)
+    {
+        $phpdir = $config->get('php_dir', null, 'pear.php.net');
+        if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) {
+            $a = new PEAR_DependencyDB;
+            $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a;
+            $a->setConfig($config, $depdb);
+            $e = $a->assertDepsDB();
+            if (PEAR::isError($e)) {
+                return $e;
+            }
+        }
+
+        return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir];
+    }
+
+    /**
+     * Set up the registry/location of dependency DB
+     * @param PEAR_Config|false
+     * @param string|false full path to the dependency database, or false to use default
+     */
+    function setConfig(&$config, $depdb = false)
+    {
+        if (!$config) {
+            $this->_config = &PEAR_Config::singleton();
+        } else {
+            $this->_config = &$config;
+        }
+
+        $this->_registry = &$this->_config->getRegistry();
+        if (!$depdb) {
+            $this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') .
+                DIRECTORY_SEPARATOR . '.depdb';
+        } else {
+            $this->_depdb = $depdb;
+        }
+
+        $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock';
+    }
+    // }}}
+
+    function hasWriteAccess()
+    {
+        if (!file_exists($this->_depdb)) {
+            $dir = $this->_depdb;
+            while ($dir && $dir != '.') {
+                $dir = dirname($dir); // cd ..
+                if ($dir != '.' && file_exists($dir)) {
+                    if (is_writeable($dir)) {
+                        return true;
+                    }
+
+                    return false;
+                }
+            }
+
+            return false;
+        }
+
+        return is_writeable($this->_depdb);
+    }
+
+    // {{{ assertDepsDB()
+
+    /**
+     * Create the dependency database, if it doesn't exist.  Error if the database is
+     * newer than the code reading it.
+     * @return void|PEAR_Error
+     */
+    function assertDepsDB()
+    {
+        if (!is_file($this->_depdb)) {
+            $this->rebuildDB();
+            return;
+        }
+
+        $depdb = $this->_getDepDB();
+        // Datatype format has been changed, rebuild the Deps DB
+        if ($depdb['_version'] < $this->_version) {
+            $this->rebuildDB();
+        }
+
+        if ($depdb['_version']{0} > $this->_version{0}) {
+            return PEAR::raiseError('Dependency database is version ' .
+                $depdb['_version'] . ', and we are version ' .
+                $this->_version . ', cannot continue');
+        }
+    }
+
+    /**
+     * Get a list of installed packages that depend on this package
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
+     * @return array|false
+     */
+    function getDependentPackages(&$pkg)
+    {
+        $data = $this->_getDepDB();
+        if (is_object($pkg)) {
+            $channel = strtolower($pkg->getChannel());
+            $package = strtolower($pkg->getPackage());
+        } else {
+            $channel = strtolower($pkg['channel']);
+            $package = strtolower($pkg['package']);
+        }
+
+        if (isset($data['packages'][$channel][$package])) {
+            return $data['packages'][$channel][$package];
+        }
+
+        return false;
+    }
+
+    /**
+     * Get a list of the actual dependencies of installed packages that depend on
+     * a package.
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
+     * @return array|false
+     */
+    function getDependentPackageDependencies(&$pkg)
+    {
+        $data = $this->_getDepDB();
+        if (is_object($pkg)) {
+            $channel = strtolower($pkg->getChannel());
+            $package = strtolower($pkg->getPackage());
+        } else {
+            $channel = strtolower($pkg['channel']);
+            $package = strtolower($pkg['package']);
+        }
+
+        $depend = $this->getDependentPackages($pkg);
+        if (!$depend) {
+            return false;
+        }
+
+        $dependencies = array();
+        foreach ($depend as $info) {
+            $temp = $this->getDependencies($info);
+            foreach ($temp as $dep) {
+                if (
+                    isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) &&
+                    strtolower($dep['dep']['channel']) == $channel &&
+                    strtolower($dep['dep']['name']) == $package
+                ) {
+                    if (!isset($dependencies[$info['channel']])) {
+                        $dependencies[$info['channel']] = array();
+                    }
+
+                    if (!isset($dependencies[$info['channel']][$info['package']])) {
+                        $dependencies[$info['channel']][$info['package']] = array();
+                    }
+                    $dependencies[$info['channel']][$info['package']][] = $dep;
+                }
+            }
+        }
+
+        return $dependencies;
+    }
+
+    /**
+     * Get a list of dependencies of this installed package
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
+     * @return array|false
+     */
+    function getDependencies(&$pkg)
+    {
+        if (is_object($pkg)) {
+            $channel = strtolower($pkg->getChannel());
+            $package = strtolower($pkg->getPackage());
+        } else {
+            $channel = strtolower($pkg['channel']);
+            $package = strtolower($pkg['package']);
+        }
+
+        $data = $this->_getDepDB();
+        if (isset($data['dependencies'][$channel][$package])) {
+            return $data['dependencies'][$channel][$package];
+        }
+
+        return false;
+    }
+
+    /**
+     * Determine whether $parent depends on $child, near or deep
+     * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
+     * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
+     */
+    function dependsOn($parent, $child)
+    {
+        $c = array();
+        $this->_getDepDB();
+        return $this->_dependsOn($parent, $child, $c);
+    }
+
+    function _dependsOn($parent, $child, &$checked)
+    {
+        if (is_object($parent)) {
+            $channel = strtolower($parent->getChannel());
+            $package = strtolower($parent->getPackage());
+        } else {
+            $channel = strtolower($parent['channel']);
+            $package = strtolower($parent['package']);
+        }
+
+        if (is_object($child)) {
+            $depchannel = strtolower($child->getChannel());
+            $deppackage = strtolower($child->getPackage());
+        } else {
+            $depchannel = strtolower($child['channel']);
+            $deppackage = strtolower($child['package']);
+        }
+
+        if (isset($checked[$channel][$package][$depchannel][$deppackage])) {
+            return false; // avoid endless recursion
+        }
+
+        $checked[$channel][$package][$depchannel][$deppackage] = true;
+        if (!isset($this->_cache['dependencies'][$channel][$package])) {
+            return false;
+        }
+
+        foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
+            if (isset($info['dep']['uri'])) {
+                if (is_object($child)) {
+                    if ($info['dep']['uri'] == $child->getURI()) {
+                        return true;
+                    }
+                } elseif (isset($child['uri'])) {
+                    if ($info['dep']['uri'] == $child['uri']) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            if (strtolower($info['dep']['channel']) == $depchannel &&
+                  strtolower($info['dep']['name']) == $deppackage) {
+                return true;
+            }
+        }
+
+        foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
+            if (isset($info['dep']['uri'])) {
+                if ($this->_dependsOn(array(
+                        'uri' => $info['dep']['uri'],
+                        'package' => $info['dep']['name']), $child, $checked)) {
+                    return true;
+                }
+            } else {
+                if ($this->_dependsOn(array(
+                        'channel' => $info['dep']['channel'],
+                        'package' => $info['dep']['name']), $child, $checked)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Register dependencies of a package that is being installed or upgraded
+     * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2
+     */
+    function installPackage(&$package)
+    {
+        $data = $this->_getDepDB();
+        unset($this->_cache);
+        $this->_setPackageDeps($data, $package);
+        $this->_writeDepDB($data);
+    }
+
+    /**
+     * Remove dependencies of a package that is being uninstalled, or upgraded.
+     *
+     * Upgraded packages first uninstall, then install
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have
+     *        indices 'channel' and 'package'
+     */
+    function uninstallPackage(&$pkg)
+    {
+        $data = $this->_getDepDB();
+        unset($this->_cache);
+        if (is_object($pkg)) {
+            $channel = strtolower($pkg->getChannel());
+            $package = strtolower($pkg->getPackage());
+        } else {
+            $channel = strtolower($pkg['channel']);
+            $package = strtolower($pkg['package']);
+        }
+
+        if (!isset($data['dependencies'][$channel][$package])) {
+            return true;
+        }
+
+        foreach ($data['dependencies'][$channel][$package] as $dep) {
+            $found      = false;
+            $depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']);
+            $depname    = strtolower($dep['dep']['name']);
+            if (isset($data['packages'][$depchannel][$depname])) {
+                foreach ($data['packages'][$depchannel][$depname] as $i => $info) {
+                    if ($info['channel'] == $channel && $info['package'] == $package) {
+                        $found = true;
+                        break;
+                    }
+                }
+            }
+
+            if ($found) {
+                unset($data['packages'][$depchannel][$depname][$i]);
+                if (!count($data['packages'][$depchannel][$depname])) {
+                    unset($data['packages'][$depchannel][$depname]);
+                    if (!count($data['packages'][$depchannel])) {
+                        unset($data['packages'][$depchannel]);
+                    }
+                } else {
+                    $data['packages'][$depchannel][$depname] =
+                        array_values($data['packages'][$depchannel][$depname]);
+                }
+            }
+        }
+
+        unset($data['dependencies'][$channel][$package]);
+        if (!count($data['dependencies'][$channel])) {
+            unset($data['dependencies'][$channel]);
+        }
+
+        if (!count($data['dependencies'])) {
+            unset($data['dependencies']);
+        }
+
+        if (!count($data['packages'])) {
+            unset($data['packages']);
+        }
+
+        $this->_writeDepDB($data);
+    }
+
+    /**
+     * Rebuild the dependency DB by reading registry entries.
+     * @return true|PEAR_Error
+     */
+    function rebuildDB()
+    {
+        $depdb = array('_version' => $this->_version);
+        if (!$this->hasWriteAccess()) {
+            // allow startup for read-only with older Registry
+            return $depdb;
+        }
+
+        $packages = $this->_registry->listAllPackages();
+        if (PEAR::isError($packages)) {
+            return $packages;
+        }
+
+        foreach ($packages as $channel => $ps) {
+            foreach ($ps as $package) {
+                $package = $this->_registry->getPackage($package, $channel);
+                if (PEAR::isError($package)) {
+                    return $package;
+                }
+                $this->_setPackageDeps($depdb, $package);
+            }
+        }
+
+        $error = $this->_writeDepDB($depdb);
+        if (PEAR::isError($error)) {
+            return $error;
+        }
+
+        $this->_cache = $depdb;
+        return true;
+    }
+
+    /**
+     * Register usage of the dependency DB to prevent race conditions
+     * @param int one of the LOCK_* constants
+     * @return true|PEAR_Error
+     * @access private
+     */
+    function _lock($mode = LOCK_EX)
+    {
+        if (stristr(php_uname(), 'Windows 9')) {
+            return true;
+        }
+
+        if ($mode != LOCK_UN && is_resource($this->_lockFp)) {
+            // XXX does not check type of lock (LOCK_SH/LOCK_EX)
+            return true;
+        }
+
+        $open_mode = 'w';
+        // XXX People reported problems with LOCK_SH and 'w'
+        if ($mode === LOCK_SH) {
+            if (!file_exists($this->_lockfile)) {
+                touch($this->_lockfile);
+            } elseif (!is_file($this->_lockfile)) {
+                return PEAR::raiseError('could not create Dependency lock file, ' .
+                    'it exists and is not a regular file');
+            }
+            $open_mode = 'r';
+        }
+
+        if (!is_resource($this->_lockFp)) {
+            $this->_lockFp = @fopen($this->_lockfile, $open_mode);
+        }
+
+        if (!is_resource($this->_lockFp)) {
+            return PEAR::raiseError("could not create Dependency lock file" .
+                                     (isset($php_errormsg) ? ": " . $php_errormsg : ""));
+        }
+
+        if (!(int)flock($this->_lockFp, $mode)) {
+            switch ($mode) {
+                case LOCK_SH: $str = 'shared';    break;
+                case LOCK_EX: $str = 'exclusive'; break;
+                case LOCK_UN: $str = 'unlock';    break;
+                default:      $str = 'unknown';   break;
+            }
+
+            return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)");
+        }
+
+        return true;
+    }
+
+    /**
+     * Release usage of dependency DB
+     * @return true|PEAR_Error
+     * @access private
+     */
+    function _unlock()
+    {
+        $ret = $this->_lock(LOCK_UN);
+        if (is_resource($this->_lockFp)) {
+            fclose($this->_lockFp);
+        }
+        $this->_lockFp = null;
+        return $ret;
+    }
+
+    /**
+     * Load the dependency database from disk, or return the cache
+     * @return array|PEAR_Error
+     */
+    function _getDepDB()
+    {
+        if (!$this->hasWriteAccess()) {
+            return array('_version' => $this->_version);
+        }
+
+        if (isset($this->_cache)) {
+            return $this->_cache;
+        }
+
+        if (!$fp = fopen($this->_depdb, 'r')) {
+            $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'");
+            return $err;
+        }
+
+        $rt = get_magic_quotes_runtime();
+        set_magic_quotes_runtime(0);
+        clearstatcache();
+        fclose($fp);
+        $data = unserialize(file_get_contents($this->_depdb));
+        set_magic_quotes_runtime($rt);
+        $this->_cache = $data;
+        return $data;
+    }
+
+    /**
+     * Write out the dependency database to disk
+     * @param array the database
+     * @return true|PEAR_Error
+     * @access private
+     */
+    function _writeDepDB(&$deps)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
+            return $e;
+        }
+
+        if (!$fp = fopen($this->_depdb, 'wb')) {
+            $this->_unlock();
+            return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing");
+        }
+
+        $rt = get_magic_quotes_runtime();
+        set_magic_quotes_runtime(0);
+        fwrite($fp, serialize($deps));
+        set_magic_quotes_runtime($rt);
+        fclose($fp);
+        $this->_unlock();
+        $this->_cache = $deps;
+        return true;
+    }
+
+    /**
+     * Register all dependencies from a package in the dependencies database, in essence
+     * "installing" the package's dependency information
+     * @param array the database
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @access private
+     */
+    function _setPackageDeps(&$data, &$pkg)
+    {
+        $pkg->setConfig($this->_config);
+        if ($pkg->getPackagexmlVersion() == '1.0') {
+            $gen = &$pkg->getDefaultGenerator();
+            $deps = $gen->dependenciesToV2();
+        } else {
+            $deps = $pkg->getDeps(true);
+        }
+
+        if (!$deps) {
+            return;
+        }
+
+        if (!is_array($data)) {
+            $data = array();
+        }
+
+        if (!isset($data['dependencies'])) {
+            $data['dependencies'] = array();
+        }
+
+        $channel = strtolower($pkg->getChannel());
+        $package = strtolower($pkg->getPackage());
+
+        if (!isset($data['dependencies'][$channel])) {
+            $data['dependencies'][$channel] = array();
+        }
+
+        $data['dependencies'][$channel][$package] = array();
+        if (isset($deps['required']['package'])) {
+            if (!isset($deps['required']['package'][0])) {
+                $deps['required']['package'] = array($deps['required']['package']);
+            }
+
+            foreach ($deps['required']['package'] as $dep) {
+                $this->_registerDep($data, $pkg, $dep, 'required');
+            }
+        }
+
+        if (isset($deps['optional']['package'])) {
+            if (!isset($deps['optional']['package'][0])) {
+                $deps['optional']['package'] = array($deps['optional']['package']);
+            }
+
+            foreach ($deps['optional']['package'] as $dep) {
+                $this->_registerDep($data, $pkg, $dep, 'optional');
+            }
+        }
+
+        if (isset($deps['required']['subpackage'])) {
+            if (!isset($deps['required']['subpackage'][0])) {
+                $deps['required']['subpackage'] = array($deps['required']['subpackage']);
+            }
+
+            foreach ($deps['required']['subpackage'] as $dep) {
+                $this->_registerDep($data, $pkg, $dep, 'required');
+            }
+        }
+
+        if (isset($deps['optional']['subpackage'])) {
+            if (!isset($deps['optional']['subpackage'][0])) {
+                $deps['optional']['subpackage'] = array($deps['optional']['subpackage']);
+            }
+
+            foreach ($deps['optional']['subpackage'] as $dep) {
+                $this->_registerDep($data, $pkg, $dep, 'optional');
+            }
+        }
+
+        if (isset($deps['group'])) {
+            if (!isset($deps['group'][0])) {
+                $deps['group'] = array($deps['group']);
+            }
+
+            foreach ($deps['group'] as $group) {
+                if (isset($group['package'])) {
+                    if (!isset($group['package'][0])) {
+                        $group['package'] = array($group['package']);
+                    }
+
+                    foreach ($group['package'] as $dep) {
+                        $this->_registerDep($data, $pkg, $dep, 'optional',
+                            $group['attribs']['name']);
+                    }
+                }
+
+                if (isset($group['subpackage'])) {
+                    if (!isset($group['subpackage'][0])) {
+                        $group['subpackage'] = array($group['subpackage']);
+                    }
+
+                    foreach ($group['subpackage'] as $dep) {
+                        $this->_registerDep($data, $pkg, $dep, 'optional',
+                            $group['attribs']['name']);
+                    }
+                }
+            }
+        }
+
+        if ($data['dependencies'][$channel][$package] == array()) {
+            unset($data['dependencies'][$channel][$package]);
+            if (!count($data['dependencies'][$channel])) {
+                unset($data['dependencies'][$channel]);
+            }
+        }
+    }
+
+    /**
+     * @param array the database
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @param array the specific dependency
+     * @param required|optional whether this is a required or an optional dep
+     * @param string|false dependency group this dependency is from, or false for ordinary dep
+     */
+    function _registerDep(&$data, &$pkg, $dep, $type, $group = false)
+    {
+        $info = array(
+            'dep'   => $dep,
+            'type'  => $type,
+            'group' => $group
+        );
+
+        $dep  = array_map('strtolower', $dep);
+        $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
+        if (!isset($data['dependencies'])) {
+            $data['dependencies'] = array();
+        }
+
+        $channel = strtolower($pkg->getChannel());
+        $package = strtolower($pkg->getPackage());
+
+        if (!isset($data['dependencies'][$channel])) {
+            $data['dependencies'][$channel] = array();
+        }
+
+        if (!isset($data['dependencies'][$channel][$package])) {
+            $data['dependencies'][$channel][$package] = array();
+        }
+
+        $data['dependencies'][$channel][$package][] = $info;
+        if (isset($data['packages'][$depchannel][$dep['name']])) {
+            $found = false;
+            foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) {
+                if ($p['channel'] == $channel && $p['package'] == $package) {
+                    $found = true;
+                    break;
+                }
+            }
+        } else {
+            if (!isset($data['packages'])) {
+                $data['packages'] = array();
+            }
+
+            if (!isset($data['packages'][$depchannel])) {
+                $data['packages'][$depchannel] = array();
+            }
+
+            if (!isset($data['packages'][$depchannel][$dep['name']])) {
+                $data['packages'][$depchannel][$dep['name']] = array();
+            }
+
+            $found = false;
+        }
+
+        if (!$found) {
+            $data['packages'][$depchannel][$dep['name']][] = array(
+                'channel' => $channel,
+                'package' => $package
+            );
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Downloader.php b/lib/php/PEAR/Downloader.php
new file mode 100644
index 00000000..71df797b
--- /dev/null
+++ b/lib/php/PEAR/Downloader.php
@@ -0,0 +1,1762 @@
+<?php
+/**
+ * PEAR_Downloader, the PEAR Installer's download utility class
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Martin Jansen <mj@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Downloader.php 287109 2009-08-11 18:50:30Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.3.0
+ */
+
+/**
+ * Needed for constants, extending
+ */
+require_once 'PEAR/Common.php';
+
+define('PEAR_INSTALLER_OK',       1);
+define('PEAR_INSTALLER_FAILED',   0);
+define('PEAR_INSTALLER_SKIPPED', -1);
+define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2);
+
+/**
+ * Administration class used to download anything from the internet (PEAR Packages,
+ * static URLs, xml files)
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Martin Jansen <mj@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.3.0
+ */
+class PEAR_Downloader extends PEAR_Common
+{
+    /**
+     * @var PEAR_Registry
+     * @access private
+     */
+    var $_registry;
+
+    /**
+     * Preferred Installation State (snapshot, devel, alpha, beta, stable)
+     * @var string|null
+     * @access private
+     */
+    var $_preferredState;
+
+    /**
+     * Options from command-line passed to Install.
+     *
+     * Recognized options:<br />
+     *  - onlyreqdeps   : install all required dependencies as well
+     *  - alldeps       : install all dependencies, including optional
+     *  - installroot   : base relative path to install files in
+     *  - force         : force a download even if warnings would prevent it
+     *  - nocompress    : download uncompressed tarballs
+     * @see PEAR_Command_Install
+     * @access private
+     * @var array
+     */
+    var $_options;
+
+    /**
+     * Downloaded Packages after a call to download().
+     *
+     * Format of each entry:
+     *
+     * <code>
+     * array('pkg' => 'package_name', 'file' => '/path/to/local/file',
+     *    'info' => array() // parsed package.xml
+     * );
+     * </code>
+     * @access private
+     * @var array
+     */
+    var $_downloadedPackages = array();
+
+    /**
+     * Packages slated for download.
+     *
+     * This is used to prevent downloading a package more than once should it be a dependency
+     * for two packages to be installed.
+     * Format of each entry:
+     *
+     * <pre>
+     * array('package_name1' => parsed package.xml, 'package_name2' => parsed package.xml,
+     * );
+     * </pre>
+     * @access private
+     * @var array
+     */
+    var $_toDownload = array();
+
+    /**
+     * Array of every package installed, with names lower-cased.
+     *
+     * Format:
+     * <code>
+     * array('package1' => 0, 'package2' => 1, );
+     * </code>
+     * @var array
+     */
+    var $_installed = array();
+
+    /**
+     * @var array
+     * @access private
+     */
+    var $_errorStack = array();
+
+    /**
+     * @var boolean
+     * @access private
+     */
+    var $_internalDownload = false;
+
+    /**
+     * Temporary variable used in sorting packages by dependency in {@link sortPkgDeps()}
+     * @var array
+     * @access private
+     */
+    var $_packageSortTree;
+
+    /**
+     * Temporary directory, or configuration value where downloads will occur
+     * @var string
+     */
+    var $_downloadDir;
+
+    /**
+     * @param PEAR_Frontend_*
+     * @param array
+     * @param PEAR_Config
+     */
+    function PEAR_Downloader(&$ui, $options, &$config)
+    {
+        parent::PEAR_Common();
+        $this->_options = $options;
+        $this->config = &$config;
+        $this->_preferredState = $this->config->get('preferred_state');
+        $this->ui = &$ui;
+        if (!$this->_preferredState) {
+            // don't inadvertantly use a non-set preferred_state
+            $this->_preferredState = null;
+        }
+
+        if (isset($this->_options['installroot'])) {
+            $this->config->setInstallRoot($this->_options['installroot']);
+        }
+        $this->_registry = &$config->getRegistry();
+
+        if (isset($this->_options['alldeps']) || isset($this->_options['onlyreqdeps'])) {
+            $this->_installed = $this->_registry->listAllPackages();
+            foreach ($this->_installed as $key => $unused) {
+                if (!count($unused)) {
+                    continue;
+                }
+                $strtolower = create_function('$a','return strtolower($a);');
+                array_walk($this->_installed[$key], $strtolower);
+            }
+        }
+    }
+
+    /**
+     * Attempt to discover a channel's remote capabilities from
+     * its server name
+     * @param string
+     * @return boolean
+     */
+    function discover($channel)
+    {
+        $this->log(1, 'Attempting to discover channel "' . $channel . '"...');
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        $callback = $this->ui ? array(&$this, '_downloadCallback') : null;
+        if (!class_exists('System')) {
+            require_once 'System.php';
+        }
+
+        $tmp = System::mktemp(array('-d'));
+        $a   = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false);
+        PEAR::popErrorHandling();
+        if (PEAR::isError($a)) {
+            // Attempt to fallback to https automatically.
+            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+            $this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...');
+            $a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false);
+            PEAR::popErrorHandling();
+            if (PEAR::isError($a)) {
+                return false;
+            }
+        }
+
+        list($a, $lastmodified) = $a;
+        if (!class_exists('PEAR_ChannelFile')) {
+            require_once 'PEAR/ChannelFile.php';
+        }
+
+        $b = new PEAR_ChannelFile;
+        if ($b->fromXmlFile($a)) {
+            unlink($a);
+            if ($this->config->get('auto_discover')) {
+                $this->_registry->addChannel($b, $lastmodified);
+                $alias = $b->getName();
+                if ($b->getName() == $this->_registry->channelName($b->getAlias())) {
+                    $alias = $b->getAlias();
+                }
+
+                $this->log(1, 'Auto-discovered channel "' . $channel .
+                    '", alias "' . $alias . '", adding to registry');
+            }
+
+            return true;
+        }
+
+        unlink($a);
+        return false;
+    }
+
+    /**
+     * For simpler unit-testing
+     * @param PEAR_Downloader
+     * @return PEAR_Downloader_Package
+     */
+    function &newDownloaderPackage(&$t)
+    {
+        if (!class_exists('PEAR_Downloader_Package')) {
+            require_once 'PEAR/Downloader/Package.php';
+        }
+        $a = &new PEAR_Downloader_Package($t);
+        return $a;
+    }
+
+    /**
+     * For simpler unit-testing
+     * @param PEAR_Config
+     * @param array
+     * @param array
+     * @param int
+     */
+    function &getDependency2Object(&$c, $i, $p, $s)
+    {
+        if (!class_exists('PEAR_Dependency2')) {
+            require_once 'PEAR/Dependency2.php';
+        }
+        $z = &new PEAR_Dependency2($c, $i, $p, $s);
+        return $z;
+    }
+
+    function &download($params)
+    {
+        if (!count($params)) {
+            $a = array();
+            return $a;
+        }
+
+        if (!isset($this->_registry)) {
+            $this->_registry = &$this->config->getRegistry();
+        }
+
+        $channelschecked = array();
+        // convert all parameters into PEAR_Downloader_Package objects
+        foreach ($params as $i => $param) {
+            $params[$i] = &$this->newDownloaderPackage($this);
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $err = $params[$i]->initialize($param);
+            PEAR::staticPopErrorHandling();
+            if (!$err) {
+                // skip parameters that were missed by preferred_state
+                continue;
+            }
+
+            if (PEAR::isError($err)) {
+                if (!isset($this->_options['soft']) && $err->getMessage() !== '') {
+                    $this->log(0, $err->getMessage());
+                }
+
+                $params[$i] = false;
+                if (is_object($param)) {
+                    $param = $param->getChannel() . '/' . $param->getPackage();
+                }
+
+                if (!isset($this->_options['soft'])) {
+                    $this->log(2, 'Package "' . $param . '" is not valid');
+                }
+
+                // Message logged above in a specific verbose mode, passing null to not show up on CLI
+                $this->pushError(null, PEAR_INSTALLER_SKIPPED);
+            } else {
+                do {
+                    if ($params[$i] && $params[$i]->getType() == 'local') {
+                        // bug #7090 skip channel.xml check for local packages
+                        break;
+                    }
+
+                    if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) &&
+                          !isset($this->_options['offline'])
+                    ) {
+                        $channelschecked[$params[$i]->getChannel()] = true;
+                        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+                        if (!class_exists('System')) {
+                            require_once 'System.php';
+                        }
+
+                        $curchannel = &$this->_registry->getChannel($params[$i]->getChannel());
+                        if (PEAR::isError($curchannel)) {
+                            PEAR::staticPopErrorHandling();
+                            return $this->raiseError($curchannel);
+                        }
+
+                        if (PEAR::isError($dir = $this->getDownloadDir())) {
+                            PEAR::staticPopErrorHandling();
+                            break;
+                        }
+
+                        $mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel());
+                        $url    = 'http://' . $mirror . '/channel.xml';
+                        $a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified());
+
+                        PEAR::staticPopErrorHandling();
+                        if (PEAR::isError($a) || !$a) {
+                            // Attempt fallback to https automatically
+                            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                            $a = $this->downloadHttp('https://' . $mirror .
+                                '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified());
+
+                            PEAR::staticPopErrorHandling();
+                            if (PEAR::isError($a) || !$a) {
+                                break;
+                            }
+                        }
+                        $this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' .
+                            'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $params[$i]->getChannel() .
+                            '" to update');
+                    }
+                } while (false);
+
+                if ($params[$i] && !isset($this->_options['downloadonly'])) {
+                    if (isset($this->_options['packagingroot'])) {
+                        $checkdir = $this->_prependPath(
+                            $this->config->get('php_dir', null, $params[$i]->getChannel()),
+                            $this->_options['packagingroot']);
+                    } else {
+                        $checkdir = $this->config->get('php_dir',
+                            null, $params[$i]->getChannel());
+                    }
+
+                    while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) {
+                        $checkdir = dirname($checkdir);
+                    }
+
+                    if ($checkdir == '.') {
+                        $checkdir = '/';
+                    }
+
+                    if (!is_writeable($checkdir)) {
+                        return PEAR::raiseError('Cannot install, php_dir for channel "' .
+                            $params[$i]->getChannel() . '" is not writeable by the current user');
+                    }
+                }
+            }
+        }
+
+        unset($channelschecked);
+        PEAR_Downloader_Package::removeDuplicates($params);
+        if (!count($params)) {
+            $a = array();
+            return $a;
+        }
+
+        if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) {
+            $reverify = true;
+            while ($reverify) {
+                $reverify = false;
+                foreach ($params as $i => $param) {
+                    //PHP Bug 40768 / PEAR Bug #10944
+                    //Nested foreaches fail in PHP 5.2.1
+                    key($params);
+                    $ret = $params[$i]->detectDependencies($params);
+                    if (PEAR::isError($ret)) {
+                        $reverify = true;
+                        $params[$i] = false;
+                        PEAR_Downloader_Package::removeDuplicates($params);
+                        if (!isset($this->_options['soft'])) {
+                            $this->log(0, $ret->getMessage());
+                        }
+                        continue 2;
+                    }
+                }
+            }
+        }
+
+        if (isset($this->_options['offline'])) {
+            $this->log(3, 'Skipping dependency download check, --offline specified');
+        }
+
+        if (!count($params)) {
+            $a = array();
+            return $a;
+        }
+
+        while (PEAR_Downloader_Package::mergeDependencies($params));
+        PEAR_Downloader_Package::removeDuplicates($params, true);
+        $errorparams = array();
+        if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) {
+            if (count($errorparams)) {
+                foreach ($errorparams as $param) {
+                    $name = $this->_registry->parsedPackageNameToString($param->getParsedPackage());
+                    $this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED);
+                }
+                $a = array();
+                return $a;
+            }
+        }
+
+        PEAR_Downloader_Package::removeInstalled($params);
+        if (!count($params)) {
+            $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED);
+            $a = array();
+            return $a;
+        }
+
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        $err = $this->analyzeDependencies($params);
+        PEAR::popErrorHandling();
+        if (!count($params)) {
+            $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED);
+            $a = array();
+            return $a;
+        }
+
+        $ret = array();
+        $newparams = array();
+        if (isset($this->_options['pretend'])) {
+            return $params;
+        }
+
+        $somefailed = false;
+        foreach ($params as $i => $package) {
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $pf = &$params[$i]->download();
+            PEAR::staticPopErrorHandling();
+            if (PEAR::isError($pf)) {
+                if (!isset($this->_options['soft'])) {
+                    $this->log(1, $pf->getMessage());
+                    $this->log(0, 'Error: cannot download "' .
+                        $this->_registry->parsedPackageNameToString($package->getParsedPackage(),
+                            true) .
+                        '"');
+                }
+                $somefailed = true;
+                continue;
+            }
+
+            $newparams[] = &$params[$i];
+            $ret[] = array(
+                'file' => $pf->getArchiveFile(),
+                'info' => &$pf,
+                'pkg'  => $pf->getPackage()
+            );
+        }
+
+        if ($somefailed) {
+            // remove params that did not download successfully
+            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+            $err = $this->analyzeDependencies($newparams, true);
+            PEAR::popErrorHandling();
+            if (!count($newparams)) {
+                $this->pushError('Download failed', PEAR_INSTALLER_FAILED);
+                $a = array();
+                return $a;
+            }
+        }
+
+        $this->_downloadedPackages = $ret;
+        return $newparams;
+    }
+
+    /**
+     * @param array all packages to be installed
+     */
+    function analyzeDependencies(&$params, $force = false)
+    {
+        $hasfailed = $failed = false;
+        if (isset($this->_options['downloadonly'])) {
+            return;
+        }
+
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $redo  = true;
+        $reset = false;
+        while ($redo) {
+            $redo = false;
+            foreach ($params as $i => $param) {
+                $deps = $param->getDeps();
+                if (!$deps) {
+                    $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(),
+                        $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING);
+                    $send = $param->getPackageFile();
+
+                    $installcheck = $depchecker->validatePackage($send, $this, $params);
+                    if (PEAR::isError($installcheck)) {
+                        if (!isset($this->_options['soft'])) {
+                            $this->log(0, $installcheck->getMessage());
+                        }
+                        $hasfailed  = true;
+                        $params[$i] = false;
+                        $reset      = true;
+                        $redo       = true;
+                        $failed     = false;
+                        PEAR_Downloader_Package::removeDuplicates($params);
+                        continue 2;
+                    }
+                    continue;
+                }
+
+                if (!$reset && $param->alreadyValidated() && !$force) {
+                    continue;
+                }
+
+                if (count($deps)) {
+                    $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(),
+                        $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING);
+                    $send = $param->getPackageFile();
+                    if ($send === null) {
+                        $send = $param->getDownloadURL();
+                    }
+
+                    $installcheck = $depchecker->validatePackage($send, $this, $params);
+                    if (PEAR::isError($installcheck)) {
+                        if (!isset($this->_options['soft'])) {
+                            $this->log(0, $installcheck->getMessage());
+                        }
+                        $hasfailed  = true;
+                        $params[$i] = false;
+                        $reset      = true;
+                        $redo       = true;
+                        $failed     = false;
+                        PEAR_Downloader_Package::removeDuplicates($params);
+                        continue 2;
+                    }
+
+                    $failed = false;
+                    if (isset($deps['required'])) {
+                        foreach ($deps['required'] as $type => $dep) {
+                            // note: Dependency2 will never return a PEAR_Error if ignore-errors
+                            // is specified, so soft is needed to turn off logging
+                            if (!isset($dep[0])) {
+                                if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep,
+                                      true, $params))) {
+                                    $failed = true;
+                                    if (!isset($this->_options['soft'])) {
+                                        $this->log(0, $e->getMessage());
+                                    }
+                                } elseif (is_array($e) && !$param->alreadyValidated()) {
+                                    if (!isset($this->_options['soft'])) {
+                                        $this->log(0, $e[0]);
+                                    }
+                                }
+                            } else {
+                                foreach ($dep as $d) {
+                                    if (PEAR::isError($e =
+                                          $depchecker->{"validate{$type}Dependency"}($d,
+                                          true, $params))) {
+                                        $failed = true;
+                                        if (!isset($this->_options['soft'])) {
+                                            $this->log(0, $e->getMessage());
+                                        }
+                                    } elseif (is_array($e) && !$param->alreadyValidated()) {
+                                        if (!isset($this->_options['soft'])) {
+                                            $this->log(0, $e[0]);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        if (isset($deps['optional'])) {
+                            foreach ($deps['optional'] as $type => $dep) {
+                                if (!isset($dep[0])) {
+                                    if (PEAR::isError($e =
+                                          $depchecker->{"validate{$type}Dependency"}($dep,
+                                          false, $params))) {
+                                        $failed = true;
+                                        if (!isset($this->_options['soft'])) {
+                                            $this->log(0, $e->getMessage());
+                                        }
+                                    } elseif (is_array($e) && !$param->alreadyValidated()) {
+                                        if (!isset($this->_options['soft'])) {
+                                            $this->log(0, $e[0]);
+                                        }
+                                    }
+                                } else {
+                                    foreach ($dep as $d) {
+                                        if (PEAR::isError($e =
+                                              $depchecker->{"validate{$type}Dependency"}($d,
+                                              false, $params))) {
+                                            $failed = true;
+                                            if (!isset($this->_options['soft'])) {
+                                                $this->log(0, $e->getMessage());
+                                            }
+                                        } elseif (is_array($e) && !$param->alreadyValidated()) {
+                                            if (!isset($this->_options['soft'])) {
+                                                $this->log(0, $e[0]);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        $groupname = $param->getGroup();
+                        if (isset($deps['group']) && $groupname) {
+                            if (!isset($deps['group'][0])) {
+                                $deps['group'] = array($deps['group']);
+                            }
+
+                            $found = false;
+                            foreach ($deps['group'] as $group) {
+                                if ($group['attribs']['name'] == $groupname) {
+                                    $found = true;
+                                    break;
+                                }
+                            }
+
+                            if ($found) {
+                                unset($group['attribs']);
+                                foreach ($group as $type => $dep) {
+                                    if (!isset($dep[0])) {
+                                        if (PEAR::isError($e =
+                                              $depchecker->{"validate{$type}Dependency"}($dep,
+                                              false, $params))) {
+                                            $failed = true;
+                                            if (!isset($this->_options['soft'])) {
+                                                $this->log(0, $e->getMessage());
+                                            }
+                                        } elseif (is_array($e) && !$param->alreadyValidated()) {
+                                            if (!isset($this->_options['soft'])) {
+                                                $this->log(0, $e[0]);
+                                            }
+                                        }
+                                    } else {
+                                        foreach ($dep as $d) {
+                                            if (PEAR::isError($e =
+                                                  $depchecker->{"validate{$type}Dependency"}($d,
+                                                  false, $params))) {
+                                                $failed = true;
+                                                if (!isset($this->_options['soft'])) {
+                                                    $this->log(0, $e->getMessage());
+                                                }
+                                            } elseif (is_array($e) && !$param->alreadyValidated()) {
+                                                if (!isset($this->_options['soft'])) {
+                                                    $this->log(0, $e[0]);
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    } else {
+                        foreach ($deps as $dep) {
+                            if (PEAR::isError($e = $depchecker->validateDependency1($dep, $params))) {
+                                $failed = true;
+                                if (!isset($this->_options['soft'])) {
+                                    $this->log(0, $e->getMessage());
+                                }
+                            } elseif (is_array($e) && !$param->alreadyValidated()) {
+                                if (!isset($this->_options['soft'])) {
+                                    $this->log(0, $e[0]);
+                                }
+                            }
+                        }
+                    }
+                    $params[$i]->setValidated();
+                }
+
+                if ($failed) {
+                    $hasfailed  = true;
+                    $params[$i] = false;
+                    $reset      = true;
+                    $redo       = true;
+                    $failed     = false;
+                    PEAR_Downloader_Package::removeDuplicates($params);
+                    continue 2;
+                }
+            }
+        }
+        PEAR::staticPopErrorHandling();
+        if ($hasfailed && (isset($this->_options['ignore-errors']) ||
+              isset($this->_options['nodeps']))) {
+            // this is probably not needed, but just in case
+            if (!isset($this->_options['soft'])) {
+                $this->log(0, 'WARNING: dependencies failed');
+            }
+        }
+    }
+
+    /**
+     * Retrieve the directory that downloads will happen in
+     * @access private
+     * @return string
+     */
+    function getDownloadDir()
+    {
+        if (isset($this->_downloadDir)) {
+            return $this->_downloadDir;
+        }
+        $downloaddir = $this->config->get('download_dir');
+        if (empty($downloaddir) || (is_dir($downloaddir) && !is_writable($downloaddir))) {
+            if  (is_dir($downloaddir) && !is_writable($downloaddir)) {
+                $this->log(0, 'WARNING: configuration download directory "' . $downloaddir .
+                    '" is not writeable.  Change download_dir config variable to ' .
+                    'a writeable dir to avoid this warning');
+            }
+            if (!class_exists('System')) {
+                require_once 'System.php';
+            }
+            if (PEAR::isError($downloaddir = System::mktemp('-d'))) {
+                return $downloaddir;
+            }
+            $this->log(3, '+ tmp dir created at ' . $downloaddir);
+        }
+        if (!is_writable($downloaddir)) {
+            if (PEAR::isError(System::mkdir(array('-p', $downloaddir))) ||
+                  !is_writable($downloaddir)) {
+                return PEAR::raiseError('download directory "' . $downloaddir .
+                    '" is not writeable.  Change download_dir config variable to ' .
+                    'a writeable dir');
+            }
+        }
+        return $this->_downloadDir = $downloaddir;
+    }
+
+    function setDownloadDir($dir)
+    {
+        if (!@is_writable($dir)) {
+            if (PEAR::isError(System::mkdir(array('-p', $dir)))) {
+                return PEAR::raiseError('download directory "' . $dir .
+                    '" is not writeable.  Change download_dir config variable to ' .
+                    'a writeable dir');
+            }
+        }
+        $this->_downloadDir = $dir;
+    }
+
+    function configSet($key, $value, $layer = 'user', $channel = false)
+    {
+        $this->config->set($key, $value, $layer, $channel);
+        $this->_preferredState = $this->config->get('preferred_state', null, $channel);
+        if (!$this->_preferredState) {
+            // don't inadvertantly use a non-set preferred_state
+            $this->_preferredState = null;
+        }
+    }
+
+    function setOptions($options)
+    {
+        $this->_options = $options;
+    }
+
+    // }}}
+    // {{{ setOptions()
+    function getOptions()
+    {
+        return $this->_options;
+    }
+
+    /**
+     * For simpler unit-testing
+     * @param PEAR_Config
+     * @param int
+     * @param string
+     */
+    function &getPackagefileObject(&$c, $d, $t = false)
+    {
+        if (!class_exists('PEAR_PackageFile')) {
+            require_once 'PEAR/PackageFile.php';
+        }
+        $a = &new PEAR_PackageFile($c, $d, $t);
+        return $a;
+    }
+
+    /**
+     * @param array output of {@link parsePackageName()}
+     * @access private
+     */
+    function _getPackageDownloadUrl($parr)
+    {
+        $curchannel = $this->config->get('default_channel');
+        $this->configSet('default_channel', $parr['channel']);
+        // getDownloadURL returns an array.  On error, it only contains information
+        // on the latest release as array(version, info).  On success it contains
+        // array(version, info, download url string)
+        $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state');
+        if (!$this->_registry->channelExists($parr['channel'])) {
+            do {
+                if ($this->config->get('auto_discover') && $this->discover($parr['channel'])) {
+                    break;
+                }
+
+                $this->configSet('default_channel', $curchannel);
+                return PEAR::raiseError('Unknown remote channel: ' . $parr['channel']);
+            } while (false);
+        }
+
+        $chan = &$this->_registry->getChannel($parr['channel']);
+        if (PEAR::isError($chan)) {
+            return $chan;
+        }
+
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $version   = $this->_registry->packageInfo($parr['package'], 'version', $parr['channel']);
+        $stability = $this->_registry->packageInfo($parr['package'], 'stability', $parr['channel']);
+        // package is installed - use the installed release stability level
+        if (!isset($parr['state']) && $stability !== null) {
+            $state = $stability['release'];
+        }
+        PEAR::staticPopErrorHandling();
+        $base2 = false;
+
+        $preferred_mirror = $this->config->get('preferred_mirror');
+        if (!$chan->supportsREST($preferred_mirror) ||
+              (
+               !($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror))
+               &&
+               !($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
+              )
+        ) {
+            return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.');
+        }
+
+        if ($base2) {
+            $rest = &$this->config->getREST('1.3', $this->_options);
+            $base = $base2;
+        } else {
+            $rest = &$this->config->getREST('1.0', $this->_options);
+        }
+
+        $downloadVersion = false;
+        if (!isset($parr['version']) && !isset($parr['state']) && $version
+              && !PEAR::isError($version)
+              && !isset($this->_options['downloadonly'])
+        ) {
+            $downloadVersion = $version;
+        }
+
+        $url = $rest->getDownloadURL($base, $parr, $state, $downloadVersion, $chan->getName());
+        if (PEAR::isError($url)) {
+            $this->configSet('default_channel', $curchannel);
+            return $url;
+        }
+
+        if ($parr['channel'] != $curchannel) {
+            $this->configSet('default_channel', $curchannel);
+        }
+
+        if (!is_array($url)) {
+            return $url;
+        }
+
+        $url['raw'] = false; // no checking is necessary for REST
+        if (!is_array($url['info'])) {
+            return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' .
+                'this should never happen');
+        }
+
+        if (!isset($this->_options['force']) &&
+              !isset($this->_options['downloadonly']) &&
+              $version &&
+              !PEAR::isError($version) &&
+              !isset($parr['group'])
+        ) {
+            if (version_compare($version, $url['version'], '=')) {
+                return PEAR::raiseError($this->_registry->parsedPackageNameToString(
+                    $parr, true) . ' is already installed and is the same as the ' .
+                    'released version ' . $url['version'], -976);
+            }
+
+            if (version_compare($version, $url['version'], '>')) {
+                return PEAR::raiseError($this->_registry->parsedPackageNameToString(
+                    $parr, true) . ' is already installed and is newer than detected ' .
+                    'released version ' . $url['version'], -976);
+            }
+        }
+
+        if (isset($url['info']['required']) || $url['compatible']) {
+            require_once 'PEAR/PackageFile/v2.php';
+            $pf = new PEAR_PackageFile_v2;
+            $pf->setRawChannel($parr['channel']);
+            if ($url['compatible']) {
+                $pf->setRawCompatible($url['compatible']);
+            }
+        } else {
+            require_once 'PEAR/PackageFile/v1.php';
+            $pf = new PEAR_PackageFile_v1;
+        }
+
+        $pf->setRawPackage($url['package']);
+        $pf->setDeps($url['info']);
+        if ($url['compatible']) {
+            $pf->setCompatible($url['compatible']);
+        }
+
+        $pf->setRawState($url['stability']);
+        $url['info'] = &$pf;
+        if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
+            $ext = '.tar';
+        } else {
+            $ext = '.tgz';
+        }
+
+        if (is_array($url) && isset($url['url'])) {
+            $url['url'] .= $ext;
+        }
+
+        return $url;
+    }
+
+    /**
+     * @param array dependency array
+     * @access private
+     */
+    function _getDepPackageDownloadUrl($dep, $parr)
+    {
+        $xsdversion = isset($dep['rel']) ? '1.0' : '2.0';
+        $curchannel = $this->config->get('default_channel');
+        if (isset($dep['uri'])) {
+            $xsdversion = '2.0';
+            $chan = &$this->_registry->getChannel('__uri');
+            if (PEAR::isError($chan)) {
+                return $chan;
+            }
+
+            $version = $this->_registry->packageInfo($dep['name'], 'version', '__uri');
+            $this->configSet('default_channel', '__uri');
+        } else {
+            if (isset($dep['channel'])) {
+                $remotechannel = $dep['channel'];
+            } else {
+                $remotechannel = 'pear.php.net';
+            }
+
+            if (!$this->_registry->channelExists($remotechannel)) {
+                do {
+                    if ($this->config->get('auto_discover')) {
+                        if ($this->discover($remotechannel)) {
+                            break;
+                        }
+                    }
+                    return PEAR::raiseError('Unknown remote channel: ' . $remotechannel);
+                } while (false);
+            }
+
+            $chan = &$this->_registry->getChannel($remotechannel);
+            if (PEAR::isError($chan)) {
+                return $chan;
+            }
+
+            $version = $this->_registry->packageInfo($dep['name'], 'version', $remotechannel);
+            $this->configSet('default_channel', $remotechannel);
+        }
+
+        $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state');
+        if (isset($parr['state']) && isset($parr['version'])) {
+            unset($parr['state']);
+        }
+
+        if (isset($dep['uri'])) {
+            $info = &$this->newDownloaderPackage($this);
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $err = $info->initialize($dep);
+            PEAR::staticPopErrorHandling();
+            if (!$err) {
+                // skip parameters that were missed by preferred_state
+                return PEAR::raiseError('Cannot initialize dependency');
+            }
+
+            if (PEAR::isError($err)) {
+                if (!isset($this->_options['soft'])) {
+                    $this->log(0, $err->getMessage());
+                }
+
+                if (is_object($info)) {
+                    $param = $info->getChannel() . '/' . $info->getPackage();
+                }
+                return PEAR::raiseError('Package "' . $param . '" is not valid');
+            }
+            return $info;
+        } elseif ($chan->supportsREST($this->config->get('preferred_mirror'))
+              && $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))
+        ) {
+            $rest = &$this->config->getREST('1.0', $this->_options);
+            $url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr,
+                    $state, $version, $chan->getName());
+            if (PEAR::isError($url)) {
+                return $url;
+            }
+
+            if ($parr['channel'] != $curchannel) {
+                $this->configSet('default_channel', $curchannel);
+            }
+
+            if (!is_array($url)) {
+                return $url;
+            }
+
+            $url['raw'] = false; // no checking is necessary for REST
+            if (!is_array($url['info'])) {
+                return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' .
+                    'this should never happen');
+            }
+
+            if (isset($url['info']['required'])) {
+                if (!class_exists('PEAR_PackageFile_v2')) {
+                    require_once 'PEAR/PackageFile/v2.php';
+                }
+                $pf = new PEAR_PackageFile_v2;
+                $pf->setRawChannel($remotechannel);
+            } else {
+                if (!class_exists('PEAR_PackageFile_v1')) {
+                    require_once 'PEAR/PackageFile/v1.php';
+                }
+                $pf = new PEAR_PackageFile_v1;
+
+            }
+            $pf->setRawPackage($url['package']);
+            $pf->setDeps($url['info']);
+            if ($url['compatible']) {
+                $pf->setCompatible($url['compatible']);
+            }
+
+            $pf->setRawState($url['stability']);
+            $url['info'] = &$pf;
+            if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
+                $ext = '.tar';
+            } else {
+                $ext = '.tgz';
+            }
+
+            if (is_array($url) && isset($url['url'])) {
+                $url['url'] .= $ext;
+            }
+
+            return $url;
+        }
+
+        return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.');
+    }
+
+    /**
+     * @deprecated in favor of _getPackageDownloadUrl
+     */
+    function getPackageDownloadUrl($package, $version = null, $channel = false)
+    {
+        if ($version) {
+            $package .= "-$version";
+        }
+        if ($this === null || $this->_registry === null) {
+            $package = "http://pear.php.net/get/$package";
+        } else {
+            $chan = $this->_registry->getChannel($channel);
+            if (PEAR::isError($chan)) {
+                return '';
+            }
+            $package = "http://" . $chan->getServer() . "/get/$package";
+        }
+        if (!extension_loaded("zlib")) {
+            $package .= '?uncompress=yes';
+        }
+        return $package;
+    }
+
+    /**
+     * Retrieve a list of downloaded packages after a call to {@link download()}.
+     *
+     * Also resets the list of downloaded packages.
+     * @return array
+     */
+    function getDownloadedPackages()
+    {
+        $ret = $this->_downloadedPackages;
+        $this->_downloadedPackages = array();
+        $this->_toDownload = array();
+        return $ret;
+    }
+
+    function _downloadCallback($msg, $params = null)
+    {
+        switch ($msg) {
+            case 'saveas':
+                $this->log(1, "downloading $params ...");
+                break;
+            case 'done':
+                $this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes');
+                break;
+            case 'bytesread':
+                static $bytes;
+                if (empty($bytes)) {
+                    $bytes = 0;
+                }
+                if (!($bytes % 10240)) {
+                    $this->log(1, '.', false);
+                }
+                $bytes += $params;
+                break;
+            case 'start':
+                if($params[1] == -1) {
+                    $length = "Unknown size";
+                } else {
+                    $length = number_format($params[1], 0, '', ',')." bytes";
+                }
+                $this->log(1, "Starting to download {$params[0]} ($length)");
+                break;
+        }
+        if (method_exists($this->ui, '_downloadCallback'))
+            $this->ui->_downloadCallback($msg, $params);
+    }
+
+    function _prependPath($path, $prepend)
+    {
+        if (strlen($prepend) > 0) {
+            if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) {
+                if (preg_match('/^[a-z]:/i', $prepend)) {
+                    $prepend = substr($prepend, 2);
+                } elseif ($prepend{0} != '\\') {
+                    $prepend = "\\$prepend";
+                }
+                $path = substr($path, 0, 2) . $prepend . substr($path, 2);
+            } else {
+                $path = $prepend . $path;
+            }
+        }
+        return $path;
+    }
+
+    /**
+     * @param string
+     * @param integer
+     */
+    function pushError($errmsg, $code = -1)
+    {
+        array_push($this->_errorStack, array($errmsg, $code));
+    }
+
+    function getErrorMsgs()
+    {
+        $msgs = array();
+        $errs = $this->_errorStack;
+        foreach ($errs as $err) {
+            $msgs[] = $err[0];
+        }
+        $this->_errorStack = array();
+        return $msgs;
+    }
+
+    /**
+     * for BC
+     *
+     * @deprecated
+     */
+    function sortPkgDeps(&$packages, $uninstall = false)
+    {
+        $uninstall ?
+            $this->sortPackagesForUninstall($packages) :
+            $this->sortPackagesForInstall($packages);
+    }
+
+    /**
+     * Sort a list of arrays of array(downloaded packagefilename) by dependency.
+     *
+     * This uses the topological sort method from graph theory, and the
+     * Structures_Graph package to properly sort dependencies for installation.
+     * @param array an array of downloaded PEAR_Downloader_Packages
+     * @return array array of array(packagefilename, package.xml contents)
+     */
+    function sortPackagesForInstall(&$packages)
+    {
+        require_once 'Structures/Graph.php';
+        require_once 'Structures/Graph/Node.php';
+        require_once 'Structures/Graph/Manipulator/TopologicalSorter.php';
+        $depgraph = new Structures_Graph(true);
+        $nodes = array();
+        $reg = &$this->config->getRegistry();
+        foreach ($packages as $i => $package) {
+            $pname = $reg->parsedPackageNameToString(
+                array(
+                    'channel' => $package->getChannel(),
+                    'package' => strtolower($package->getPackage()),
+                ));
+            $nodes[$pname] = new Structures_Graph_Node;
+            $nodes[$pname]->setData($packages[$i]);
+            $depgraph->addNode($nodes[$pname]);
+        }
+
+        $deplinks = array();
+        foreach ($nodes as $package => $node) {
+            $pf = &$node->getData();
+            $pdeps = $pf->getDeps(true);
+            if (!$pdeps) {
+                continue;
+            }
+
+            if ($pf->getPackagexmlVersion() == '1.0') {
+                foreach ($pdeps as $dep) {
+                    if ($dep['type'] != 'pkg' ||
+                          (isset($dep['optional']) && $dep['optional'] == 'yes')) {
+                        continue;
+                    }
+
+                    $dname = $reg->parsedPackageNameToString(
+                          array(
+                              'channel' => 'pear.php.net',
+                              'package' => strtolower($dep['name']),
+                          ));
+
+                    if (isset($nodes[$dname])) {
+                        if (!isset($deplinks[$dname])) {
+                            $deplinks[$dname] = array();
+                        }
+
+                        $deplinks[$dname][$package] = 1;
+                        // dependency is in installed packages
+                        continue;
+                    }
+
+                    $dname = $reg->parsedPackageNameToString(
+                          array(
+                              'channel' => 'pecl.php.net',
+                              'package' => strtolower($dep['name']),
+                          ));
+
+                    if (isset($nodes[$dname])) {
+                        if (!isset($deplinks[$dname])) {
+                            $deplinks[$dname] = array();
+                        }
+
+                        $deplinks[$dname][$package] = 1;
+                        // dependency is in installed packages
+                        continue;
+                    }
+                }
+            } else {
+                // the only ordering we care about is:
+                // 1) subpackages must be installed before packages that depend on them
+                // 2) required deps must be installed before packages that depend on them
+                if (isset($pdeps['required']['subpackage'])) {
+                    $t = $pdeps['required']['subpackage'];
+                    if (!isset($t[0])) {
+                        $t = array($t);
+                    }
+
+                    $this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
+                }
+
+                if (isset($pdeps['group'])) {
+                    if (!isset($pdeps['group'][0])) {
+                        $pdeps['group'] = array($pdeps['group']);
+                    }
+
+                    foreach ($pdeps['group'] as $group) {
+                        if (isset($group['subpackage'])) {
+                            $t = $group['subpackage'];
+                            if (!isset($t[0])) {
+                                $t = array($t);
+                            }
+
+                            $this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
+                        }
+                    }
+                }
+
+                if (isset($pdeps['optional']['subpackage'])) {
+                    $t = $pdeps['optional']['subpackage'];
+                    if (!isset($t[0])) {
+                        $t = array($t);
+                    }
+
+                    $this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
+                }
+
+                if (isset($pdeps['required']['package'])) {
+                    $t = $pdeps['required']['package'];
+                    if (!isset($t[0])) {
+                        $t = array($t);
+                    }
+
+                    $this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
+                }
+
+                if (isset($pdeps['group'])) {
+                    if (!isset($pdeps['group'][0])) {
+                        $pdeps['group'] = array($pdeps['group']);
+                    }
+
+                    foreach ($pdeps['group'] as $group) {
+                        if (isset($group['package'])) {
+                            $t = $group['package'];
+                            if (!isset($t[0])) {
+                                $t = array($t);
+                            }
+
+                            $this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
+                        }
+                    }
+                }
+            }
+        }
+
+        $this->_detectDepCycle($deplinks);
+        foreach ($deplinks as $dependent => $parents) {
+            foreach ($parents as $parent => $unused) {
+                $nodes[$dependent]->connectTo($nodes[$parent]);
+            }
+        }
+
+        $installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph);
+        $ret = array();
+        for ($i = 0, $count = count($installOrder); $i < $count; $i++) {
+            foreach ($installOrder[$i] as $index => $sortedpackage) {
+                $data = &$installOrder[$i][$index]->getData();
+                $ret[] = &$nodes[$reg->parsedPackageNameToString(
+                          array(
+                              'channel' => $data->getChannel(),
+                              'package' => strtolower($data->getPackage()),
+                          ))]->getData();
+            }
+        }
+
+        $packages = $ret;
+        return;
+    }
+
+    /**
+     * Detect recursive links between dependencies and break the cycles
+     *
+     * @param array
+     * @access private
+     */
+    function _detectDepCycle(&$deplinks)
+    {
+        do {
+            $keepgoing = false;
+            foreach ($deplinks as $dep => $parents) {
+                foreach ($parents as $parent => $unused) {
+                    // reset the parent cycle detector
+                    $this->_testCycle(null, null, null);
+                    if ($this->_testCycle($dep, $deplinks, $parent)) {
+                        $keepgoing = true;
+                        unset($deplinks[$dep][$parent]);
+                        if (count($deplinks[$dep]) == 0) {
+                            unset($deplinks[$dep]);
+                        }
+
+                        continue 3;
+                    }
+                }
+            }
+        } while ($keepgoing);
+    }
+
+    function _testCycle($test, $deplinks, $dep)
+    {
+        static $visited = array();
+        if ($test === null) {
+            $visited = array();
+            return;
+        }
+
+        // this happens when a parent has a dep cycle on another dependency
+        // but the child is not part of the cycle
+        if (isset($visited[$dep])) {
+            return false;
+        }
+
+        $visited[$dep] = 1;
+        if ($test == $dep) {
+            return true;
+        }
+
+        if (isset($deplinks[$dep])) {
+            if (in_array($test, array_keys($deplinks[$dep]), true)) {
+                return true;
+            }
+
+            foreach ($deplinks[$dep] as $parent => $unused) {
+                if ($this->_testCycle($test, $deplinks, $parent)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Set up the dependency for installation parsing
+     *
+     * @param array $t dependency information
+     * @param PEAR_Registry $reg
+     * @param array $deplinks list of dependency links already established
+     * @param array $nodes all existing package nodes
+     * @param string $package parent package name
+     * @access private
+     */
+    function _setupGraph($t, $reg, &$deplinks, &$nodes, $package)
+    {
+        foreach ($t as $dep) {
+            $depchannel = !isset($dep['channel']) ? '__uri': $dep['channel'];
+            $dname = $reg->parsedPackageNameToString(
+                  array(
+                      'channel' => $depchannel,
+                      'package' => strtolower($dep['name']),
+                  ));
+
+            if (isset($nodes[$dname])) {
+                if (!isset($deplinks[$dname])) {
+                    $deplinks[$dname] = array();
+                }
+                $deplinks[$dname][$package] = 1;
+            }
+        }
+    }
+
+    function _dependsOn($a, $b)
+    {
+        return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()), $b);
+    }
+
+    function _checkDepTree($channel, $package, $b, $checked = array())
+    {
+        $checked[$channel][$package] = true;
+        if (!isset($this->_depTree[$channel][$package])) {
+            return false;
+        }
+
+        if (isset($this->_depTree[$channel][$package][strtolower($b->getChannel())]
+              [strtolower($b->getPackage())])) {
+            return true;
+        }
+
+        foreach ($this->_depTree[$channel][$package] as $ch => $packages) {
+            foreach ($packages as $pa => $true) {
+                if ($this->_checkDepTree($ch, $pa, $b, $checked)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    function _sortInstall($a, $b)
+    {
+        if (!$a->getDeps() && !$b->getDeps()) {
+            return 0; // neither package has dependencies, order is insignificant
+        }
+        if ($a->getDeps() && !$b->getDeps()) {
+            return 1; // $a must be installed after $b because $a has dependencies
+        }
+        if (!$a->getDeps() && $b->getDeps()) {
+            return -1; // $b must be installed after $a because $b has dependencies
+        }
+        // both packages have dependencies
+        if ($this->_dependsOn($a, $b)) {
+            return 1;
+        }
+        if ($this->_dependsOn($b, $a)) {
+            return -1;
+        }
+        return 0;
+    }
+
+    /**
+     * Download a file through HTTP.  Considers suggested file name in
+     * Content-disposition: header and can run a callback function for
+     * different events.  The callback will be called with two
+     * parameters: the callback type, and parameters.  The implemented
+     * callback types are:
+     *
+     *  'setup'       called at the very beginning, parameter is a UI object
+     *                that should be used for all output
+     *  'message'     the parameter is a string with an informational message
+     *  'saveas'      may be used to save with a different file name, the
+     *                parameter is the filename that is about to be used.
+     *                If a 'saveas' callback returns a non-empty string,
+     *                that file name will be used as the filename instead.
+     *                Note that $save_dir will not be affected by this, only
+     *                the basename of the file.
+     *  'start'       download is starting, parameter is number of bytes
+     *                that are expected, or -1 if unknown
+     *  'bytesread'   parameter is the number of bytes read so far
+     *  'done'        download is complete, parameter is the total number
+     *                of bytes read
+     *  'connfailed'  if the TCP/SSL connection fails, this callback is called
+     *                with array(host,port,errno,errmsg)
+     *  'writefailed' if writing to disk fails, this callback is called
+     *                with array(destfile,errmsg)
+     *
+     * If an HTTP proxy has been configured (http_proxy PEAR_Config
+     * setting), the proxy will be used.
+     *
+     * @param string  $url       the URL to download
+     * @param object  $ui        PEAR_Frontend_* instance
+     * @param object  $config    PEAR_Config instance
+     * @param string  $save_dir  directory to save file in
+     * @param mixed   $callback  function/method to call for status
+     *                           updates
+     * @param false|string|array $lastmodified header values to check against for caching
+     *                           use false to return the header values from this download
+     * @param false|array $accept Accept headers to send
+     * @param false|string $channel Channel to use for retrieving authentication
+     * @return string|array  Returns the full path of the downloaded file or a PEAR
+     *                       error on failure.  If the error is caused by
+     *                       socket-related errors, the error object will
+     *                       have the fsockopen error code available through
+     *                       getCode().  If caching is requested, then return the header
+     *                       values.
+     *
+     * @access public
+     */
+    function downloadHttp($url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null,
+                          $accept = false, $channel = false)
+    {
+        static $redirect = 0;
+        // always reset , so we are clean case of error
+        $wasredirect = $redirect;
+        $redirect = 0;
+        if ($callback) {
+            call_user_func($callback, 'setup', array(&$ui));
+        }
+
+        $info = parse_url($url);
+        if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) {
+            return PEAR::raiseError('Cannot download non-http URL "' . $url . '"');
+        }
+
+        if (!isset($info['host'])) {
+            return PEAR::raiseError('Cannot download from non-URL "' . $url . '"');
+        }
+
+        $host = isset($info['host']) ? $info['host'] : null;
+        $port = isset($info['port']) ? $info['port'] : null;
+        $path = isset($info['path']) ? $info['path'] : null;
+
+        if (isset($this)) {
+            $config = &$this->config;
+        } else {
+            $config = &PEAR_Config::singleton();
+        }
+
+        $proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
+        if ($config->get('http_proxy') &&
+              $proxy = parse_url($config->get('http_proxy'))) {
+            $proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
+            if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
+                $proxy_host = 'ssl://' . $proxy_host;
+            }
+            $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
+            $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
+            $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
+
+            if ($callback) {
+                call_user_func($callback, 'message', "Using HTTP proxy $host:$port");
+            }
+        }
+
+        if (empty($port)) {
+            $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80;
+        }
+
+        $scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http';
+
+        if ($proxy_host != '') {
+            $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr);
+            if (!$fp) {
+                if ($callback) {
+                    call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port,
+                                                                  $errno, $errstr));
+                }
+                return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno);
+            }
+
+            if ($lastmodified === false || $lastmodified) {
+                $request  = "GET $url HTTP/1.1\r\n";
+                $request .= "Host: $host:$port\r\n";
+            } else {
+                $request  = "GET $url HTTP/1.0\r\n";
+                $request .= "Host: $host\r\n";
+            }
+        } else {
+            $network_host = $host;
+            if (isset($info['scheme']) && $info['scheme'] == 'https') {
+                $network_host = 'ssl://' . $host;
+            }
+
+            $fp = @fsockopen($network_host, $port, $errno, $errstr);
+            if (!$fp) {
+                if ($callback) {
+                    call_user_func($callback, 'connfailed', array($host, $port,
+                                                                  $errno, $errstr));
+                }
+                return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
+            }
+
+            if ($lastmodified === false || $lastmodified) {
+                $request = "GET $path HTTP/1.1\r\n";
+                $request .= "Host: $host:$port\r\n";
+            } else {
+                $request = "GET $path HTTP/1.0\r\n";
+                $request .= "Host: $host\r\n";
+            }
+        }
+
+        $ifmodifiedsince = '';
+        if (is_array($lastmodified)) {
+            if (isset($lastmodified['Last-Modified'])) {
+                $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n";
+            }
+
+            if (isset($lastmodified['ETag'])) {
+                $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n";
+            }
+        } else {
+            $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : '');
+        }
+
+        $request .= $ifmodifiedsince .
+            "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n";
+
+        if (isset($this)) { // only pass in authentication for non-static calls
+            $username = $config->get('username', null, $channel);
+            $password = $config->get('password', null, $channel);
+            if ($username && $password) {
+                $tmp = base64_encode("$username:$password");
+                $request .= "Authorization: Basic $tmp\r\n";
+            }
+        }
+
+        if ($proxy_host != '' && $proxy_user != '') {
+            $request .= 'Proxy-Authorization: Basic ' .
+                base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n";
+        }
+
+        if ($accept) {
+            $request .= 'Accept: ' . implode(', ', $accept) . "\r\n";
+        }
+
+        $request .= "Connection: close\r\n";
+        $request .= "\r\n";
+        fwrite($fp, $request);
+        $headers = array();
+        $reply = 0;
+        while (trim($line = fgets($fp, 1024))) {
+            if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) {
+                $headers[strtolower($matches[1])] = trim($matches[2]);
+            } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
+                $reply = (int)$matches[1];
+                if ($reply == 304 && ($lastmodified || ($lastmodified === false))) {
+                    return false;
+                }
+
+                if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) {
+                    return PEAR::raiseError("File $scheme://$host:$port$path not valid (received: $line)");
+                }
+            }
+        }
+
+        if ($reply != 200) {
+            if (!isset($headers['location'])) {
+                return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirected but no location)");
+            }
+
+            if ($wasredirect > 4) {
+                return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirection looped more than 5 times)");
+            }
+
+            $redirect = $wasredirect + 1;
+            return $this->downloadHttp($headers['location'],
+                    $ui, $save_dir, $callback, $lastmodified, $accept);
+        }
+
+        if (isset($headers['content-disposition']) &&
+            preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|\\z)/', $headers['content-disposition'], $matches)) {
+            $save_as = basename($matches[1]);
+        } else {
+            $save_as = basename($url);
+        }
+
+        if ($callback) {
+            $tmp = call_user_func($callback, 'saveas', $save_as);
+            if ($tmp) {
+                $save_as = $tmp;
+            }
+        }
+
+        $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as;
+        if (!$wp = @fopen($dest_file, 'wb')) {
+            fclose($fp);
+            if ($callback) {
+                call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
+            }
+            return PEAR::raiseError("could not open $dest_file for writing");
+        }
+
+        $length = isset($headers['content-length']) ? $headers['content-length'] : -1;
+
+        $bytes = 0;
+        if ($callback) {
+            call_user_func($callback, 'start', array(basename($dest_file), $length));
+        }
+
+        while ($data = fread($fp, 1024)) {
+            $bytes += strlen($data);
+            if ($callback) {
+                call_user_func($callback, 'bytesread', $bytes);
+            }
+            if (!@fwrite($wp, $data)) {
+                fclose($fp);
+                if ($callback) {
+                    call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg));
+                }
+                return PEAR::raiseError("$dest_file: write failed ($php_errormsg)");
+            }
+        }
+
+        fclose($fp);
+        fclose($wp);
+        if ($callback) {
+            call_user_func($callback, 'done', $bytes);
+        }
+
+        if ($lastmodified === false || $lastmodified) {
+            if (isset($headers['etag'])) {
+                $lastmodified = array('ETag' => $headers['etag']);
+            }
+
+            if (isset($headers['last-modified'])) {
+                if (is_array($lastmodified)) {
+                    $lastmodified['Last-Modified'] = $headers['last-modified'];
+                } else {
+                    $lastmodified = $headers['last-modified'];
+                }
+            }
+            return array($dest_file, $lastmodified, $headers);
+        }
+        return $dest_file;
+    }
+}
+// }}}
\ No newline at end of file
diff --git a/lib/php/PEAR/Downloader/Package.php b/lib/php/PEAR/Downloader/Package.php
new file mode 100644
index 00000000..36fc494d
--- /dev/null
+++ b/lib/php/PEAR/Downloader/Package.php
@@ -0,0 +1,2004 @@
+<?php
+/**
+ * PEAR_Downloader_Package
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Package.php 287560 2009-08-21 22:36:18Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * Error code when parameter initialization fails because no releases
+ * exist within preferred_state, but releases do exist
+ */
+define('PEAR_DOWNLOADER_PACKAGE_STATE', -1003);
+/**
+ * Error code when parameter initialization fails because no releases
+ * exist that will work with the existing PHP version
+ */
+define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004);
+
+/**
+ * Coordinates download parameters and manages their dependencies
+ * prior to downloading them.
+ *
+ * Input can come from three sources:
+ *
+ * - local files (archives or package.xml)
+ * - remote files (downloadable urls)
+ * - abstract package names
+ *
+ * The first two elements are handled cleanly by PEAR_PackageFile, but the third requires
+ * accessing pearweb's xml-rpc interface to determine necessary dependencies, and the
+ * format returned of dependencies is slightly different from that used in package.xml.
+ *
+ * This class hides the differences between these elements, and makes automatic
+ * dependency resolution a piece of cake.  It also manages conflicts when
+ * two classes depend on incompatible dependencies, or differing versions of the same
+ * package dependency.  In addition, download will not be attempted if the php version is
+ * not supported, PEAR installer version is not supported, or non-PECL extensions are not
+ * installed.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Downloader_Package
+{
+    /**
+     * @var PEAR_Downloader
+     */
+    var $_downloader;
+    /**
+     * @var PEAR_Config
+     */
+    var $_config;
+    /**
+     * @var PEAR_Registry
+     */
+    var $_registry;
+    /**
+     * Used to implement packagingroot properly
+     * @var PEAR_Registry
+     */
+    var $_installRegistry;
+    /**
+     * @var PEAR_PackageFile_v1|PEAR_PackageFile|v2
+     */
+    var $_packagefile;
+    /**
+     * @var array
+     */
+    var $_parsedname;
+    /**
+     * @var array
+     */
+    var $_downloadURL;
+    /**
+     * @var array
+     */
+    var $_downloadDeps = array();
+    /**
+     * @var boolean
+     */
+    var $_valid = false;
+    /**
+     * @var boolean
+     */
+    var $_analyzed = false;
+    /**
+     * if this or a parent package was invoked with Package-state, this is set to the
+     * state variable.
+     *
+     * This allows temporary reassignment of preferred_state for a parent package and all of
+     * its dependencies.
+     * @var string|false
+     */
+    var $_explicitState = false;
+    /**
+     * If this package is invoked with Package#group, this variable will be true
+     */
+    var $_explicitGroup = false;
+    /**
+     * Package type local|url
+     * @var string
+     */
+    var $_type;
+    /**
+     * Contents of package.xml, if downloaded from a remote channel
+     * @var string|false
+     * @access private
+     */
+    var $_rawpackagefile;
+    /**
+     * @var boolean
+     * @access private
+     */
+    var $_validated = false;
+
+    /**
+     * @param PEAR_Downloader
+     */
+    function PEAR_Downloader_Package(&$downloader)
+    {
+        $this->_downloader = &$downloader;
+        $this->_config = &$this->_downloader->config;
+        $this->_registry = &$this->_config->getRegistry();
+        $options = $downloader->getOptions();
+        if (isset($options['packagingroot'])) {
+            $this->_config->setInstallRoot($options['packagingroot']);
+            $this->_installRegistry = &$this->_config->getRegistry();
+            $this->_config->setInstallRoot(false);
+        } else {
+            $this->_installRegistry = &$this->_registry;
+        }
+        $this->_valid = $this->_analyzed = false;
+    }
+
+    /**
+     * Parse the input and determine whether this is a local file, a remote uri, or an
+     * abstract package name.
+     *
+     * This is the heart of the PEAR_Downloader_Package(), and is used in
+     * {@link PEAR_Downloader::download()}
+     * @param string
+     * @return bool|PEAR_Error
+     */
+    function initialize($param)
+    {
+        $origErr = $this->_fromFile($param);
+        if ($this->_valid) {
+            return true;
+        }
+
+        $options = $this->_downloader->getOptions();
+        if (isset($options['offline'])) {
+            if (PEAR::isError($origErr) && !isset($options['soft'])) {
+                foreach ($origErr->getUserInfo() as $userInfo) {
+                    if (isset($userInfo['message'])) {
+                        $this->_downloader->log(0, $userInfo['message']);
+                    }
+                }
+
+                $this->_downloader->log(0, $origErr->getMessage());
+            }
+
+            return PEAR::raiseError('Cannot download non-local package "' . $param . '"');
+        }
+
+        $err = $this->_fromUrl($param);
+        if (PEAR::isError($err) || !$this->_valid) {
+            if ($this->_type == 'url') {
+                if (PEAR::isError($err) && !isset($options['soft'])) {
+                    $this->_downloader->log(0, $err->getMessage());
+                }
+
+                return PEAR::raiseError("Invalid or missing remote package file");
+            }
+
+            $err = $this->_fromString($param);
+            if (PEAR::isError($err) || !$this->_valid) {
+                if (PEAR::isError($err) && $err->getCode() == PEAR_DOWNLOADER_PACKAGE_STATE) {
+                    return false; // instruct the downloader to silently skip
+                }
+
+                if (isset($this->_type) && $this->_type == 'local' && PEAR::isError($origErr)) {
+                    if (is_array($origErr->getUserInfo())) {
+                        foreach ($origErr->getUserInfo() as $err) {
+                            if (is_array($err)) {
+                                $err = $err['message'];
+                            }
+
+                            if (!isset($options['soft'])) {
+                                $this->_downloader->log(0, $err);
+                            }
+                        }
+                    }
+
+                    if (!isset($options['soft'])) {
+                        $this->_downloader->log(0, $origErr->getMessage());
+                    }
+
+                    if (is_array($param)) {
+                        $param = $this->_registry->parsedPackageNameToString($param, true);
+                    }
+
+                    if (!isset($options['soft'])) {
+                        $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file");
+                    }
+
+                    // Passing no message back - already logged above
+                    return PEAR::raiseError();
+                }
+
+                if (PEAR::isError($err) && !isset($options['soft'])) {
+                    $this->_downloader->log(0, $err->getMessage());
+                }
+
+                if (is_array($param)) {
+                    $param = $this->_registry->parsedPackageNameToString($param, true);
+                }
+
+                if (!isset($options['soft'])) {
+                    $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file");
+                }
+
+                // Passing no message back - already logged above
+                return PEAR::raiseError();
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Retrieve any non-local packages
+     * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|PEAR_Error
+     */
+    function &download()
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile;
+        }
+
+        if (isset($this->_downloadURL['url'])) {
+            $this->_isvalid = false;
+            $info = $this->getParsedPackage();
+            foreach ($info as $i => $p) {
+                $info[$i] = strtolower($p);
+            }
+
+            $err = $this->_fromUrl($this->_downloadURL['url'],
+                $this->_registry->parsedPackageNameToString($this->_parsedname, true));
+            $newinfo = $this->getParsedPackage();
+            foreach ($newinfo as $i => $p) {
+                $newinfo[$i] = strtolower($p);
+            }
+
+            if ($info != $newinfo) {
+                do {
+                    if ($info['channel'] == 'pecl.php.net' && $newinfo['channel'] == 'pear.php.net') {
+                        $info['channel'] = 'pear.php.net';
+                        if ($info == $newinfo) {
+                            // skip the channel check if a pecl package says it's a PEAR package
+                            break;
+                        }
+                    }
+                    if ($info['channel'] == 'pear.php.net' && $newinfo['channel'] == 'pecl.php.net') {
+                        $info['channel'] = 'pecl.php.net';
+                        if ($info == $newinfo) {
+                            // skip the channel check if a pecl package says it's a PEAR package
+                            break;
+                        }
+                    }
+
+                    return PEAR::raiseError('CRITICAL ERROR: We are ' .
+                        $this->_registry->parsedPackageNameToString($info) . ', but the file ' .
+                        'downloaded claims to be ' .
+                        $this->_registry->parsedPackageNameToString($this->getParsedPackage()));
+                } while (false);
+            }
+
+            if (PEAR::isError($err) || !$this->_valid) {
+                return $err;
+            }
+        }
+
+        $this->_type = 'local';
+        return $this->_packagefile;
+    }
+
+    function &getPackageFile()
+    {
+        return $this->_packagefile;
+    }
+
+    function &getDownloader()
+    {
+        return $this->_downloader;
+    }
+
+    function getType()
+    {
+        return $this->_type;
+    }
+
+    /**
+     * Like {@link initialize()}, but operates on a dependency
+     */
+    function fromDepURL($dep)
+    {
+        $this->_downloadURL = $dep;
+        if (isset($dep['uri'])) {
+            $options = $this->_downloader->getOptions();
+            if (!extension_loaded("zlib") || isset($options['nocompress'])) {
+                $ext = '.tar';
+            } else {
+                $ext = '.tgz';
+            }
+
+            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+            $err = $this->_fromUrl($dep['uri'] . $ext);
+            PEAR::popErrorHandling();
+            if (PEAR::isError($err)) {
+                if (!isset($options['soft'])) {
+                    $this->_downloader->log(0, $err->getMessage());
+                }
+
+                return PEAR::raiseError('Invalid uri dependency "' . $dep['uri'] . $ext . '", ' .
+                    'cannot download');
+            }
+        } else {
+            $this->_parsedname =
+                array(
+                    'package' => $dep['info']->getPackage(),
+                    'channel' => $dep['info']->getChannel(),
+                    'version' => $dep['version']
+                );
+            if (!isset($dep['nodefault'])) {
+                $this->_parsedname['group'] = 'default'; // download the default dependency group
+                $this->_explicitGroup = false;
+            }
+
+            $this->_rawpackagefile = $dep['raw'];
+        }
+    }
+
+    function detectDependencies($params)
+    {
+        $options = $this->_downloader->getOptions();
+        if (isset($options['downloadonly'])) {
+            return;
+        }
+
+        if (isset($options['offline'])) {
+            $this->_downloader->log(3, 'Skipping dependency download check, --offline specified');
+            return;
+        }
+
+        $pname = $this->getParsedPackage();
+        if (!$pname) {
+            return;
+        }
+
+        $deps = $this->getDeps();
+        if (!$deps) {
+            return;
+        }
+
+        if (isset($deps['required'])) { // package.xml 2.0
+            return $this->_detect2($deps, $pname, $options, $params);
+        }
+
+        return $this->_detect1($deps, $pname, $options, $params);
+    }
+
+    function setValidated()
+    {
+        $this->_validated = true;
+    }
+
+    function alreadyValidated()
+    {
+        return $this->_validated;
+    }
+
+    /**
+     * Remove packages to be downloaded that are already installed
+     * @param array of PEAR_Downloader_Package objects
+     * @static
+     */
+    function removeInstalled(&$params)
+    {
+        if (!isset($params[0])) {
+            return;
+        }
+
+        $options = $params[0]->_downloader->getOptions();
+        if (!isset($options['downloadonly'])) {
+            foreach ($params as $i => $param) {
+                $package = $param->getPackage();
+                $channel = $param->getChannel();
+                // remove self if already installed with this version
+                // this does not need any pecl magic - we only remove exact matches
+                if ($param->_installRegistry->packageExists($package, $channel)) {
+                    $packageVersion = $param->_installRegistry->packageInfo($package, 'version', $channel);
+                    if (version_compare($packageVersion, $param->getVersion(), '==')) {
+                        if (!isset($options['force'])) {
+                            $info = $param->getParsedPackage();
+                            unset($info['version']);
+                            unset($info['state']);
+                            if (!isset($options['soft'])) {
+                                $param->_downloader->log(1, 'Skipping package "' .
+                                    $param->getShortName() .
+                                    '", already installed as version ' . $packageVersion);
+                            }
+                            $params[$i] = false;
+                        }
+                    } elseif (!isset($options['force']) && !isset($options['upgrade']) &&
+                          !isset($options['soft'])) {
+                        $info = $param->getParsedPackage();
+                        $param->_downloader->log(1, 'Skipping package "' .
+                            $param->getShortName() .
+                            '", already installed as version ' . $packageVersion);
+                        $params[$i] = false;
+                    }
+                }
+            }
+        }
+
+        PEAR_Downloader_Package::removeDuplicates($params);
+    }
+
+    function _detect2($deps, $pname, $options, $params)
+    {
+        $this->_downloadDeps = array();
+        $groupnotfound = false;
+        foreach (array('package', 'subpackage') as $packagetype) {
+            // get required dependency group
+            if (isset($deps['required'][$packagetype])) {
+                if (isset($deps['required'][$packagetype][0])) {
+                    foreach ($deps['required'][$packagetype] as $dep) {
+                        if (isset($dep['conflicts'])) {
+                            // skip any package that this package conflicts with
+                            continue;
+                        }
+                        $ret = $this->_detect2Dep($dep, $pname, 'required', $params);
+                        if (is_array($ret)) {
+                            $this->_downloadDeps[] = $ret;
+                        } elseif (PEAR::isError($ret) && !isset($options['soft'])) {
+                            $this->_downloader->log(0, $ret->getMessage());
+                        }
+                    }
+                } else {
+                    $dep = $deps['required'][$packagetype];
+                    if (!isset($dep['conflicts'])) {
+                        // skip any package that this package conflicts with
+                        $ret = $this->_detect2Dep($dep, $pname, 'required', $params);
+                        if (is_array($ret)) {
+                            $this->_downloadDeps[] = $ret;
+                        } elseif (PEAR::isError($ret) && !isset($options['soft'])) {
+                            $this->_downloader->log(0, $ret->getMessage());
+                        }
+                    }
+                }
+            }
+
+            // get optional dependency group, if any
+            if (isset($deps['optional'][$packagetype])) {
+                $skipnames = array();
+                if (!isset($deps['optional'][$packagetype][0])) {
+                    $deps['optional'][$packagetype] = array($deps['optional'][$packagetype]);
+                }
+
+                foreach ($deps['optional'][$packagetype] as $dep) {
+                    $skip = false;
+                    if (!isset($options['alldeps'])) {
+                        $dep['package'] = $dep['name'];
+                        if (!isset($options['soft'])) {
+                            $this->_downloader->log(3, 'Notice: package "' .
+                              $this->_registry->parsedPackageNameToString($this->getParsedPackage(),
+                                    true) . '" optional dependency "' .
+                                $this->_registry->parsedPackageNameToString(array('package' =>
+                                    $dep['name'], 'channel' => 'pear.php.net'), true) .
+                                '" will not be automatically downloaded');
+                        }
+                        $skipnames[] = $this->_registry->parsedPackageNameToString($dep, true);
+                        $skip = true;
+                        unset($dep['package']);
+                    }
+
+                    $ret = $this->_detect2Dep($dep, $pname, 'optional', $params);
+                    if (PEAR::isError($ret) && !isset($options['soft'])) {
+                        $this->_downloader->log(0, $ret->getMessage());
+                    }
+
+                    if (!$ret) {
+                        $dep['package'] = $dep['name'];
+                        $skip = count($skipnames) ?
+                            $skipnames[count($skipnames) - 1] : '';
+                        if ($skip ==
+                              $this->_registry->parsedPackageNameToString($dep, true)) {
+                            array_pop($skipnames);
+                        }
+                    }
+
+                    if (!$skip && is_array($ret)) {
+                        $this->_downloadDeps[] = $ret;
+                    }
+                }
+
+                if (count($skipnames)) {
+                    if (!isset($options['soft'])) {
+                        $this->_downloader->log(1, 'Did not download optional dependencies: ' .
+                            implode(', ', $skipnames) .
+                            ', use --alldeps to download automatically');
+                    }
+                }
+            }
+
+            // get requested dependency group, if any
+            $groupname = $this->getGroup();
+            $explicit  = $this->_explicitGroup;
+            if (!$groupname) {
+                if (!$this->canDefault()) {
+                    continue;
+                }
+
+                $groupname = 'default'; // try the default dependency group
+            }
+
+            if ($groupnotfound) {
+                continue;
+            }
+
+            if (isset($deps['group'])) {
+                if (isset($deps['group']['attribs'])) {
+                    if (strtolower($deps['group']['attribs']['name']) == strtolower($groupname)) {
+                        $group = $deps['group'];
+                    } elseif ($explicit) {
+                        if (!isset($options['soft'])) {
+                            $this->_downloader->log(0, 'Warning: package "' .
+                                $this->_registry->parsedPackageNameToString($pname, true) .
+                                '" has no dependency ' . 'group named "' . $groupname . '"');
+                        }
+
+                        $groupnotfound = true;
+                        continue;
+                    }
+                } else {
+                    $found = false;
+                    foreach ($deps['group'] as $group) {
+                        if (strtolower($group['attribs']['name']) == strtolower($groupname)) {
+                            $found = true;
+                            break;
+                        }
+                    }
+
+                    if (!$found) {
+                        if ($explicit) {
+                            if (!isset($options['soft'])) {
+                                $this->_downloader->log(0, 'Warning: package "' .
+                                    $this->_registry->parsedPackageNameToString($pname, true) .
+                                    '" has no dependency ' . 'group named "' . $groupname . '"');
+                            }
+                        }
+
+                        $groupnotfound = true;
+                        continue;
+                    }
+                }
+            }
+
+            if (isset($group) && isset($group[$packagetype])) {
+                if (isset($group[$packagetype][0])) {
+                    foreach ($group[$packagetype] as $dep) {
+                        $ret = $this->_detect2Dep($dep, $pname, 'dependency group "' .
+                            $group['attribs']['name'] . '"', $params);
+                        if (is_array($ret)) {
+                            $this->_downloadDeps[] = $ret;
+                        } elseif (PEAR::isError($ret) && !isset($options['soft'])) {
+                            $this->_downloader->log(0, $ret->getMessage());
+                        }
+                    }
+                } else {
+                    $ret = $this->_detect2Dep($group[$packagetype], $pname,
+                        'dependency group "' .
+                        $group['attribs']['name'] . '"', $params);
+                    if (is_array($ret)) {
+                        $this->_downloadDeps[] = $ret;
+                    } elseif (PEAR::isError($ret) && !isset($options['soft'])) {
+                        $this->_downloader->log(0, $ret->getMessage());
+                    }
+                }
+            }
+        }
+    }
+
+    function _detect2Dep($dep, $pname, $group, $params)
+    {
+        if (isset($dep['conflicts'])) {
+            return true;
+        }
+
+        $options = $this->_downloader->getOptions();
+        if (isset($dep['uri'])) {
+            return array('uri' => $dep['uri'], 'dep' => $dep);;
+        }
+
+        $testdep = $dep;
+        $testdep['package'] = $dep['name'];
+        if (PEAR_Downloader_Package::willDownload($testdep, $params)) {
+            $dep['package'] = $dep['name'];
+            if (!isset($options['soft'])) {
+                $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group .
+                    ' dependency "' .
+                    $this->_registry->parsedPackageNameToString($dep, true) .
+                    '", will be installed');
+            }
+            return false;
+        }
+
+        $options = $this->_downloader->getOptions();
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        if ($this->_explicitState) {
+            $pname['state'] = $this->_explicitState;
+        }
+
+        $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname);
+        if (PEAR::isError($url)) {
+            PEAR::popErrorHandling();
+            return $url;
+        }
+
+        $dep['package'] = $dep['name'];
+        $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, $group == 'optional' &&
+            !isset($options['alldeps']), true);
+        PEAR::popErrorHandling();
+        if (PEAR::isError($ret)) {
+            if (!isset($options['soft'])) {
+                $this->_downloader->log(0, $ret->getMessage());
+            }
+
+            return false;
+        }
+
+        // check to see if a dep is already installed and is the same or newer
+        if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended'])) {
+            $oper = 'has';
+        } else {
+            $oper = 'gt';
+        }
+
+        // do not try to move this before getDepPackageDownloadURL
+        // we can't determine whether upgrade is necessary until we know what
+        // version would be downloaded
+        if (!isset($options['force']) && $this->isInstalled($ret, $oper)) {
+            $version = $this->_installRegistry->packageInfo($dep['name'], 'version', $dep['channel']);
+            $dep['package'] = $dep['name'];
+            if (!isset($options['soft'])) {
+                $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group .
+                    ' dependency "' .
+                $this->_registry->parsedPackageNameToString($dep, true) .
+                    '" version ' . $url['version'] . ', already installed as version ' .
+                    $version);
+            }
+
+            return false;
+        }
+
+        if (isset($dep['nodefault'])) {
+            $ret['nodefault'] = true;
+        }
+
+        return $ret;
+    }
+
+    function _detect1($deps, $pname, $options, $params)
+    {
+        $this->_downloadDeps = array();
+        $skipnames = array();
+        foreach ($deps as $dep) {
+            $nodownload = false;
+            if (isset ($dep['type']) && $dep['type'] === 'pkg') {
+                $dep['channel'] = 'pear.php.net';
+                $dep['package'] = $dep['name'];
+                switch ($dep['rel']) {
+                    case 'not' :
+                        continue 2;
+                    case 'ge' :
+                    case 'eq' :
+                    case 'gt' :
+                    case 'has' :
+                        $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ?
+                            'required' :
+                            'optional';
+                        if (PEAR_Downloader_Package::willDownload($dep, $params)) {
+                            $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group
+                                . ' dependency "' .
+                                $this->_registry->parsedPackageNameToString($dep, true) .
+                                '", will be installed');
+                            continue 2;
+                        }
+                        $fakedp = new PEAR_PackageFile_v1;
+                        $fakedp->setPackage($dep['name']);
+                        // skip internet check if we are not upgrading (bug #5810)
+                        if (!isset($options['upgrade']) && $this->isInstalled(
+                              $fakedp, $dep['rel'])) {
+                            $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group
+                                . ' dependency "' .
+                                $this->_registry->parsedPackageNameToString($dep, true) .
+                                '", is already installed');
+                            continue 2;
+                        }
+                }
+
+                PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                if ($this->_explicitState) {
+                    $pname['state'] = $this->_explicitState;
+                }
+
+                $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname);
+                $chan = 'pear.php.net';
+                if (PEAR::isError($url)) {
+                    // check to see if this is a pecl package that has jumped
+                    // from pear.php.net to pecl.php.net channel
+                    if (!class_exists('PEAR_Dependency2')) {
+                        require_once 'PEAR/Dependency2.php';
+                    }
+
+                    $newdep = PEAR_Dependency2::normalizeDep($dep);
+                    $newdep = $newdep[0];
+                    $newdep['channel'] = 'pecl.php.net';
+                    $chan = 'pecl.php.net';
+                    $url = $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname);
+                    $obj = &$this->_installRegistry->getPackage($dep['name']);
+                    if (PEAR::isError($url)) {
+                        PEAR::popErrorHandling();
+                        if ($obj !== null && $this->isInstalled($obj, $dep['rel'])) {
+                            $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ?
+                                'required' :
+                                'optional';
+                            $dep['package'] = $dep['name'];
+                            if (!isset($options['soft'])) {
+                                $this->_downloader->log(3, $this->getShortName() .
+                                    ': Skipping ' . $group . ' dependency "' .
+                                    $this->_registry->parsedPackageNameToString($dep, true) .
+                                    '", already installed as version ' . $obj->getVersion());
+                            }
+                            $skip = count($skipnames) ?
+                                $skipnames[count($skipnames) - 1] : '';
+                            if ($skip ==
+                                  $this->_registry->parsedPackageNameToString($dep, true)) {
+                                array_pop($skipnames);
+                            }
+                            continue;
+                        } else {
+                            if (isset($dep['optional']) && $dep['optional'] == 'yes') {
+                                $this->_downloader->log(2, $this->getShortName() .
+                                    ': Skipping optional dependency "' .
+                                    $this->_registry->parsedPackageNameToString($dep, true) .
+                                    '", no releases exist');
+                                continue;
+                            } else {
+                                return $url;
+                            }
+                        }
+                    }
+                }
+
+                PEAR::popErrorHandling();
+                if (!isset($options['alldeps'])) {
+                    if (isset($dep['optional']) && $dep['optional'] == 'yes') {
+                        if (!isset($options['soft'])) {
+                            $this->_downloader->log(3, 'Notice: package "' .
+                                $this->getShortName() .
+                                '" optional dependency "' .
+                                $this->_registry->parsedPackageNameToString(
+                                    array('channel' => $chan, 'package' =>
+                                    $dep['name']), true) .
+                                '" will not be automatically downloaded');
+                        }
+                        $skipnames[] = $this->_registry->parsedPackageNameToString(
+                                array('channel' => $chan, 'package' =>
+                                $dep['name']), true);
+                        $nodownload = true;
+                    }
+                }
+
+                if (!isset($options['alldeps']) && !isset($options['onlyreqdeps'])) {
+                    if (!isset($dep['optional']) || $dep['optional'] == 'no') {
+                        if (!isset($options['soft'])) {
+                            $this->_downloader->log(3, 'Notice: package "' .
+                                $this->getShortName() .
+                                '" required dependency "' .
+                                $this->_registry->parsedPackageNameToString(
+                                    array('channel' => $chan, 'package' =>
+                                    $dep['name']), true) .
+                                '" will not be automatically downloaded');
+                        }
+                        $skipnames[] = $this->_registry->parsedPackageNameToString(
+                                array('channel' => $chan, 'package' =>
+                                $dep['name']), true);
+                        $nodownload = true;
+                    }
+                }
+
+                // check to see if a dep is already installed
+                // do not try to move this before getDepPackageDownloadURL
+                // we can't determine whether upgrade is necessary until we know what
+                // version would be downloaded
+                if (!isset($options['force']) && $this->isInstalled(
+                        $url, $dep['rel'])) {
+                    $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ?
+                        'required' :
+                        'optional';
+                    $dep['package'] = $dep['name'];
+                    if (isset($newdep)) {
+                        $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', $newdep['channel']);
+                    } else {
+                        $version = $this->_installRegistry->packageInfo($dep['name'], 'version');
+                    }
+
+                    $dep['version'] = $url['version'];
+                    if (!isset($options['soft'])) {
+                        $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group .
+                            ' dependency "' .
+                            $this->_registry->parsedPackageNameToString($dep, true) .
+                            '", already installed as version ' . $version);
+                    }
+
+                    $skip = count($skipnames) ?
+                        $skipnames[count($skipnames) - 1] : '';
+                    if ($skip ==
+                          $this->_registry->parsedPackageNameToString($dep, true)) {
+                        array_pop($skipnames);
+                    }
+
+                    continue;
+                }
+
+                if ($nodownload) {
+                    continue;
+                }
+
+                PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                if (isset($newdep)) {
+                    $dep = $newdep;
+                }
+
+                $dep['package'] = $dep['name'];
+                $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params,
+                    isset($dep['optional']) && $dep['optional'] == 'yes' &&
+                    !isset($options['alldeps']), true);
+                PEAR::popErrorHandling();
+                if (PEAR::isError($ret)) {
+                    if (!isset($options['soft'])) {
+                        $this->_downloader->log(0, $ret->getMessage());
+                    }
+                    continue;
+                }
+
+                $this->_downloadDeps[] = $ret;
+            }
+        }
+
+        if (count($skipnames)) {
+            if (!isset($options['soft'])) {
+                $this->_downloader->log(1, 'Did not download dependencies: ' .
+                    implode(', ', $skipnames) .
+                    ', use --alldeps or --onlyreqdeps to download automatically');
+            }
+        }
+    }
+
+    function setDownloadURL($pkg)
+    {
+        $this->_downloadURL = $pkg;
+    }
+
+    /**
+     * Set the package.xml object for this downloaded package
+     *
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 $pkg
+     */
+    function setPackageFile(&$pkg)
+    {
+        $this->_packagefile = &$pkg;
+    }
+
+    function getShortName()
+    {
+        return $this->_registry->parsedPackageNameToString(array('channel' => $this->getChannel(),
+            'package' => $this->getPackage()), true);
+    }
+
+    function getParsedPackage()
+    {
+        if (isset($this->_packagefile) || isset($this->_parsedname)) {
+            return array('channel' => $this->getChannel(),
+                'package' => $this->getPackage(),
+                'version' => $this->getVersion());
+        }
+
+        return false;
+    }
+
+    function getDownloadURL()
+    {
+        return $this->_downloadURL;
+    }
+
+    function canDefault()
+    {
+        if (isset($this->_downloadURL) && isset($this->_downloadURL['nodefault'])) {
+            return false;
+        }
+
+        return true;
+    }
+
+    function getPackage()
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->getPackage();
+        } elseif (isset($this->_downloadURL['info'])) {
+            return $this->_downloadURL['info']->getPackage();
+        }
+
+        return false;
+    }
+
+    /**
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     */
+    function isSubpackage(&$pf)
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->isSubpackage($pf);
+        } elseif (isset($this->_downloadURL['info'])) {
+            return $this->_downloadURL['info']->isSubpackage($pf);
+        }
+
+        return false;
+    }
+
+    function getPackageType()
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->getPackageType();
+        } elseif (isset($this->_downloadURL['info'])) {
+            return $this->_downloadURL['info']->getPackageType();
+        }
+
+        return false;
+    }
+
+    function isBundle()
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->getPackageType() == 'bundle';
+        }
+
+        return false;
+    }
+
+    function getPackageXmlVersion()
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->getPackagexmlVersion();
+        } elseif (isset($this->_downloadURL['info'])) {
+            return $this->_downloadURL['info']->getPackagexmlVersion();
+        }
+
+        return '1.0';
+    }
+
+    function getChannel()
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->getChannel();
+        } elseif (isset($this->_downloadURL['info'])) {
+            return $this->_downloadURL['info']->getChannel();
+        }
+
+        return false;
+    }
+
+    function getURI()
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->getURI();
+        } elseif (isset($this->_downloadURL['info'])) {
+            return $this->_downloadURL['info']->getURI();
+        }
+
+        return false;
+    }
+
+    function getVersion()
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->getVersion();
+        } elseif (isset($this->_downloadURL['version'])) {
+            return $this->_downloadURL['version'];
+        }
+
+        return false;
+    }
+
+    function isCompatible($pf)
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->isCompatible($pf);
+        } elseif (isset($this->_downloadURL['info'])) {
+            return $this->_downloadURL['info']->isCompatible($pf);
+        }
+
+        return true;
+    }
+
+    function setGroup($group)
+    {
+        $this->_parsedname['group'] = $group;
+    }
+
+    function getGroup()
+    {
+        if (isset($this->_parsedname['group'])) {
+            return $this->_parsedname['group'];
+        }
+
+        return '';
+    }
+
+    function isExtension($name)
+    {
+        if (isset($this->_packagefile)) {
+            return $this->_packagefile->isExtension($name);
+        } elseif (isset($this->_downloadURL['info'])) {
+            if ($this->_downloadURL['info']->getPackagexmlVersion() == '2.0') {
+                return $this->_downloadURL['info']->getProvidesExtension() == $name;
+            }
+
+            return false;
+        }
+
+        return false;
+    }
+
+    function getDeps()
+    {
+        if (isset($this->_packagefile)) {
+            $ver = $this->_packagefile->getPackagexmlVersion();
+            if (version_compare($ver, '2.0', '>=')) {
+                return $this->_packagefile->getDeps(true);
+            }
+
+            return $this->_packagefile->getDeps();
+        } elseif (isset($this->_downloadURL['info'])) {
+            $ver = $this->_downloadURL['info']->getPackagexmlVersion();
+            if (version_compare($ver, '2.0', '>=')) {
+                return $this->_downloadURL['info']->getDeps(true);
+            }
+
+            return $this->_downloadURL['info']->getDeps();
+        }
+
+        return array();
+    }
+
+    /**
+     * @param array Parsed array from {@link PEAR_Registry::parsePackageName()} or a dependency
+     *                     returned from getDepDownloadURL()
+     */
+    function isEqual($param)
+    {
+        if (is_object($param)) {
+            $channel = $param->getChannel();
+            $package = $param->getPackage();
+            if ($param->getURI()) {
+                $param = array(
+                    'channel' => $param->getChannel(),
+                    'package' => $param->getPackage(),
+                    'version' => $param->getVersion(),
+                    'uri' => $param->getURI(),
+                );
+            } else {
+                $param = array(
+                    'channel' => $param->getChannel(),
+                    'package' => $param->getPackage(),
+                    'version' => $param->getVersion(),
+                );
+            }
+        } else {
+            if (isset($param['uri'])) {
+                if ($this->getChannel() != '__uri') {
+                    return false;
+                }
+                return $param['uri'] == $this->getURI();
+            }
+
+            $package = isset($param['package']) ? $param['package'] : $param['info']->getPackage();
+            $channel = isset($param['channel']) ? $param['channel'] : $param['info']->getChannel();
+            if (isset($param['rel'])) {
+                if (!class_exists('PEAR_Dependency2')) {
+                    require_once 'PEAR/Dependency2.php';
+                }
+
+                $newdep = PEAR_Dependency2::normalizeDep($param);
+                $newdep = $newdep[0];
+            } elseif (isset($param['min'])) {
+                $newdep = $param;
+            }
+        }
+
+        if (isset($newdep)) {
+            if (!isset($newdep['min'])) {
+                $newdep['min'] = '0';
+            }
+
+            if (!isset($newdep['max'])) {
+                $newdep['max'] = '100000000000000000000';
+            }
+
+            // use magic to support pecl packages suddenly jumping to the pecl channel
+            // we need to support both dependency possibilities
+            if ($channel == 'pear.php.net' && $this->getChannel() == 'pecl.php.net') {
+                if ($package == $this->getPackage()) {
+                    $channel = 'pecl.php.net';
+                }
+            }
+            if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') {
+                if ($package == $this->getPackage()) {
+                    $channel = 'pear.php.net';
+                }
+            }
+
+            return (strtolower($package) == strtolower($this->getPackage()) &&
+                $channel == $this->getChannel() &&
+                version_compare($newdep['min'], $this->getVersion(), '<=') &&
+                version_compare($newdep['max'], $this->getVersion(), '>='));
+        }
+
+        // use magic to support pecl packages suddenly jumping to the pecl channel
+        if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') {
+            if (strtolower($package) == strtolower($this->getPackage())) {
+                $channel = 'pear.php.net';
+            }
+        }
+
+        if (isset($param['version'])) {
+            return (strtolower($package) == strtolower($this->getPackage()) &&
+                $channel == $this->getChannel() &&
+                $param['version'] == $this->getVersion());
+        }
+
+        return strtolower($package) == strtolower($this->getPackage()) &&
+            $channel == $this->getChannel();
+    }
+
+    function isInstalled($dep, $oper = '==')
+    {
+        if (!$dep) {
+            return false;
+        }
+
+        if ($oper != 'ge' && $oper != 'gt' && $oper != 'has' && $oper != '==') {
+            return false;
+        }
+
+        if (is_object($dep)) {
+            $package = $dep->getPackage();
+            $channel = $dep->getChannel();
+            if ($dep->getURI()) {
+                $dep = array(
+                    'uri' => $dep->getURI(),
+                    'version' => $dep->getVersion(),
+                );
+            } else {
+                $dep = array(
+                    'version' => $dep->getVersion(),
+                );
+            }
+        } else {
+            if (isset($dep['uri'])) {
+                $channel = '__uri';
+                $package = $dep['dep']['name'];
+            } else {
+                $channel = $dep['info']->getChannel();
+                $package = $dep['info']->getPackage();
+            }
+        }
+
+        $options = $this->_downloader->getOptions();
+        $test    = $this->_installRegistry->packageExists($package, $channel);
+        if (!$test && $channel == 'pecl.php.net') {
+            // do magic to allow upgrading from old pecl packages to new ones
+            $test = $this->_installRegistry->packageExists($package, 'pear.php.net');
+            $channel = 'pear.php.net';
+        }
+
+        if ($test) {
+            if (isset($dep['uri'])) {
+                if ($this->_installRegistry->packageInfo($package, 'uri', '__uri') == $dep['uri']) {
+                    return true;
+                }
+            }
+
+            if (isset($options['upgrade'])) {
+                $packageVersion = $this->_installRegistry->packageInfo($package, 'version', $channel);
+                if (version_compare($packageVersion, $dep['version'], '>=')) {
+                    return true;
+                }
+
+                return false;
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Detect duplicate package names with differing versions
+     *
+     * If a user requests to install Date 1.4.6 and Date 1.4.7,
+     * for instance, this is a logic error.  This method
+     * detects this situation.
+     *
+     * @param array $params array of PEAR_Downloader_Package objects
+     * @param array $errorparams empty array
+     * @return array array of stupid duplicated packages in PEAR_Downloader_Package obejcts
+     */
+    function detectStupidDuplicates($params, &$errorparams)
+    {
+        $existing = array();
+        foreach ($params as $i => $param) {
+            $package = $param->getPackage();
+            $channel = $param->getChannel();
+            $group   = $param->getGroup();
+            if (!isset($existing[$channel . '/' . $package])) {
+                $existing[$channel . '/' . $package] = array();
+            }
+
+            if (!isset($existing[$channel . '/' . $package][$group])) {
+                $existing[$channel . '/' . $package][$group] = array();
+            }
+
+            $existing[$channel . '/' . $package][$group][] = $i;
+        }
+
+        $indices = array();
+        foreach ($existing as $package => $groups) {
+            foreach ($groups as $group => $dupes) {
+                if (count($dupes) > 1) {
+                    $indices = $indices + $dupes;
+                }
+            }
+        }
+
+        $indices = array_unique($indices);
+        foreach ($indices as $index) {
+            $errorparams[] = $params[$index];
+        }
+
+        return count($errorparams);
+    }
+
+    /**
+     * @param array
+     * @param bool ignore install groups - for final removal of dupe packages
+     * @static
+     */
+    function removeDuplicates(&$params, $ignoreGroups = false)
+    {
+        $pnames = array();
+        foreach ($params as $i => $param) {
+            if (!$param) {
+                continue;
+            }
+
+            if ($param->getPackage()) {
+                $group = $ignoreGroups ? '' : $param->getGroup();
+                $pnames[$i] = $param->getChannel() . '/' .
+                    $param->getPackage() . '-' . $param->getVersion() . '#' . $group;
+            }
+        }
+
+        $pnames = array_unique($pnames);
+        $unset  = array_diff(array_keys($params), array_keys($pnames));
+        $testp  = array_flip($pnames);
+        foreach ($params as $i => $param) {
+            if (!$param) {
+                $unset[] = $i;
+                continue;
+            }
+
+            if (!is_a($param, 'PEAR_Downloader_Package')) {
+                $unset[] = $i;
+                continue;
+            }
+
+            $group = $ignoreGroups ? '' : $param->getGroup();
+            if (!isset($testp[$param->getChannel() . '/' . $param->getPackage() . '-' .
+                  $param->getVersion() . '#' . $group])) {
+                $unset[] = $i;
+            }
+        }
+
+        foreach ($unset as $i) {
+            unset($params[$i]);
+        }
+
+        $ret = array();
+        foreach ($params as $i => $param) {
+            $ret[] = &$params[$i];
+        }
+
+        $params = array();
+        foreach ($ret as $i => $param) {
+            $params[] = &$ret[$i];
+        }
+    }
+
+    function explicitState()
+    {
+        return $this->_explicitState;
+    }
+
+    function setExplicitState($s)
+    {
+        $this->_explicitState = $s;
+    }
+
+    /**
+     * @static
+     */
+    function mergeDependencies(&$params)
+    {
+        $bundles = $newparams = array();
+        foreach ($params as $i => $param) {
+            if (!$param->isBundle()) {
+                continue;
+            }
+
+            $bundles[] = $i;
+            $pf = &$param->getPackageFile();
+            $newdeps = array();
+            $contents = $pf->getBundledPackages();
+            if (!is_array($contents)) {
+                $contents = array($contents);
+            }
+
+            foreach ($contents as $file) {
+                $filecontents = $pf->getFileContents($file);
+                $dl = &$param->getDownloader();
+                $options = $dl->getOptions();
+                if (PEAR::isError($dir = $dl->getDownloadDir())) {
+                    return $dir;
+                }
+
+                $fp = @fopen($dir . DIRECTORY_SEPARATOR . $file, 'wb');
+                if (!$fp) {
+                    continue;
+                }
+
+                fwrite($fp, $filecontents, strlen($filecontents));
+                fclose($fp);
+                if ($s = $params[$i]->explicitState()) {
+                    $obj->setExplicitState($s);
+                }
+
+                $obj = &new PEAR_Downloader_Package($params[$i]->getDownloader());
+                PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                if (PEAR::isError($dir = $dl->getDownloadDir())) {
+                    PEAR::popErrorHandling();
+                    return $dir;
+                }
+
+                $e = $obj->_fromFile($a = $dir . DIRECTORY_SEPARATOR . $file);
+                PEAR::popErrorHandling();
+                if (PEAR::isError($e)) {
+                    if (!isset($options['soft'])) {
+                        $dl->log(0, $e->getMessage());
+                    }
+                    continue;
+                }
+
+                $j = &$obj;
+                if (!PEAR_Downloader_Package::willDownload($j,
+                      array_merge($params, $newparams)) && !$param->isInstalled($j)) {
+                    $newparams[] = &$j;
+                }
+            }
+        }
+
+        foreach ($bundles as $i) {
+            unset($params[$i]); // remove bundles - only their contents matter for installation
+        }
+
+        PEAR_Downloader_Package::removeDuplicates($params); // strip any unset indices
+        if (count($newparams)) { // add in bundled packages for install
+            foreach ($newparams as $i => $unused) {
+                $params[] = &$newparams[$i];
+            }
+            $newparams = array();
+        }
+
+        foreach ($params as $i => $param) {
+            $newdeps = array();
+            foreach ($param->_downloadDeps as $dep) {
+                $merge = array_merge($params, $newparams);
+                if (!PEAR_Downloader_Package::willDownload($dep, $merge)
+                    && !$param->isInstalled($dep)
+                ) {
+                    $newdeps[] = $dep;
+                } else {
+                    //var_dump($dep);
+                    // detect versioning conflicts here
+                }
+            }
+
+            // convert the dependencies into PEAR_Downloader_Package objects for the next time around
+            $params[$i]->_downloadDeps = array();
+            foreach ($newdeps as $dep) {
+                $obj = &new PEAR_Downloader_Package($params[$i]->getDownloader());
+                if ($s = $params[$i]->explicitState()) {
+                    $obj->setExplicitState($s);
+                }
+
+                PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                $e = $obj->fromDepURL($dep);
+                PEAR::popErrorHandling();
+                if (PEAR::isError($e)) {
+                    if (!isset($options['soft'])) {
+                        $obj->_downloader->log(0, $e->getMessage());
+                    }
+                    continue;
+                }
+
+                $e = $obj->detectDependencies($params);
+                if (PEAR::isError($e)) {
+                    if (!isset($options['soft'])) {
+                        $obj->_downloader->log(0, $e->getMessage());
+                    }
+                }
+
+                $j = &$obj;
+                $newparams[] = &$j;
+            }
+        }
+
+        if (count($newparams)) {
+            foreach ($newparams as $i => $unused) {
+                $params[] = &$newparams[$i];
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+
+    /**
+     * @static
+     */
+    function willDownload($param, $params)
+    {
+        if (!is_array($params)) {
+            return false;
+        }
+
+        foreach ($params as $obj) {
+            if ($obj->isEqual($param)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * For simpler unit-testing
+     * @param PEAR_Config
+     * @param int
+     * @param string
+     */
+    function &getPackagefileObject(&$c, $d, $t = false)
+    {
+        $a = &new PEAR_PackageFile($c, $d, $t);
+        return $a;
+    }
+
+
+    /**
+     * This will retrieve from a local file if possible, and parse out
+     * a group name as well.  The original parameter will be modified to reflect this.
+     * @param string|array can be a parsed package name as well
+     * @access private
+     */
+    function _fromFile(&$param)
+    {
+        $saveparam = $param;
+        if (is_string($param)) {
+            if (!@file_exists($param)) {
+                $test = explode('#', $param);
+                $group = array_pop($test);
+                if (@file_exists(implode('#', $test))) {
+                    $this->setGroup($group);
+                    $param = implode('#', $test);
+                    $this->_explicitGroup = true;
+                }
+            }
+
+            if (@is_file($param)) {
+                $this->_type = 'local';
+                $options = $this->_downloader->getOptions();
+                if (isset($options['downloadonly'])) {
+                    $pkg = &$this->getPackagefileObject($this->_config,
+                        $this->_downloader->_debug);
+                } else {
+                    if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) {
+                        return $dir;
+                    }
+                    $pkg = &$this->getPackagefileObject($this->_config,
+                        $this->_downloader->_debug, $dir);
+                }
+                PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                $pf = &$pkg->fromAnyFile($param, PEAR_VALIDATE_INSTALLING);
+                PEAR::popErrorHandling();
+                if (PEAR::isError($pf)) {
+                    $this->_valid = false;
+                    $param = $saveparam;
+                    return $pf;
+                }
+                $this->_packagefile = &$pf;
+                if (!$this->getGroup()) {
+                    $this->setGroup('default'); // install the default dependency group
+                }
+                return $this->_valid = true;
+            }
+        }
+        $param = $saveparam;
+        return $this->_valid = false;
+    }
+
+    function _fromUrl($param, $saveparam = '')
+    {
+        if (!is_array($param) && (preg_match('#^(http|https|ftp)://#', $param))) {
+            $options = $this->_downloader->getOptions();
+            $this->_type = 'url';
+            $callback = $this->_downloader->ui ?
+                array(&$this->_downloader, '_downloadCallback') : null;
+            $this->_downloader->pushErrorHandling(PEAR_ERROR_RETURN);
+            if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) {
+                $this->_downloader->popErrorHandling();
+                return $dir;
+            }
+
+            $this->_downloader->log(3, 'Downloading "' . $param . '"');
+            $file = $this->_downloader->downloadHttp($param, $this->_downloader->ui,
+                $dir, $callback, null, false, $this->getChannel());
+            $this->_downloader->popErrorHandling();
+            if (PEAR::isError($file)) {
+                if (!empty($saveparam)) {
+                    $saveparam = ", cannot download \"$saveparam\"";
+                }
+                $err = PEAR::raiseError('Could not download from "' . $param .
+                    '"' . $saveparam . ' (' . $file->getMessage() . ')');
+                    return $err;
+            }
+
+            if ($this->_rawpackagefile) {
+                require_once 'Archive/Tar.php';
+                $tar = &new Archive_Tar($file);
+                $packagexml = $tar->extractInString('package2.xml');
+                if (!$packagexml) {
+                    $packagexml = $tar->extractInString('package.xml');
+                }
+
+                if (str_replace(array("\n", "\r"), array('',''), $packagexml) !=
+                      str_replace(array("\n", "\r"), array('',''), $this->_rawpackagefile)) {
+                    if ($this->getChannel() != 'pear.php.net') {
+                        return PEAR::raiseError('CRITICAL ERROR: package.xml downloaded does ' .
+                            'not match value returned from xml-rpc');
+                    }
+
+                    // be more lax for the existing PEAR packages that have not-ok
+                    // characters in their package.xml
+                    $this->_downloader->log(0, 'CRITICAL WARNING: The "' .
+                        $this->getPackage() . '" package has invalid characters in its ' .
+                        'package.xml.  The next version of PEAR may not be able to install ' .
+                        'this package for security reasons.  Please open a bug report at ' .
+                        'http://pear.php.net/package/' . $this->getPackage() . '/bugs');
+                }
+            }
+
+            // whew, download worked!
+            if (isset($options['downloadonly'])) {
+                $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug);
+            } else {
+                $dir = $this->_downloader->getDownloadDir();
+                if (PEAR::isError($dir)) {
+                    return $dir;
+                }
+                $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug, $dir);
+            }
+
+            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+            $pf = &$pkg->fromAnyFile($file, PEAR_VALIDATE_INSTALLING);
+            PEAR::popErrorHandling();
+            if (PEAR::isError($pf)) {
+                if (is_array($pf->getUserInfo())) {
+                    foreach ($pf->getUserInfo() as $err) {
+                        if (is_array($err)) {
+                            $err = $err['message'];
+                        }
+
+                        if (!isset($options['soft'])) {
+                            $this->_downloader->log(0, "Validation Error: $err");
+                        }
+                    }
+                }
+
+                if (!isset($options['soft'])) {
+                    $this->_downloader->log(0, $pf->getMessage());
+                }
+
+                ///FIXME need to pass back some error code that we can use to match with to cancel all further operations
+                /// At least stop all deps of this package from being installed
+                $out = $saveparam ? $saveparam : $param;
+                $err = PEAR::raiseError('Download of "' . $out . '" succeeded, but it is not a valid package archive');
+                $this->_valid = false;
+                return $err;
+            }
+
+            $this->_packagefile = &$pf;
+            $this->setGroup('default'); // install the default dependency group
+            return $this->_valid = true;
+        }
+
+        return $this->_valid = false;
+    }
+
+    /**
+     *
+     * @param string|array pass in an array of format
+     *                     array(
+     *                      'package' => 'pname',
+     *                     ['channel' => 'channame',]
+     *                     ['version' => 'version',]
+     *                     ['state' => 'state',])
+     *                     or a string of format [channame/]pname[-version|-state]
+     */
+    function _fromString($param)
+    {
+        $options = $this->_downloader->getOptions();
+        $channel = $this->_config->get('default_channel');
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        $pname = $this->_registry->parsePackageName($param, $channel);
+        PEAR::popErrorHandling();
+        if (PEAR::isError($pname)) {
+            if ($pname->getCode() == 'invalid') {
+                $this->_valid = false;
+                return false;
+            }
+
+            if ($pname->getCode() == 'channel') {
+                $parsed = $pname->getUserInfo();
+                if ($this->_downloader->discover($parsed['channel'])) {
+                    if ($this->_config->get('auto_discover')) {
+                        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                        $pname = $this->_registry->parsePackageName($param, $channel);
+                        PEAR::popErrorHandling();
+                    } else {
+                        if (!isset($options['soft'])) {
+                            $this->_downloader->log(0, 'Channel "' . $parsed['channel'] .
+                                '" is not initialized, use ' .
+                                '"pear channel-discover ' . $parsed['channel'] . '" to initialize' .
+                                'or pear config-set auto_discover 1');
+                        }
+                    }
+                }
+
+                if (PEAR::isError($pname)) {
+                    if (!isset($options['soft'])) {
+                        $this->_downloader->log(0, $pname->getMessage());
+                    }
+
+                    if (is_array($param)) {
+                        $param = $this->_registry->parsedPackageNameToString($param);
+                    }
+
+                    $err = PEAR::raiseError('invalid package name/package file "' . $param . '"');
+                    $this->_valid = false;
+                    return $err;
+                }
+            } else {
+                if (!isset($options['soft'])) {
+                    $this->_downloader->log(0, $pname->getMessage());
+                }
+
+                $err = PEAR::raiseError('invalid package name/package file "' . $param . '"');
+                $this->_valid = false;
+                return $err;
+            }
+        }
+
+        if (!isset($this->_type)) {
+            $this->_type = 'rest';
+        }
+
+        $this->_parsedname    = $pname;
+        $this->_explicitState = isset($pname['state']) ? $pname['state'] : false;
+        $this->_explicitGroup = isset($pname['group']) ? true : false;
+
+        $info = $this->_downloader->_getPackageDownloadUrl($pname);
+        if (PEAR::isError($info)) {
+            if ($info->getCode() != -976 && $pname['channel'] == 'pear.php.net') {
+                // try pecl
+                $pname['channel'] = 'pecl.php.net';
+                if ($test = $this->_downloader->_getPackageDownloadUrl($pname)) {
+                    if (!PEAR::isError($test)) {
+                        $info = PEAR::raiseError($info->getMessage() . ' - package ' .
+                            $this->_registry->parsedPackageNameToString($pname, true) .
+                            ' can be installed with "pecl install ' . $pname['package'] .
+                            '"');
+                    } else {
+                        $pname['channel'] = 'pear.php.net';
+                    }
+                } else {
+                    $pname['channel'] = 'pear.php.net';
+                }
+            }
+
+            return $info;
+        }
+
+        $this->_rawpackagefile = $info['raw'];
+        $ret = $this->_analyzeDownloadURL($info, $param, $pname);
+        if (PEAR::isError($ret)) {
+            return $ret;
+        }
+
+        if ($ret) {
+            $this->_downloadURL = $ret;
+            return $this->_valid = (bool) $ret;
+        }
+    }
+
+    /**
+     * @param array output of package.getDownloadURL
+     * @param string|array|object information for detecting packages to be downloaded, and
+     *                            for errors
+     * @param array name information of the package
+     * @param array|null packages to be downloaded
+     * @param bool is this an optional dependency?
+     * @param bool is this any kind of dependency?
+     * @access private
+     */
+    function _analyzeDownloadURL($info, $param, $pname, $params = null, $optional = false,
+                                 $isdependency = false)
+    {
+        if (!is_string($param) && PEAR_Downloader_Package::willDownload($param, $params)) {
+            return false;
+        }
+
+        if ($info === false) {
+            $saveparam = !is_string($param) ? ", cannot download \"$param\"" : '';
+
+            // no releases exist
+            return PEAR::raiseError('No releases for package "' .
+                $this->_registry->parsedPackageNameToString($pname, true) . '" exist' . $saveparam);
+        }
+
+        if (strtolower($info['info']->getChannel()) != strtolower($pname['channel'])) {
+            $err = false;
+            if ($pname['channel'] == 'pecl.php.net') {
+                if ($info['info']->getChannel() != 'pear.php.net') {
+                    $err = true;
+                }
+            } elseif ($info['info']->getChannel() == 'pecl.php.net') {
+                if ($pname['channel'] != 'pear.php.net') {
+                    $err = true;
+                }
+            } else {
+                $err = true;
+            }
+
+            if ($err) {
+                return PEAR::raiseError('SECURITY ERROR: package in channel "' . $pname['channel'] .
+                    '" retrieved another channel\'s name for download! ("' .
+                    $info['info']->getChannel() . '")');
+            }
+        }
+
+        $preferred_state = $this->_config->get('preferred_state');
+        if (!isset($info['url'])) {
+            $package_version = $this->_registry->packageInfo($info['info']->getPackage(),
+            'version', $info['info']->getChannel());
+            if ($this->isInstalled($info)) {
+                if ($isdependency && version_compare($info['version'], $package_version, '<=')) {
+                    // ignore bogus errors of "failed to download dependency"
+                    // if it is already installed and the one that would be
+                    // downloaded is older or the same version (Bug #7219)
+                    return false;
+                }
+            }
+
+            if ($info['version'] === $package_version) {
+                if (!isset($options['soft'])) {
+                    $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] .
+                        '/' . $pname['package'] . '-' . $package_version. ', additionally the suggested version' .
+                        ' (' . $package_version . ') is the same as the locally installed one.');
+                }
+
+                return false;
+            }
+
+            if (version_compare($info['version'], $package_version, '<=')) {
+                if (!isset($options['soft'])) {
+                    $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] .
+                        '/' . $pname['package'] . '-' . $package_version . ', additionally the suggested version' .
+                        ' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').');
+                }
+
+                return false;
+            }
+
+            $instead =  ', will instead download version ' . $info['version'] .
+                        ', stability "' . $info['info']->getState() . '"';
+            // releases exist, but we failed to get any
+            if (isset($this->_downloader->_options['force'])) {
+                if (isset($pname['version'])) {
+                    $vs = ', version "' . $pname['version'] . '"';
+                } elseif (isset($pname['state'])) {
+                    $vs = ', stability "' . $pname['state'] . '"';
+                } elseif ($param == 'dependency') {
+                    if (!class_exists('PEAR_Common')) {
+                        require_once 'PEAR/Common.php';
+                    }
+
+                    if (!in_array($info['info']->getState(),
+                          PEAR_Common::betterStates($preferred_state, true))) {
+                        if ($optional) {
+                            // don't spit out confusing error message
+                            return $this->_downloader->_getPackageDownloadUrl(
+                                array('package' => $pname['package'],
+                                      'channel' => $pname['channel'],
+                                      'version' => $info['version']));
+                        }
+                        $vs = ' within preferred state "' . $preferred_state .
+                            '"';
+                    } else {
+                        if (!class_exists('PEAR_Dependency2')) {
+                            require_once 'PEAR/Dependency2.php';
+                        }
+
+                        if ($optional) {
+                            // don't spit out confusing error message
+                            return $this->_downloader->_getPackageDownloadUrl(
+                                array('package' => $pname['package'],
+                                      'channel' => $pname['channel'],
+                                      'version' => $info['version']));
+                        }
+                        $vs = PEAR_Dependency2::_getExtraString($pname);
+                        $instead = '';
+                    }
+                } else {
+                    $vs = ' within preferred state "' . $preferred_state . '"';
+                }
+
+                if (!isset($options['soft'])) {
+                    $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] .
+                        '/' . $pname['package'] . $vs . $instead);
+                }
+
+                // download the latest release
+                return $this->_downloader->_getPackageDownloadUrl(
+                    array('package' => $pname['package'],
+                          'channel' => $pname['channel'],
+                          'version' => $info['version']));
+            } else {
+                if (isset($info['php']) && $info['php']) {
+                    $err = PEAR::raiseError('Failed to download ' .
+                        $this->_registry->parsedPackageNameToString(
+                            array('channel' => $pname['channel'],
+                                  'package' => $pname['package']),
+                                true) .
+                        ', latest release is version ' . $info['php']['v'] .
+                        ', but it requires PHP version "' .
+                        $info['php']['m'] . '", use "' .
+                        $this->_registry->parsedPackageNameToString(
+                            array('channel' => $pname['channel'], 'package' => $pname['package'],
+                            'version' => $info['php']['v'])) . '" to install',
+                            PEAR_DOWNLOADER_PACKAGE_PHPVERSION);
+                    return $err;
+                }
+
+                // construct helpful error message
+                if (isset($pname['version'])) {
+                    $vs = ', version "' . $pname['version'] . '"';
+                } elseif (isset($pname['state'])) {
+                    $vs = ', stability "' . $pname['state'] . '"';
+                } elseif ($param == 'dependency') {
+                    if (!class_exists('PEAR_Common')) {
+                        require_once 'PEAR/Common.php';
+                    }
+
+                    if (!in_array($info['info']->getState(),
+                          PEAR_Common::betterStates($preferred_state, true))) {
+                        if ($optional) {
+                            // don't spit out confusing error message, and don't die on
+                            // optional dep failure!
+                            return $this->_downloader->_getPackageDownloadUrl(
+                                array('package' => $pname['package'],
+                                      'channel' => $pname['channel'],
+                                      'version' => $info['version']));
+                        }
+                        $vs = ' within preferred state "' . $preferred_state . '"';
+                    } else {
+                        if (!class_exists('PEAR_Dependency2')) {
+                            require_once 'PEAR/Dependency2.php';
+                        }
+
+                        if ($optional) {
+                            // don't spit out confusing error message, and don't die on
+                            // optional dep failure!
+                            return $this->_downloader->_getPackageDownloadUrl(
+                                array('package' => $pname['package'],
+                                      'channel' => $pname['channel'],
+                                      'version' => $info['version']));
+                        }
+                        $vs = PEAR_Dependency2::_getExtraString($pname);
+                    }
+                } else {
+                    $vs = ' within preferred state "' . $this->_downloader->config->get('preferred_state') . '"';
+                }
+
+                $options = $this->_downloader->getOptions();
+                // this is only set by the "download-all" command
+                if (isset($options['ignorepreferred_state'])) {
+                    $err = PEAR::raiseError(
+                        'Failed to download ' . $this->_registry->parsedPackageNameToString(
+                            array('channel' => $pname['channel'], 'package' => $pname['package']),
+                                true)
+                         . $vs .
+                        ', latest release is version ' . $info['version'] .
+                        ', stability "' . $info['info']->getState() . '", use "' .
+                        $this->_registry->parsedPackageNameToString(
+                            array('channel' => $pname['channel'], 'package' => $pname['package'],
+                            'version' => $info['version'])) . '" to install',
+                            PEAR_DOWNLOADER_PACKAGE_STATE);
+                    return $err;
+                }
+
+                // Checks if the user has a package installed already and checks the release against
+                // the state against the installed package, this allows upgrades for packages
+                // with lower stability than the preferred_state
+                $stability = $this->_registry->packageInfo($pname['package'], 'stability', $pname['channel']);
+                if (!$this->isInstalled($info)
+                    || !in_array($info['info']->getState(), PEAR_Common::betterStates($stability['release'], true))
+                ) {
+                    $err = PEAR::raiseError(
+                        'Failed to download ' . $this->_registry->parsedPackageNameToString(
+                            array('channel' => $pname['channel'], 'package' => $pname['package']),
+                                true)
+                         . $vs .
+                        ', latest release is version ' . $info['version'] .
+                        ', stability "' . $info['info']->getState() . '", use "' .
+                        $this->_registry->parsedPackageNameToString(
+                            array('channel' => $pname['channel'], 'package' => $pname['package'],
+                            'version' => $info['version'])) . '" to install');
+                    return $err;
+                }
+            }
+        }
+
+        if (isset($info['deprecated']) && $info['deprecated']) {
+            $this->_downloader->log(0,
+                'WARNING: "' .
+                    $this->_registry->parsedPackageNameToString(
+                            array('channel' => $info['info']->getChannel(),
+                                  'package' => $info['info']->getPackage()), true) .
+                '" is deprecated in favor of "' .
+                    $this->_registry->parsedPackageNameToString($info['deprecated'], true) .
+                '"');
+        }
+
+        return $info;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/ErrorStack.php b/lib/php/PEAR/ErrorStack.php
new file mode 100644
index 00000000..7072ac9f
--- /dev/null
+++ b/lib/php/PEAR/ErrorStack.php
@@ -0,0 +1,985 @@
+<?php
+/**
+ * Error Stack Implementation
+ * 
+ * This is an incredibly simple implementation of a very complex error handling
+ * facility.  It contains the ability
+ * to track multiple errors from multiple packages simultaneously.  In addition,
+ * it can track errors of many levels, save data along with the error, context
+ * information such as the exact file, line number, class and function that
+ * generated the error, and if necessary, it can raise a traditional PEAR_Error.
+ * It has built-in support for PEAR::Log, to log errors as they occur
+ * 
+ * Since version 0.2alpha, it is also possible to selectively ignore errors,
+ * through the use of an error callback, see {@link pushCallback()}
+ * 
+ * Since version 0.3alpha, it is possible to specify the exception class
+ * returned from {@link push()}
+ *
+ * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class.  This can
+ * still be done quite handily in an error callback or by manipulating the returned array
+ * @category   Debugging
+ * @package    PEAR_ErrorStack
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  2004-2008 Greg Beaver
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR_ErrorStack
+ */
+
+/**
+ * Singleton storage
+ * 
+ * Format:
+ * <pre>
+ * array(
+ *  'package1' => PEAR_ErrorStack object,
+ *  'package2' => PEAR_ErrorStack object,
+ *  ...
+ * )
+ * </pre>
+ * @access private
+ * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']
+ */
+$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();
+
+/**
+ * Global error callback (default)
+ * 
+ * This is only used if set to non-false.  * is the default callback for
+ * all packages, whereas specific packages may set a default callback
+ * for all instances, regardless of whether they are a singleton or not.
+ *
+ * To exclude non-singletons, only set the local callback for the singleton
+ * @see PEAR_ErrorStack::setDefaultCallback()
+ * @access private
+ * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']
+ */
+$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
+    '*' => false,
+);
+
+/**
+ * Global Log object (default)
+ * 
+ * This is only used if set to non-false.  Use to set a default log object for
+ * all stacks, regardless of instantiation order or location
+ * @see PEAR_ErrorStack::setDefaultLogger()
+ * @access private
+ * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
+ */
+$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;
+
+/**
+ * Global Overriding Callback
+ * 
+ * This callback will override any error callbacks that specific loggers have set.
+ * Use with EXTREME caution
+ * @see PEAR_ErrorStack::staticPushCallback()
+ * @access private
+ * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
+ */
+$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
+
+/**#@+
+ * One of four possible return values from the error Callback
+ * @see PEAR_ErrorStack::_errorCallback()
+ */
+/**
+ * If this is returned, then the error will be both pushed onto the stack
+ * and logged.
+ */
+define('PEAR_ERRORSTACK_PUSHANDLOG', 1);
+/**
+ * If this is returned, then the error will only be pushed onto the stack,
+ * and not logged.
+ */
+define('PEAR_ERRORSTACK_PUSH', 2);
+/**
+ * If this is returned, then the error will only be logged, but not pushed
+ * onto the error stack.
+ */
+define('PEAR_ERRORSTACK_LOG', 3);
+/**
+ * If this is returned, then the error is completely ignored.
+ */
+define('PEAR_ERRORSTACK_IGNORE', 4);
+/**
+ * If this is returned, then the error is logged and die() is called.
+ */
+define('PEAR_ERRORSTACK_DIE', 5);
+/**#@-*/
+
+/**
+ * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in
+ * the singleton method.
+ */
+define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);
+
+/**
+ * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}
+ * that has no __toString() method
+ */
+define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
+/**
+ * Error Stack Implementation
+ *
+ * Usage:
+ * <code>
+ * // global error stack
+ * $global_stack = &PEAR_ErrorStack::singleton('MyPackage');
+ * // local error stack
+ * $local_stack = new PEAR_ErrorStack('MyPackage');
+ * </code>
+ * @author     Greg Beaver <cellog@php.net>
+ * @version    1.9.0
+ * @package    PEAR_ErrorStack
+ * @category   Debugging
+ * @copyright  2004-2008 Greg Beaver
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR_ErrorStack
+ */
+class PEAR_ErrorStack {
+    /**
+     * Errors are stored in the order that they are pushed on the stack.
+     * @since 0.4alpha Errors are no longer organized by error level.
+     * This renders pop() nearly unusable, and levels could be more easily
+     * handled in a callback anyway
+     * @var array
+     * @access private
+     */
+    var $_errors = array();
+
+    /**
+     * Storage of errors by level.
+     *
+     * Allows easy retrieval and deletion of only errors from a particular level
+     * @since PEAR 1.4.0dev
+     * @var array
+     * @access private
+     */
+    var $_errorsByLevel = array();
+
+    /**
+     * Package name this error stack represents
+     * @var string
+     * @access protected
+     */
+    var $_package;
+    
+    /**
+     * Determines whether a PEAR_Error is thrown upon every error addition
+     * @var boolean
+     * @access private
+     */
+    var $_compat = false;
+    
+    /**
+     * If set to a valid callback, this will be used to generate the error
+     * message from the error code, otherwise the message passed in will be
+     * used
+     * @var false|string|array
+     * @access private
+     */
+    var $_msgCallback = false;
+    
+    /**
+     * If set to a valid callback, this will be used to generate the error
+     * context for an error.  For PHP-related errors, this will be a file
+     * and line number as retrieved from debug_backtrace(), but can be
+     * customized for other purposes.  The error might actually be in a separate
+     * configuration file, or in a database query.
+     * @var false|string|array
+     * @access protected
+     */
+    var $_contextCallback = false;
+    
+    /**
+     * If set to a valid callback, this will be called every time an error
+     * is pushed onto the stack.  The return value will be used to determine
+     * whether to allow an error to be pushed or logged.
+     * 
+     * The return value must be one an PEAR_ERRORSTACK_* constant
+     * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
+     * @var false|string|array
+     * @access protected
+     */
+    var $_errorCallback = array();
+    
+    /**
+     * PEAR::Log object for logging errors
+     * @var false|Log
+     * @access protected
+     */
+    var $_logger = false;
+    
+    /**
+     * Error messages - designed to be overridden
+     * @var array
+     * @abstract
+     */
+    var $_errorMsgs = array();
+    
+    /**
+     * Set up a new error stack
+     * 
+     * @param string   $package name of the package this error stack represents
+     * @param callback $msgCallback callback used for error message generation
+     * @param callback $contextCallback callback used for context generation,
+     *                 defaults to {@link getFileLine()}
+     * @param boolean  $throwPEAR_Error
+     */
+    function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false,
+                         $throwPEAR_Error = false)
+    {
+        $this->_package = $package;
+        $this->setMessageCallback($msgCallback);
+        $this->setContextCallback($contextCallback);
+        $this->_compat = $throwPEAR_Error;
+    }
+    
+    /**
+     * Return a single error stack for this package.
+     * 
+     * Note that all parameters are ignored if the stack for package $package
+     * has already been instantiated
+     * @param string   $package name of the package this error stack represents
+     * @param callback $msgCallback callback used for error message generation
+     * @param callback $contextCallback callback used for context generation,
+     *                 defaults to {@link getFileLine()}
+     * @param boolean  $throwPEAR_Error
+     * @param string   $stackClass class to instantiate
+     * @static
+     * @return PEAR_ErrorStack
+     */
+    function &singleton($package, $msgCallback = false, $contextCallback = false,
+                         $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack')
+    {
+        if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
+            return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
+        }
+        if (!class_exists($stackClass)) {
+            if (function_exists('debug_backtrace')) {
+                $trace = debug_backtrace();
+            }
+            PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,
+                'exception', array('stackclass' => $stackClass),
+                'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
+                false, $trace);
+        }
+        $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
+            new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
+
+        return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
+    }
+
+    /**
+     * Internal error handler for PEAR_ErrorStack class
+     * 
+     * Dies if the error is an exception (and would have died anyway)
+     * @access private
+     */
+    function _handleError($err)
+    {
+        if ($err['level'] == 'exception') {
+            $message = $err['message'];
+            if (isset($_SERVER['REQUEST_URI'])) {
+                echo '<br />';
+            } else {
+                echo "\n";
+            }
+            var_dump($err['context']);
+            die($message);
+        }
+    }
+    
+    /**
+     * Set up a PEAR::Log object for all error stacks that don't have one
+     * @param Log $log 
+     * @static
+     */
+    function setDefaultLogger(&$log)
+    {
+        if (is_object($log) && method_exists($log, 'log') ) {
+            $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
+        } elseif (is_callable($log)) {
+            $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
+	}
+    }
+    
+    /**
+     * Set up a PEAR::Log object for this error stack
+     * @param Log $log 
+     */
+    function setLogger(&$log)
+    {
+        if (is_object($log) && method_exists($log, 'log') ) {
+            $this->_logger = &$log;
+        } elseif (is_callable($log)) {
+            $this->_logger = &$log;
+        }
+    }
+    
+    /**
+     * Set an error code => error message mapping callback
+     * 
+     * This method sets the callback that can be used to generate error
+     * messages for any instance
+     * @param array|string Callback function/method
+     */
+    function setMessageCallback($msgCallback)
+    {
+        if (!$msgCallback) {
+            $this->_msgCallback = array(&$this, 'getErrorMessage');
+        } else {
+            if (is_callable($msgCallback)) {
+                $this->_msgCallback = $msgCallback;
+            }
+        }
+    }
+    
+    /**
+     * Get an error code => error message mapping callback
+     * 
+     * This method returns the current callback that can be used to generate error
+     * messages
+     * @return array|string|false Callback function/method or false if none
+     */
+    function getMessageCallback()
+    {
+        return $this->_msgCallback;
+    }
+    
+    /**
+     * Sets a default callback to be used by all error stacks
+     * 
+     * This method sets the callback that can be used to generate error
+     * messages for a singleton
+     * @param array|string Callback function/method
+     * @param string Package name, or false for all packages
+     * @static
+     */
+    function setDefaultCallback($callback = false, $package = false)
+    {
+        if (!is_callable($callback)) {
+            $callback = false;
+        }
+        $package = $package ? $package : '*';
+        $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
+    }
+    
+    /**
+     * Set a callback that generates context information (location of error) for an error stack
+     * 
+     * This method sets the callback that can be used to generate context
+     * information for an error.  Passing in NULL will disable context generation
+     * and remove the expensive call to debug_backtrace()
+     * @param array|string|null Callback function/method
+     */
+    function setContextCallback($contextCallback)
+    {
+        if ($contextCallback === null) {
+            return $this->_contextCallback = false;
+        }
+        if (!$contextCallback) {
+            $this->_contextCallback = array(&$this, 'getFileLine');
+        } else {
+            if (is_callable($contextCallback)) {
+                $this->_contextCallback = $contextCallback;
+            }
+        }
+    }
+    
+    /**
+     * Set an error Callback
+     * If set to a valid callback, this will be called every time an error
+     * is pushed onto the stack.  The return value will be used to determine
+     * whether to allow an error to be pushed or logged.
+     * 
+     * The return value must be one of the ERRORSTACK_* constants.
+     * 
+     * This functionality can be used to emulate PEAR's pushErrorHandling, and
+     * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of
+     * the error stack or logging
+     * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
+     * @see popCallback()
+     * @param string|array $cb
+     */
+    function pushCallback($cb)
+    {
+        array_push($this->_errorCallback, $cb);
+    }
+    
+    /**
+     * Remove a callback from the error callback stack
+     * @see pushCallback()
+     * @return array|string|false
+     */
+    function popCallback()
+    {
+        if (!count($this->_errorCallback)) {
+            return false;
+        }
+        return array_pop($this->_errorCallback);
+    }
+    
+    /**
+     * Set a temporary overriding error callback for every package error stack
+     *
+     * Use this to temporarily disable all existing callbacks (can be used
+     * to emulate the @ operator, for instance)
+     * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
+     * @see staticPopCallback(), pushCallback()
+     * @param string|array $cb
+     * @static
+     */
+    function staticPushCallback($cb)
+    {
+        array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
+    }
+    
+    /**
+     * Remove a temporary overriding error callback
+     * @see staticPushCallback()
+     * @return array|string|false
+     * @static
+     */
+    function staticPopCallback()
+    {
+        $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
+        if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
+            $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
+        }
+        return $ret;
+    }
+    
+    /**
+     * Add an error to the stack
+     * 
+     * If the message generator exists, it is called with 2 parameters.
+     *  - the current Error Stack object
+     *  - an array that is in the same format as an error.  Available indices
+     *    are 'code', 'package', 'time', 'params', 'level', and 'context'
+     * 
+     * Next, if the error should contain context information, this is
+     * handled by the context grabbing method.
+     * Finally, the error is pushed onto the proper error stack
+     * @param int    $code      Package-specific error code
+     * @param string $level     Error level.  This is NOT spell-checked
+     * @param array  $params    associative array of error parameters
+     * @param string $msg       Error message, or a portion of it if the message
+     *                          is to be generated
+     * @param array  $repackage If this error re-packages an error pushed by
+     *                          another package, place the array returned from
+     *                          {@link pop()} in this parameter
+     * @param array  $backtrace Protected parameter: use this to pass in the
+     *                          {@link debug_backtrace()} that should be used
+     *                          to find error context
+     * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
+     * thrown.  If a PEAR_Error is returned, the userinfo
+     * property is set to the following array:
+     * 
+     * <code>
+     * array(
+     *    'code' => $code,
+     *    'params' => $params,
+     *    'package' => $this->_package,
+     *    'level' => $level,
+     *    'time' => time(),
+     *    'context' => $context,
+     *    'message' => $msg,
+     * //['repackage' => $err] repackaged error array/Exception class
+     * );
+     * </code>
+     * 
+     * Normally, the previous array is returned.
+     */
+    function push($code, $level = 'error', $params = array(), $msg = false,
+                  $repackage = false, $backtrace = false)
+    {
+        $context = false;
+        // grab error context
+        if ($this->_contextCallback) {
+            if (!$backtrace) {
+                $backtrace = debug_backtrace();
+            }
+            $context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
+        }
+        
+        // save error
+        $time = explode(' ', microtime());
+        $time = $time[1] + $time[0];
+        $err = array(
+                'code' => $code,
+                'params' => $params,
+                'package' => $this->_package,
+                'level' => $level,
+                'time' => $time,
+                'context' => $context,
+                'message' => $msg,
+               );
+
+        if ($repackage) {
+            $err['repackage'] = $repackage;
+        }
+
+        // set up the error message, if necessary
+        if ($this->_msgCallback) {
+            $msg = call_user_func_array($this->_msgCallback,
+                                        array(&$this, $err));
+            $err['message'] = $msg;
+        }        
+        $push = $log = true;
+        $die = false;
+        // try the overriding callback first
+        $callback = $this->staticPopCallback();
+        if ($callback) {
+            $this->staticPushCallback($callback);
+        }
+        if (!is_callable($callback)) {
+            // try the local callback next
+            $callback = $this->popCallback();
+            if (is_callable($callback)) {
+                $this->pushCallback($callback);
+            } else {
+                // try the default callback
+                $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
+                    $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :
+                    $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];
+            }
+        }
+        if (is_callable($callback)) {
+            switch(call_user_func($callback, $err)){
+            	case PEAR_ERRORSTACK_IGNORE: 
+            		return $err;
+        		break;
+            	case PEAR_ERRORSTACK_PUSH: 
+            		$log = false;
+        		break;
+            	case PEAR_ERRORSTACK_LOG: 
+            		$push = false;
+        		break;
+            	case PEAR_ERRORSTACK_DIE: 
+            		$die = true;
+        		break;
+                // anything else returned has the same effect as pushandlog
+            }
+        }
+        if ($push) {
+            array_unshift($this->_errors, $err);
+            if (!isset($this->_errorsByLevel[$err['level']])) {
+                $this->_errorsByLevel[$err['level']] = array();
+            }
+            $this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
+        }
+        if ($log) {
+            if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
+                $this->_log($err);
+            }
+        }
+        if ($die) {
+            die();
+        }
+        if ($this->_compat && $push) {
+            return $this->raiseError($msg, $code, null, null, $err);
+        }
+        return $err;
+    }
+    
+    /**
+     * Static version of {@link push()}
+     * 
+     * @param string $package   Package name this error belongs to
+     * @param int    $code      Package-specific error code
+     * @param string $level     Error level.  This is NOT spell-checked
+     * @param array  $params    associative array of error parameters
+     * @param string $msg       Error message, or a portion of it if the message
+     *                          is to be generated
+     * @param array  $repackage If this error re-packages an error pushed by
+     *                          another package, place the array returned from
+     *                          {@link pop()} in this parameter
+     * @param array  $backtrace Protected parameter: use this to pass in the
+     *                          {@link debug_backtrace()} that should be used
+     *                          to find error context
+     * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
+     *                          thrown.  see docs for {@link push()}
+     * @static
+     */
+    function staticPush($package, $code, $level = 'error', $params = array(),
+                        $msg = false, $repackage = false, $backtrace = false)
+    {
+        $s = &PEAR_ErrorStack::singleton($package);
+        if ($s->_contextCallback) {
+            if (!$backtrace) {
+                if (function_exists('debug_backtrace')) {
+                    $backtrace = debug_backtrace();
+                }
+            }
+        }
+        return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
+    }
+    
+    /**
+     * Log an error using PEAR::Log
+     * @param array $err Error array
+     * @param array $levels Error level => Log constant map
+     * @access protected
+     */
+    function _log($err)
+    {
+        if ($this->_logger) {
+            $logger = &$this->_logger;
+        } else {
+            $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
+        }
+        if (is_a($logger, 'Log')) {
+            $levels = array(
+                'exception' => PEAR_LOG_CRIT,
+                'alert' => PEAR_LOG_ALERT,
+                'critical' => PEAR_LOG_CRIT,
+                'error' => PEAR_LOG_ERR,
+                'warning' => PEAR_LOG_WARNING,
+                'notice' => PEAR_LOG_NOTICE,
+                'info' => PEAR_LOG_INFO,
+                'debug' => PEAR_LOG_DEBUG);
+            if (isset($levels[$err['level']])) {
+                $level = $levels[$err['level']];
+            } else {
+                $level = PEAR_LOG_INFO;
+            }
+            $logger->log($err['message'], $level, $err);
+        } else { // support non-standard logs
+            call_user_func($logger, $err);
+        }
+    }
+
+    
+    /**
+     * Pop an error off of the error stack
+     * 
+     * @return false|array
+     * @since 0.4alpha it is no longer possible to specify a specific error
+     * level to return - the last error pushed will be returned, instead
+     */
+    function pop()
+    {
+        $err = @array_shift($this->_errors);
+        if (!is_null($err)) {
+            @array_pop($this->_errorsByLevel[$err['level']]);
+            if (!count($this->_errorsByLevel[$err['level']])) {
+                unset($this->_errorsByLevel[$err['level']]);
+            }
+        }
+        return $err;
+    }
+
+    /**
+     * Pop an error off of the error stack, static method
+     *
+     * @param string package name
+     * @return boolean
+     * @since PEAR1.5.0a1
+     */
+    function staticPop($package)
+    {
+        if ($package) {
+            if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
+                return false;
+            }
+            return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
+        }
+    }
+
+    /**
+     * Determine whether there are any errors on the stack
+     * @param string|array Level name.  Use to determine if any errors
+     * of level (string), or levels (array) have been pushed
+     * @return boolean
+     */
+    function hasErrors($level = false)
+    {
+        if ($level) {
+            return isset($this->_errorsByLevel[$level]);
+        }
+        return count($this->_errors);
+    }
+    
+    /**
+     * Retrieve all errors since last purge
+     * 
+     * @param boolean set in order to empty the error stack
+     * @param string level name, to return only errors of a particular severity
+     * @return array
+     */
+    function getErrors($purge = false, $level = false)
+    {
+        if (!$purge) {
+            if ($level) {
+                if (!isset($this->_errorsByLevel[$level])) {
+                    return array();
+                } else {
+                    return $this->_errorsByLevel[$level];
+                }
+            } else {
+                return $this->_errors;
+            }
+        }
+        if ($level) {
+            $ret = $this->_errorsByLevel[$level];
+            foreach ($this->_errorsByLevel[$level] as $i => $unused) {
+                // entries are references to the $_errors array
+                $this->_errorsByLevel[$level][$i] = false;
+            }
+            // array_filter removes all entries === false
+            $this->_errors = array_filter($this->_errors);
+            unset($this->_errorsByLevel[$level]);
+            return $ret;
+        }
+        $ret = $this->_errors;
+        $this->_errors = array();
+        $this->_errorsByLevel = array();
+        return $ret;
+    }
+    
+    /**
+     * Determine whether there are any errors on a single error stack, or on any error stack
+     *
+     * The optional parameter can be used to test the existence of any errors without the need of
+     * singleton instantiation
+     * @param string|false Package name to check for errors
+     * @param string Level name to check for a particular severity
+     * @return boolean
+     * @static
+     */
+    function staticHasErrors($package = false, $level = false)
+    {
+        if ($package) {
+            if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
+                return false;
+            }
+            return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
+        }
+        foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
+            if ($obj->hasErrors($level)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Get a list of all errors since last purge, organized by package
+     * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be
+     * @param boolean $purge Set to purge the error stack of existing errors
+     * @param string  $level Set to a level name in order to retrieve only errors of a particular level
+     * @param boolean $merge Set to return a flat array, not organized by package
+     * @param array   $sortfunc Function used to sort a merged array - default
+     *        sorts by time, and should be good for most cases
+     * @static
+     * @return array 
+     */
+    function staticGetErrors($purge = false, $level = false, $merge = false,
+                             $sortfunc = array('PEAR_ErrorStack', '_sortErrors'))
+    {
+        $ret = array();
+        if (!is_callable($sortfunc)) {
+            $sortfunc = array('PEAR_ErrorStack', '_sortErrors');
+        }
+        foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
+            $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
+            if ($test) {
+                if ($merge) {
+                    $ret = array_merge($ret, $test);
+                } else {
+                    $ret[$package] = $test;
+                }
+            }
+        }
+        if ($merge) {
+            usort($ret, $sortfunc);
+        }
+        return $ret;
+    }
+    
+    /**
+     * Error sorting function, sorts by time
+     * @access private
+     */
+    function _sortErrors($a, $b)
+    {
+        if ($a['time'] == $b['time']) {
+            return 0;
+        }
+        if ($a['time'] < $b['time']) {
+            return 1;
+        }
+        return -1;
+    }
+
+    /**
+     * Standard file/line number/function/class context callback
+     *
+     * This function uses a backtrace generated from {@link debug_backtrace()}
+     * and so will not work at all in PHP < 4.3.0.  The frame should
+     * reference the frame that contains the source of the error.
+     * @return array|false either array('file' => file, 'line' => line,
+     *         'function' => function name, 'class' => class name) or
+     *         if this doesn't work, then false
+     * @param unused
+     * @param integer backtrace frame.
+     * @param array Results of debug_backtrace()
+     * @static
+     */
+    function getFileLine($code, $params, $backtrace = null)
+    {
+        if ($backtrace === null) {
+            return false;
+        }
+        $frame = 0;
+        $functionframe = 1;
+        if (!isset($backtrace[1])) {
+            $functionframe = 0;
+        } else {
+            while (isset($backtrace[$functionframe]['function']) &&
+                  $backtrace[$functionframe]['function'] == 'eval' &&
+                  isset($backtrace[$functionframe + 1])) {
+                $functionframe++;
+            }
+        }
+        if (isset($backtrace[$frame])) {
+            if (!isset($backtrace[$frame]['file'])) {
+                $frame++;
+            }
+            $funcbacktrace = $backtrace[$functionframe];
+            $filebacktrace = $backtrace[$frame];
+            $ret = array('file' => $filebacktrace['file'],
+                         'line' => $filebacktrace['line']);
+            // rearrange for eval'd code or create function errors
+            if (strpos($filebacktrace['file'], '(') && 
+            	  preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
+                  $matches)) {
+                $ret['file'] = $matches[1];
+                $ret['line'] = $matches[2] + 0;
+            }
+            if (isset($funcbacktrace['function']) && isset($backtrace[1])) {
+                if ($funcbacktrace['function'] != 'eval') {
+                    if ($funcbacktrace['function'] == '__lambda_func') {
+                        $ret['function'] = 'create_function() code';
+                    } else {
+                        $ret['function'] = $funcbacktrace['function'];
+                    }
+                }
+            }
+            if (isset($funcbacktrace['class']) && isset($backtrace[1])) {
+                $ret['class'] = $funcbacktrace['class'];
+            }
+            return $ret;
+        }
+        return false;
+    }
+    
+    /**
+     * Standard error message generation callback
+     * 
+     * This method may also be called by a custom error message generator
+     * to fill in template values from the params array, simply
+     * set the third parameter to the error message template string to use
+     * 
+     * The special variable %__msg% is reserved: use it only to specify
+     * where a message passed in by the user should be placed in the template,
+     * like so:
+     * 
+     * Error message: %msg% - internal error
+     * 
+     * If the message passed like so:
+     * 
+     * <code>
+     * $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
+     * </code>
+     * 
+     * The returned error message will be "Error message: server error 500 -
+     * internal error"
+     * @param PEAR_ErrorStack
+     * @param array
+     * @param string|false Pre-generated error message template
+     * @static
+     * @return string
+     */
+    function getErrorMessage(&$stack, $err, $template = false)
+    {
+        if ($template) {
+            $mainmsg = $template;
+        } else {
+            $mainmsg = $stack->getErrorMessageTemplate($err['code']);
+        }
+        $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
+        if (is_array($err['params']) && count($err['params'])) {
+            foreach ($err['params'] as $name => $val) {
+                if (is_array($val)) {
+                    // @ is needed in case $val is a multi-dimensional array
+                    $val = @implode(', ', $val);
+                }
+                if (is_object($val)) {
+                    if (method_exists($val, '__toString')) {
+                        $val = $val->__toString();
+                    } else {
+                        PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,
+                            'warning', array('obj' => get_class($val)),
+                            'object %obj% passed into getErrorMessage, but has no __toString() method');
+                        $val = 'Object';
+                    }
+                }
+                $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
+            }
+        }
+        return $mainmsg;
+    }
+    
+    /**
+     * Standard Error Message Template generator from code
+     * @return string
+     */
+    function getErrorMessageTemplate($code)
+    {
+        if (!isset($this->_errorMsgs[$code])) {
+            return '%__msg%';
+        }
+        return $this->_errorMsgs[$code];
+    }
+    
+    /**
+     * Set the Error Message Template array
+     * 
+     * The array format must be:
+     * <pre>
+     * array(error code => 'message template',...)
+     * </pre>
+     * 
+     * Error message parameters passed into {@link push()} will be used as input
+     * for the error message.  If the template is 'message %foo% was %bar%', and the
+     * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
+     * be 'message one was six'
+     * @return string
+     */
+    function setErrorMessageTemplate($template)
+    {
+        $this->_errorMsgs = $template;
+    }
+    
+    
+    /**
+     * emulate PEAR::raiseError()
+     * 
+     * @return PEAR_Error
+     */
+    function raiseError()
+    {
+        require_once 'PEAR.php';
+        $args = func_get_args();
+        return call_user_func_array(array('PEAR', 'raiseError'), $args);
+    }
+}
+$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
+$stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));
+?>
diff --git a/lib/php/PEAR/Exception.php b/lib/php/PEAR/Exception.php
new file mode 100644
index 00000000..ba4dd219
--- /dev/null
+++ b/lib/php/PEAR/Exception.php
@@ -0,0 +1,391 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+/**
+ * PEAR_Exception
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Hans Lellelid <hans@velum.net>
+ * @author     Bertrand Mansion <bmansion@mamasam.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Exception.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.3.3
+ */
+
+
+/**
+ * Base PEAR_Exception Class
+ *
+ * 1) Features:
+ *
+ * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
+ * - Definable triggers, shot when exceptions occur
+ * - Pretty and informative error messages
+ * - Added more context info available (like class, method or cause)
+ * - cause can be a PEAR_Exception or an array of mixed
+ *   PEAR_Exceptions/PEAR_ErrorStack warnings
+ * - callbacks for specific exception classes and their children
+ *
+ * 2) Ideas:
+ *
+ * - Maybe a way to define a 'template' for the output
+ *
+ * 3) Inherited properties from PHP Exception Class:
+ *
+ * protected $message
+ * protected $code
+ * protected $line
+ * protected $file
+ * private   $trace
+ *
+ * 4) Inherited methods from PHP Exception Class:
+ *
+ * __clone
+ * __construct
+ * getMessage
+ * getCode
+ * getFile
+ * getLine
+ * getTraceSafe
+ * getTraceSafeAsString
+ * __toString
+ *
+ * 5) Usage example
+ *
+ * <code>
+ *  require_once 'PEAR/Exception.php';
+ *
+ *  class Test {
+ *     function foo() {
+ *         throw new PEAR_Exception('Error Message', ERROR_CODE);
+ *     }
+ *  }
+ *
+ *  function myLogger($pear_exception) {
+ *     echo $pear_exception->getMessage();
+ *  }
+ *  // each time a exception is thrown the 'myLogger' will be called
+ *  // (its use is completely optional)
+ *  PEAR_Exception::addObserver('myLogger');
+ *  $test = new Test;
+ *  try {
+ *     $test->foo();
+ *  } catch (PEAR_Exception $e) {
+ *     print $e;
+ *  }
+ * </code>
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @author     Hans Lellelid <hans@velum.net>
+ * @author     Bertrand Mansion <bmansion@mamasam.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.3.3
+ *
+ */
+class PEAR_Exception extends Exception
+{
+    const OBSERVER_PRINT = -2;
+    const OBSERVER_TRIGGER = -4;
+    const OBSERVER_DIE = -8;
+    protected $cause;
+    private static $_observers = array();
+    private static $_uniqueid = 0;
+    private $_trace;
+
+    /**
+     * Supported signatures:
+     *  - PEAR_Exception(string $message);
+     *  - PEAR_Exception(string $message, int $code);
+     *  - PEAR_Exception(string $message, Exception $cause);
+     *  - PEAR_Exception(string $message, Exception $cause, int $code);
+     *  - PEAR_Exception(string $message, PEAR_Error $cause);
+     *  - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
+     *  - PEAR_Exception(string $message, array $causes);
+     *  - PEAR_Exception(string $message, array $causes, int $code);
+     * @param string exception message
+     * @param int|Exception|PEAR_Error|array|null exception cause
+     * @param int|null exception code or null
+     */
+    public function __construct($message, $p2 = null, $p3 = null)
+    {
+        if (is_int($p2)) {
+            $code = $p2;
+            $this->cause = null;
+        } elseif (is_object($p2) || is_array($p2)) {
+            // using is_object allows both Exception and PEAR_Error
+            if (is_object($p2) && !($p2 instanceof Exception)) {
+                if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
+                    throw new PEAR_Exception('exception cause must be Exception, ' .
+                        'array, or PEAR_Error');
+                }
+            }
+            $code = $p3;
+            if (is_array($p2) && isset($p2['message'])) {
+                // fix potential problem of passing in a single warning
+                $p2 = array($p2);
+            }
+            $this->cause = $p2;
+        } else {
+            $code = null;
+            $this->cause = null;
+        }
+        parent::__construct($message, $code);
+        $this->signal();
+    }
+
+    /**
+     * @param mixed $callback  - A valid php callback, see php func is_callable()
+     *                         - A PEAR_Exception::OBSERVER_* constant
+     *                         - An array(const PEAR_Exception::OBSERVER_*,
+     *                           mixed $options)
+     * @param string $label    The name of the observer. Use this if you want
+     *                         to remove it later with removeObserver()
+     */
+    public static function addObserver($callback, $label = 'default')
+    {
+        self::$_observers[$label] = $callback;
+    }
+
+    public static function removeObserver($label = 'default')
+    {
+        unset(self::$_observers[$label]);
+    }
+
+    /**
+     * @return int unique identifier for an observer
+     */
+    public static function getUniqueId()
+    {
+        return self::$_uniqueid++;
+    }
+
+    private function signal()
+    {
+        foreach (self::$_observers as $func) {
+            if (is_callable($func)) {
+                call_user_func($func, $this);
+                continue;
+            }
+            settype($func, 'array');
+            switch ($func[0]) {
+                case self::OBSERVER_PRINT :
+                    $f = (isset($func[1])) ? $func[1] : '%s';
+                    printf($f, $this->getMessage());
+                    break;
+                case self::OBSERVER_TRIGGER :
+                    $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
+                    trigger_error($this->getMessage(), $f);
+                    break;
+                case self::OBSERVER_DIE :
+                    $f = (isset($func[1])) ? $func[1] : '%s';
+                    die(printf($f, $this->getMessage()));
+                    break;
+                default:
+                    trigger_error('invalid observer type', E_USER_WARNING);
+            }
+        }
+    }
+
+    /**
+     * Return specific error information that can be used for more detailed
+     * error messages or translation.
+     *
+     * This method may be overridden in child exception classes in order
+     * to add functionality not present in PEAR_Exception and is a placeholder
+     * to define API
+     *
+     * The returned array must be an associative array of parameter => value like so:
+     * <pre>
+     * array('name' => $name, 'context' => array(...))
+     * </pre>
+     * @return array
+     */
+    public function getErrorData()
+    {
+        return array();
+    }
+
+    /**
+     * Returns the exception that caused this exception to be thrown
+     * @access public
+     * @return Exception|array The context of the exception
+     */
+    public function getCause()
+    {
+        return $this->cause;
+    }
+
+    /**
+     * Function must be public to call on caused exceptions
+     * @param array
+     */
+    public function getCauseMessage(&$causes)
+    {
+        $trace = $this->getTraceSafe();
+        $cause = array('class'   => get_class($this),
+                       'message' => $this->message,
+                       'file' => 'unknown',
+                       'line' => 'unknown');
+        if (isset($trace[0])) {
+            if (isset($trace[0]['file'])) {
+                $cause['file'] = $trace[0]['file'];
+                $cause['line'] = $trace[0]['line'];
+            }
+        }
+        $causes[] = $cause;
+        if ($this->cause instanceof PEAR_Exception) {
+            $this->cause->getCauseMessage($causes);
+        } elseif ($this->cause instanceof Exception) {
+            $causes[] = array('class'   => get_class($this->cause),
+                              'message' => $this->cause->getMessage(),
+                              'file' => $this->cause->getFile(),
+                              'line' => $this->cause->getLine());
+        } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
+            $causes[] = array('class' => get_class($this->cause),
+                              'message' => $this->cause->getMessage(),
+                              'file' => 'unknown',
+                              'line' => 'unknown');
+        } elseif (is_array($this->cause)) {
+            foreach ($this->cause as $cause) {
+                if ($cause instanceof PEAR_Exception) {
+                    $cause->getCauseMessage($causes);
+                } elseif ($cause instanceof Exception) {
+                    $causes[] = array('class'   => get_class($cause),
+                                   'message' => $cause->getMessage(),
+                                   'file' => $cause->getFile(),
+                                   'line' => $cause->getLine());
+                } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) {
+                    $causes[] = array('class' => get_class($cause),
+                                      'message' => $cause->getMessage(),
+                                      'file' => 'unknown',
+                                      'line' => 'unknown');
+                } elseif (is_array($cause) && isset($cause['message'])) {
+                    // PEAR_ErrorStack warning
+                    $causes[] = array(
+                        'class' => $cause['package'],
+                        'message' => $cause['message'],
+                        'file' => isset($cause['context']['file']) ?
+                                            $cause['context']['file'] :
+                                            'unknown',
+                        'line' => isset($cause['context']['line']) ?
+                                            $cause['context']['line'] :
+                                            'unknown',
+                    );
+                }
+            }
+        }
+    }
+
+    public function getTraceSafe()
+    {   
+        if (!isset($this->_trace)) {
+            $this->_trace = $this->getTrace();
+            if (empty($this->_trace)) {
+                $backtrace = debug_backtrace();
+                $this->_trace = array($backtrace[count($backtrace)-1]);
+            }
+        }
+        return $this->_trace;
+    }
+
+    public function getErrorClass()
+    {
+        $trace = $this->getTraceSafe();
+        return $trace[0]['class'];
+    }
+
+    public function getErrorMethod()
+    {
+        $trace = $this->getTraceSafe();
+        return $trace[0]['function'];
+    }
+
+    public function __toString()
+    {
+        if (isset($_SERVER['REQUEST_URI'])) {
+            return $this->toHtml();
+        }
+        return $this->toText();
+    }
+
+    public function toHtml()
+    {
+        $trace = $this->getTraceSafe();
+        $causes = array();
+        $this->getCauseMessage($causes);
+        $html =  '<table border="1" cellspacing="0">' . "\n";
+        foreach ($causes as $i => $cause) {
+            $html .= '<tr><td colspan="3" bgcolor="#ff9999">'
+               . str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
+               . htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
+               . 'on line <b>' . $cause['line'] . '</b>'
+               . "</td></tr>\n";
+        }
+        $html .= '<tr><td colspan="3" bgcolor="#aaaaaa" align="center"><b>Exception trace</b></td></tr>' . "\n"
+               . '<tr><td align="center" bgcolor="#cccccc" width="20"><b>#</b></td>'
+               . '<td align="center" bgcolor="#cccccc"><b>Function</b></td>'
+               . '<td align="center" bgcolor="#cccccc"><b>Location</b></td></tr>' . "\n";
+
+        foreach ($trace as $k => $v) {
+            $html .= '<tr><td align="center">' . $k . '</td>'
+                   . '<td>';
+            if (!empty($v['class'])) {
+                $html .= $v['class'] . $v['type'];
+            }
+            $html .= $v['function'];
+            $args = array();
+            if (!empty($v['args'])) {
+                foreach ($v['args'] as $arg) {
+                    if (is_null($arg)) $args[] = 'null';
+                    elseif (is_array($arg)) $args[] = 'Array';
+                    elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')';
+                    elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false';
+                    elseif (is_int($arg) || is_double($arg)) $args[] = $arg;
+                    else {
+                        $arg = (string)$arg;
+                        $str = htmlspecialchars(substr($arg, 0, 16));
+                        if (strlen($arg) > 16) $str .= '&hellip;';
+                        $args[] = "'" . $str . "'";
+                    }
+                }
+            }
+            $html .= '(' . implode(', ',$args) . ')'
+                   . '</td>'
+                   . '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
+                   . ':' . (isset($v['line']) ? $v['line'] : 'unknown')
+                   . '</td></tr>' . "\n";
+        }
+        $html .= '<tr><td align="center">' . ($k+1) . '</td>'
+               . '<td>{main}</td>'
+               . '<td>&nbsp;</td></tr>' . "\n"
+               . '</table>';
+        return $html;
+    }
+
+    public function toText()
+    {
+        $causes = array();
+        $this->getCauseMessage($causes);
+        $causeMsg = '';
+        foreach ($causes as $i => $cause) {
+            $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
+                   . $cause['message'] . ' in ' . $cause['file']
+                   . ' on line ' . $cause['line'] . "\n";
+        }
+        return $causeMsg . $this->getTraceAsString();
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/FixPHP5PEARWarnings.php b/lib/php/PEAR/FixPHP5PEARWarnings.php
new file mode 100644
index 00000000..be5dc3ce
--- /dev/null
+++ b/lib/php/PEAR/FixPHP5PEARWarnings.php
@@ -0,0 +1,7 @@
+<?php
+if ($skipmsg) {
+    $a = &new $ec($code, $mode, $options, $userinfo);
+} else {
+    $a = &new $ec($message, $code, $mode, $options, $userinfo);
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Frontend.php b/lib/php/PEAR/Frontend.php
new file mode 100644
index 00000000..d355a7f5
--- /dev/null
+++ b/lib/php/PEAR/Frontend.php
@@ -0,0 +1,228 @@
+<?php
+/**
+ * PEAR_Frontend, the singleton-based frontend for user input/output
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Frontend.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * Include error handling
+ */
+//require_once 'PEAR.php';
+
+/**
+ * Which user interface class is being used.
+ * @var string class name
+ */
+$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI';
+
+/**
+ * Instance of $_PEAR_Command_uiclass.
+ * @var object
+ */
+$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null;
+
+/**
+ * Singleton-based frontend for PEAR user input/output
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Frontend extends PEAR
+{
+    /**
+     * Retrieve the frontend object
+     * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk
+     * @static
+     */
+    function &singleton($type = null)
+    {
+        if ($type === null) {
+            if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) {
+                $a = false;
+                return $a;
+            }
+            return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
+        }
+
+        $a = PEAR_Frontend::setFrontendClass($type);
+        return $a;
+    }
+
+    /**
+     * Set the frontend class that will be used by calls to {@link singleton()}
+     *
+     * Frontends are expected to conform to the PEAR naming standard of
+     * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php)
+     * @param string $uiclass full class name
+     * @return PEAR_Frontend
+     * @static
+     */
+    function &setFrontendClass($uiclass)
+    {
+        if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
+              is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) {
+            return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
+        }
+
+        if (!class_exists($uiclass)) {
+            $file = str_replace('_', '/', $uiclass) . '.php';
+            if (PEAR_Frontend::isIncludeable($file)) {
+                include_once $file;
+            }
+        }
+
+        if (class_exists($uiclass)) {
+            $obj = &new $uiclass;
+            // quick test to see if this class implements a few of the most
+            // important frontend methods
+            if (is_a($obj, 'PEAR_Frontend')) {
+                $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj;
+                $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass;
+                return $obj;
+            }
+
+            $err = PEAR::raiseError("not a frontend class: $uiclass");
+            return $err;
+        }
+
+        $err = PEAR::raiseError("no such class: $uiclass");
+        return $err;
+    }
+
+    /**
+     * Set the frontend class that will be used by calls to {@link singleton()}
+     *
+     * Frontends are expected to be a descendant of PEAR_Frontend
+     * @param PEAR_Frontend
+     * @return PEAR_Frontend
+     * @static
+     */
+    function &setFrontendObject($uiobject)
+    {
+        if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
+              is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) {
+            return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
+        }
+
+        if (!is_a($uiobject, 'PEAR_Frontend')) {
+            $err = PEAR::raiseError('not a valid frontend class: (' .
+                get_class($uiobject) . ')');
+            return $err;
+        }
+
+        $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject;
+        $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject);
+        return $uiobject;
+    }
+
+    /**
+     * @param string $path relative or absolute include path
+     * @return boolean
+     * @static
+     */
+    function isIncludeable($path)
+    {
+        if (file_exists($path) && is_readable($path)) {
+            return true;
+        }
+
+        $fp = @fopen($path, 'r', true);
+        if ($fp) {
+            fclose($fp);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @param PEAR_Config
+     */
+    function setConfig(&$config)
+    {
+    }
+
+    /**
+     * This can be overridden to allow session-based temporary file management
+     *
+     * By default, all files are deleted at the end of a session.  The web installer
+     * needs to be able to sustain a list over many sessions in order to support
+     * user interaction with install scripts
+     */
+    function addTempFile($file)
+    {
+        $GLOBALS['_PEAR_Common_tempfiles'][] = $file;
+    }
+
+    /**
+     * Log an action
+     *
+     * @param string $msg the message to log
+     * @param boolean $append_crlf
+     * @return boolean true
+     * @abstract
+     */
+    function log($msg, $append_crlf = true)
+    {
+    }
+
+    /**
+     * Run a post-installation script
+     *
+     * @param array $scripts array of post-install scripts
+     * @abstract
+     */
+    function runPostinstallScripts(&$scripts)
+    {
+    }
+
+    /**
+     * Display human-friendly output formatted depending on the
+     * $command parameter.
+     *
+     * This should be able to handle basic output data with no command
+     * @param mixed  $data    data structure containing the information to display
+     * @param string $command command from which this method was called
+     * @abstract
+     */
+    function outputData($data, $command = '_default')
+    {
+    }
+
+    /**
+     * Display a modal form dialog and return the given input
+     *
+     * A frontend that requires multiple requests to retrieve and process
+     * data must take these needs into account, and implement the request
+     * handling code.
+     * @param string $command  command from which this method was called
+     * @param array  $prompts  associative array. keys are the input field names
+     *                         and values are the description
+     * @param array  $types    array of input field types (text, password,
+     *                         etc.) keys have to be the same like in $prompts
+     * @param array  $defaults array of default values. again keys have
+     *                         to be the same like in $prompts.  Do not depend
+     *                         on a default value being set.
+     * @return array input sent by the user
+     * @abstract
+     */
+    function userDialog($command, $prompts, $types = array(), $defaults = array())
+    {
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Frontend/CLI.php b/lib/php/PEAR/Frontend/CLI.php
new file mode 100644
index 00000000..374f0872
--- /dev/null
+++ b/lib/php/PEAR/Frontend/CLI.php
@@ -0,0 +1,732 @@
+<?php
+/**
+ * PEAR_Frontend_CLI
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: CLI.php 278236 2009-04-04 00:09:14Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+/**
+ * base class
+ */
+require_once 'PEAR/Frontend.php';
+
+/**
+ * Command-line Frontend for the PEAR Installer
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Frontend_CLI extends PEAR_Frontend
+{
+    /**
+     * What type of user interface this frontend is for.
+     * @var string
+     * @access public
+     */
+    var $type = 'CLI';
+    var $lp = ''; // line prefix
+
+    var $params = array();
+    var $term = array(
+        'bold'   => '',
+        'normal' => '',
+    );
+
+    function PEAR_Frontend_CLI()
+    {
+        parent::PEAR();
+        $term = getenv('TERM'); //(cox) $_ENV is empty for me in 4.1.1
+        if (function_exists('posix_isatty') && !posix_isatty(1)) {
+            // output is being redirected to a file or through a pipe
+        } elseif ($term) {
+            if (preg_match('/^(xterm|vt220|linux)/', $term)) {
+                $this->term['bold']   = sprintf("%c%c%c%c", 27, 91, 49, 109);
+                $this->term['normal'] = sprintf("%c%c%c", 27, 91, 109);
+            } elseif (preg_match('/^vt100/', $term)) {
+                $this->term['bold']   = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0);
+                $this->term['normal'] = sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0);
+            }
+        } elseif (OS_WINDOWS) {
+            // XXX add ANSI codes here
+        }
+    }
+
+    /**
+     * @param object PEAR_Error object
+     */
+    function displayError($e)
+    {
+        return $this->_displayLine($e->getMessage());
+    }
+
+    /**
+     * @param object PEAR_Error object
+     */
+    function displayFatalError($eobj)
+    {
+        $this->displayError($eobj);
+        if (class_exists('PEAR_Config')) {
+            $config = &PEAR_Config::singleton();
+            if ($config->get('verbose') > 5) {
+                if (function_exists('debug_print_backtrace')) {
+                    debug_print_backtrace();
+                    exit(1);
+                }
+
+                $raised = false;
+                foreach (debug_backtrace() as $i => $frame) {
+                    if (!$raised) {
+                        if (isset($frame['class'])
+                            && strtolower($frame['class']) == 'pear'
+                            && strtolower($frame['function']) == 'raiseerror'
+                        ) {
+                            $raised = true;
+                        } else {
+                            continue;
+                        }
+                    }
+
+                    $frame['class']    = !isset($frame['class'])    ? '' : $frame['class'];
+                    $frame['type']     = !isset($frame['type'])     ? '' : $frame['type'];
+                    $frame['function'] = !isset($frame['function']) ? '' : $frame['function'];
+                    $frame['line']     = !isset($frame['line'])     ? '' : $frame['line'];
+                    $this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]");
+                }
+            }
+        }
+
+        exit(1);
+    }
+
+    /**
+     * Instruct the runInstallScript method to skip a paramgroup that matches the
+     * id value passed in.
+     *
+     * This method is useful for dynamically configuring which sections of a post-install script
+     * will be run based on the user's setup, which is very useful for making flexible
+     * post-install scripts without losing the cross-Frontend ability to retrieve user input
+     * @param string
+     */
+    function skipParamgroup($id)
+    {
+        $this->_skipSections[$id] = true;
+    }
+
+    function runPostinstallScripts(&$scripts)
+    {
+        foreach ($scripts as $i => $script) {
+            $this->runInstallScript($scripts[$i]->_params, $scripts[$i]->_obj);
+        }
+    }
+
+    /**
+     * @param array $xml contents of postinstallscript tag
+     * @param object $script post-installation script
+     * @param string install|upgrade
+     */
+    function runInstallScript($xml, &$script)
+    {
+        $this->_skipSections = array();
+        if (!is_array($xml) || !isset($xml['paramgroup'])) {
+            $script->run(array(), '_default');
+            return;
+        }
+
+        $completedPhases = array();
+        if (!isset($xml['paramgroup'][0])) {
+            $xml['paramgroup'] = array($xml['paramgroup']);
+        }
+
+        foreach ($xml['paramgroup'] as $group) {
+            if (isset($this->_skipSections[$group['id']])) {
+                // the post-install script chose to skip this section dynamically
+                continue;
+            }
+
+            if (isset($group['name'])) {
+                $paramname = explode('::', $group['name']);
+                if ($lastgroup['id'] != $paramname[0]) {
+                    continue;
+                }
+
+                $group['name'] = $paramname[1];
+                if (!isset($answers)) {
+                    return;
+                }
+
+                if (isset($answers[$group['name']])) {
+                    switch ($group['conditiontype']) {
+                        case '=' :
+                            if ($answers[$group['name']] != $group['value']) {
+                                continue 2;
+                            }
+                        break;
+                        case '!=' :
+                            if ($answers[$group['name']] == $group['value']) {
+                                continue 2;
+                            }
+                        break;
+                        case 'preg_match' :
+                            if (!@preg_match('/' . $group['value'] . '/',
+                                  $answers[$group['name']])) {
+                                continue 2;
+                            }
+                        break;
+                        default :
+                        return;
+                    }
+                }
+            }
+
+            $lastgroup = $group;
+            if (isset($group['instructions'])) {
+                $this->_display($group['instructions']);
+            }
+
+            if (!isset($group['param'][0])) {
+                $group['param'] = array($group['param']);
+            }
+
+            if (isset($group['param'])) {
+                if (method_exists($script, 'postProcessPrompts')) {
+                    $prompts = $script->postProcessPrompts($group['param'], $group['id']);
+                    if (!is_array($prompts) || count($prompts) != count($group['param'])) {
+                        $this->outputData('postinstall', 'Error: post-install script did not ' .
+                            'return proper post-processed prompts');
+                        $prompts = $group['param'];
+                    } else {
+                        foreach ($prompts as $i => $var) {
+                            if (!is_array($var) || !isset($var['prompt']) ||
+                                  !isset($var['name']) ||
+                                  ($var['name'] != $group['param'][$i]['name']) ||
+                                  ($var['type'] != $group['param'][$i]['type'])
+                            ) {
+                                $this->outputData('postinstall', 'Error: post-install script ' .
+                                    'modified the variables or prompts, severe security risk. ' .
+                                    'Will instead use the defaults from the package.xml');
+                                $prompts = $group['param'];
+                            }
+                        }
+                    }
+
+                    $answers = $this->confirmDialog($prompts);
+                } else {
+                    $answers = $this->confirmDialog($group['param']);
+                }
+            }
+
+            if ((isset($answers) && $answers) || !isset($group['param'])) {
+                if (!isset($answers)) {
+                    $answers = array();
+                }
+
+                array_unshift($completedPhases, $group['id']);
+                if (!$script->run($answers, $group['id'])) {
+                    $script->run($completedPhases, '_undoOnError');
+                    return;
+                }
+            } else {
+                $script->run($completedPhases, '_undoOnError');
+                return;
+            }
+        }
+    }
+
+    /**
+     * Ask for user input, confirm the answers and continue until the user is satisfied
+     * @param array an array of arrays, format array('name' => 'paramname', 'prompt' =>
+     *              'text to display', 'type' => 'string'[, default => 'default value'])
+     * @return array
+     */
+    function confirmDialog($params)
+    {
+        $answers = $prompts = $types = array();
+        foreach ($params as $param) {
+            $prompts[$param['name']] = $param['prompt'];
+            $types[$param['name']]   = $param['type'];
+            $answers[$param['name']] = isset($param['default']) ? $param['default'] : '';
+        }
+
+        $tried = false;
+        do {
+            if ($tried) {
+                $i = 1;
+                foreach ($answers as $var => $value) {
+                    if (!strlen($value)) {
+                        echo $this->bold("* Enter an answer for #" . $i . ": ({$prompts[$var]})\n");
+                    }
+                    $i++;
+                }
+            }
+
+            $answers = $this->userDialog('', $prompts, $types, $answers);
+            $tried   = true;
+        } while (is_array($answers) && count(array_filter($answers)) != count($prompts));
+
+        return $answers;
+    }
+
+    function userDialog($command, $prompts, $types = array(), $defaults = array(), $screensize = 20)
+    {
+        if (!is_array($prompts)) {
+            return array();
+        }
+
+        $testprompts = array_keys($prompts);
+        $result      = $defaults;
+
+        reset($prompts);
+        if (count($prompts) === 1) {
+            foreach ($prompts as $key => $prompt) {
+                $type    = $types[$key];
+                $default = @$defaults[$key];
+                print "$prompt ";
+                if ($default) {
+                    print "[$default] ";
+                }
+                print ": ";
+
+                $line         = fgets(STDIN, 2048);
+                $result[$key] =  ($default && trim($line) == '') ? $default : trim($line);
+            }
+
+            return $result;
+        }
+
+        $first_run = true;
+        while (true) {
+            $descLength = max(array_map('strlen', $prompts));
+            $descFormat = "%-{$descLength}s";
+            $last       = count($prompts);
+
+            $i = 0;
+            foreach ($prompts as $n => $var) {
+                $res = isset($result[$n]) ? $result[$n] : null;
+                printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], $res);
+            }
+            print "\n1-$last, 'all', 'abort', or Enter to continue: ";
+
+            $tmp = trim(fgets(STDIN, 1024));
+            if (empty($tmp)) {
+                break;
+            }
+
+            if ($tmp == 'abort') {
+                return false;
+            }
+
+            if (isset($testprompts[(int)$tmp - 1])) {
+                $var     = $testprompts[(int)$tmp - 1];
+                $desc    = $prompts[$var];
+                $current = @$result[$var];
+                print "$desc [$current] : ";
+                $tmp = trim(fgets(STDIN, 1024));
+                if ($tmp !== '') {
+                    $result[$var] = $tmp;
+                }
+            } elseif ($tmp == 'all') {
+                foreach ($prompts as $var => $desc) {
+                    $current = $result[$var];
+                    print "$desc [$current] : ";
+                    $tmp = trim(fgets(STDIN, 1024));
+                    if (trim($tmp) !== '') {
+                        $result[$var] = trim($tmp);
+                    }
+                }
+            }
+
+            $first_run = false;
+        }
+
+        return $result;
+    }
+
+    function userConfirm($prompt, $default = 'yes')
+    {
+        trigger_error("PEAR_Frontend_CLI::userConfirm not yet converted", E_USER_ERROR);
+        static $positives = array('y', 'yes', 'on', '1');
+        static $negatives = array('n', 'no', 'off', '0');
+        print "$this->lp$prompt [$default] : ";
+        $fp = fopen("php://stdin", "r");
+        $line = fgets($fp, 2048);
+        fclose($fp);
+        $answer = strtolower(trim($line));
+        if (empty($answer)) {
+            $answer = $default;
+        }
+        if (in_array($answer, $positives)) {
+            return true;
+        }
+        if (in_array($answer, $negatives)) {
+            return false;
+        }
+        if (in_array($default, $positives)) {
+            return true;
+        }
+        return false;
+    }
+
+    function outputData($data, $command = '_default')
+    {
+        switch ($command) {
+            case 'channel-info':
+                foreach ($data as $type => $section) {
+                    if ($type == 'main') {
+                        $section['data'] = array_values($section['data']);
+                    }
+
+                    $this->outputData($section);
+                }
+                break;
+            case 'install':
+            case 'upgrade':
+            case 'upgrade-all':
+                if (isset($data['release_warnings'])) {
+                    $this->_displayLine('');
+                    $this->_startTable(array(
+                        'border' => false,
+                        'caption' => 'Release Warnings'
+                    ));
+                    $this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55)));
+                    $this->_endTable();
+                    $this->_displayLine('');
+                }
+
+                $this->_displayLine($data['data']);
+                break;
+            case 'search':
+                $this->_startTable($data);
+                if (isset($data['headline']) && is_array($data['headline'])) {
+                    $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
+                }
+
+                foreach($data['data'] as $category) {
+                    foreach($category as $pkg) {
+                        $this->_tableRow($pkg, null, array(1 => array('wrap' => 55)));
+                    }
+                }
+
+                $this->_endTable();
+                break;
+            case 'list-all':
+                if (!isset($data['data'])) {
+                      $this->_displayLine('No packages in channel');
+                      break;
+                }
+
+                $this->_startTable($data);
+                if (isset($data['headline']) && is_array($data['headline'])) {
+                    $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
+                }
+
+                foreach($data['data'] as $category) {
+                    foreach($category as $pkg) {
+                        unset($pkg[4], $pkg[5]);
+                        $this->_tableRow($pkg, null, array(1 => array('wrap' => 55)));
+                    }
+                }
+
+                $this->_endTable();
+                break;
+            case 'config-show':
+                $data['border'] = false;
+                $opts = array(
+                    0 => array('wrap' => 30),
+                    1 => array('wrap' => 20),
+                    2 => array('wrap' => 35)
+                );
+
+                $this->_startTable($data);
+                if (isset($data['headline']) && is_array($data['headline'])) {
+                    $this->_tableRow($data['headline'], array('bold' => true), $opts);
+                }
+
+                foreach ($data['data'] as $group) {
+                    foreach ($group as $value) {
+                        if ($value[2] == '') {
+                            $value[2] = "<not set>";
+                        }
+
+                        $this->_tableRow($value, null, $opts);
+                    }
+                }
+
+                $this->_endTable();
+                break;
+            case 'remote-info':
+                $d = $data;
+                $data = array(
+                    'caption' => 'Package details:',
+                    'border'  => false,
+                    'data'    => array(
+                        array("Latest",      $data['stable']),
+                        array("Installed",   $data['installed']),
+                        array("Package",     $data['name']),
+                        array("License",     $data['license']),
+                        array("Category",    $data['category']),
+                        array("Summary",     $data['summary']),
+                        array("Description", $data['description']),
+                    ),
+                );
+
+                if (isset($d['deprecated']) && $d['deprecated']) {
+                    $conf = &PEAR_Config::singleton();
+                    $reg = $conf->getRegistry();
+                    $name = $reg->parsedPackageNameToString($d['deprecated'], true);
+                    $data['data'][] = array('Deprecated! use', $name);
+                }
+            default: {
+                if (is_array($data)) {
+                    $this->_startTable($data);
+                    $count = count($data['data'][0]);
+                    if ($count == 2) {
+                        $opts = array(0 => array('wrap' => 25),
+                                      1 => array('wrap' => 48)
+                        );
+                    } elseif ($count == 3) {
+                        $opts = array(0 => array('wrap' => 30),
+                                      1 => array('wrap' => 20),
+                                      2 => array('wrap' => 35)
+                        );
+                    } else {
+                        $opts = null;
+                    }
+                    if (isset($data['headline']) && is_array($data['headline'])) {
+                        $this->_tableRow($data['headline'],
+                                         array('bold' => true),
+                                         $opts);
+                    }
+
+                    foreach($data['data'] as $row) {
+                        $this->_tableRow($row, null, $opts);
+                    }
+                    $this->_endTable();
+                } else {
+                    $this->_displayLine($data);
+                }
+            }
+        }
+    }
+
+    function log($text, $append_crlf = true)
+    {
+        if ($append_crlf) {
+            return $this->_displayLine($text);
+        }
+
+        return $this->_display($text);
+    }
+
+    function bold($text)
+    {
+        if (empty($this->term['bold'])) {
+            return strtoupper($text);
+        }
+
+        return $this->term['bold'] . $text . $this->term['normal'];
+    }
+
+    function _displayHeading($title)
+    {
+        print $this->lp.$this->bold($title)."\n";
+        print $this->lp.str_repeat("=", strlen($title))."\n";
+    }
+
+    function _startTable($params = array())
+    {
+        $params['table_data'] = array();
+        $params['widest']     = array();  // indexed by column
+        $params['highest']    = array(); // indexed by row
+        $params['ncols']      = 0;
+        $this->params         = $params;
+    }
+
+    function _tableRow($columns, $rowparams = array(), $colparams = array())
+    {
+        $highest = 1;
+        for ($i = 0; $i < count($columns); $i++) {
+            $col = &$columns[$i];
+            if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) {
+                $col = wordwrap($col, $colparams[$i]['wrap']);
+            }
+
+            if (strpos($col, "\n") !== false) {
+                $multiline = explode("\n", $col);
+                $w = 0;
+                foreach ($multiline as $n => $line) {
+                    $len = strlen($line);
+                    if ($len > $w) {
+                        $w = $len;
+                    }
+                }
+                $lines = count($multiline);
+            } else {
+                $w = strlen($col);
+            }
+
+            if (isset($this->params['widest'][$i])) {
+                if ($w > $this->params['widest'][$i]) {
+                    $this->params['widest'][$i] = $w;
+                }
+            } else {
+                $this->params['widest'][$i] = $w;
+            }
+
+            $tmp = count_chars($columns[$i], 1);
+            // handle unix, mac and windows formats
+            $lines = (isset($tmp[10]) ? $tmp[10] : (isset($tmp[13]) ? $tmp[13] : 0)) + 1;
+            if ($lines > $highest) {
+                $highest = $lines;
+            }
+        }
+
+        if (count($columns) > $this->params['ncols']) {
+            $this->params['ncols'] = count($columns);
+        }
+
+        $new_row = array(
+            'data'      => $columns,
+            'height'    => $highest,
+            'rowparams' => $rowparams,
+            'colparams' => $colparams,
+        );
+        $this->params['table_data'][] = $new_row;
+    }
+
+    function _endTable()
+    {
+        extract($this->params);
+        if (!empty($caption)) {
+            $this->_displayHeading($caption);
+        }
+
+        if (count($table_data) === 0) {
+            return;
+        }
+
+        if (!isset($width)) {
+            $width = $widest;
+        } else {
+            for ($i = 0; $i < $ncols; $i++) {
+                if (!isset($width[$i])) {
+                    $width[$i] = $widest[$i];
+                }
+            }
+        }
+
+        $border = false;
+        if (empty($border)) {
+            $cellstart  = '';
+            $cellend    = ' ';
+            $rowend     = '';
+            $padrowend  = false;
+            $borderline = '';
+        } else {
+            $cellstart  = '| ';
+            $cellend    = ' ';
+            $rowend     = '|';
+            $padrowend  = true;
+            $borderline = '+';
+            foreach ($width as $w) {
+                $borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1);
+                $borderline .= '+';
+            }
+        }
+
+        if ($borderline) {
+            $this->_displayLine($borderline);
+        }
+
+        for ($i = 0; $i < count($table_data); $i++) {
+            extract($table_data[$i]);
+            if (!is_array($rowparams)) {
+                $rowparams = array();
+            }
+
+            if (!is_array($colparams)) {
+                $colparams = array();
+            }
+
+            $rowlines = array();
+            if ($height > 1) {
+                for ($c = 0; $c < count($data); $c++) {
+                    $rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]);
+                    if (count($rowlines[$c]) < $height) {
+                        $rowlines[$c] = array_pad($rowlines[$c], $height, '');
+                    }
+                }
+            } else {
+                for ($c = 0; $c < count($data); $c++) {
+                    $rowlines[$c] = array($data[$c]);
+                }
+            }
+
+            for ($r = 0; $r < $height; $r++) {
+                $rowtext = '';
+                for ($c = 0; $c < count($data); $c++) {
+                    if (isset($colparams[$c])) {
+                        $attribs = array_merge($rowparams, $colparams);
+                    } else {
+                        $attribs = $rowparams;
+                    }
+
+                    $w = isset($width[$c]) ? $width[$c] : 0;
+                    //$cell = $data[$c];
+                    $cell = $rowlines[$c][$r];
+                    $l = strlen($cell);
+                    if ($l > $w) {
+                        $cell = substr($cell, 0, $w);
+                    }
+
+                    if (isset($attribs['bold'])) {
+                        $cell = $this->bold($cell);
+                    }
+
+                    if ($l < $w) {
+                        // not using str_pad here because we may
+                        // add bold escape characters to $cell
+                        $cell .= str_repeat(' ', $w - $l);
+                    }
+
+                    $rowtext .= $cellstart . $cell . $cellend;
+                }
+
+                if (!$border) {
+                    $rowtext = rtrim($rowtext);
+                }
+
+                $rowtext .= $rowend;
+                $this->_displayLine($rowtext);
+            }
+        }
+
+        if ($borderline) {
+            $this->_displayLine($borderline);
+        }
+    }
+
+    function _displayLine($text)
+    {
+        print "$this->lp$text\n";
+    }
+
+    function _display($text)
+    {
+        print $text;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer.php b/lib/php/PEAR/Installer.php
new file mode 100644
index 00000000..cdd4be88
--- /dev/null
+++ b/lib/php/PEAR/Installer.php
@@ -0,0 +1,1823 @@
+<?php
+/**
+ * PEAR_Installer
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V.V. Cox <cox@idecnet.com>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Installer.php 287446 2009-08-18 11:45:05Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * Used for installation groups in package.xml 2.0 and platform exceptions
+ */
+require_once 'OS/Guess.php';
+require_once 'PEAR/Downloader.php';
+
+define('PEAR_INSTALLER_NOBINARY', -240);
+/**
+ * Administration class used to install PEAR packages and maintain the
+ * installed package database.
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V.V. Cox <cox@idecnet.com>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Installer extends PEAR_Downloader
+{
+    // {{{ properties
+
+    /** name of the package directory, for example Foo-1.0
+     * @var string
+     */
+    var $pkgdir;
+
+    /** directory where PHP code files go
+     * @var string
+     */
+    var $phpdir;
+
+    /** directory where PHP extension files go
+     * @var string
+     */
+    var $extdir;
+
+    /** directory where documentation goes
+     * @var string
+     */
+    var $docdir;
+
+    /** installation root directory (ala PHP's INSTALL_ROOT or
+     * automake's DESTDIR
+     * @var string
+     */
+    var $installroot = '';
+
+    /** debug level
+     * @var int
+     */
+    var $debug = 1;
+
+    /** temporary directory
+     * @var string
+     */
+    var $tmpdir;
+
+    /**
+     * PEAR_Registry object used by the installer
+     * @var PEAR_Registry
+     */
+    var $registry;
+
+    /**
+     * array of PEAR_Downloader_Packages
+     * @var array
+     */
+    var $_downloadedPackages;
+
+    /** List of file transactions queued for an install/upgrade/uninstall.
+     *
+     *  Format:
+     *    array(
+     *      0 => array("rename => array("from-file", "to-file")),
+     *      1 => array("delete" => array("file-to-delete")),
+     *      ...
+     *    )
+     *
+     * @var array
+     */
+    var $file_operations = array();
+
+    // }}}
+
+    // {{{ constructor
+
+    /**
+     * PEAR_Installer constructor.
+     *
+     * @param object $ui user interface object (instance of PEAR_Frontend_*)
+     *
+     * @access public
+     */
+    function PEAR_Installer(&$ui)
+    {
+        parent::PEAR_Common();
+        $this->setFrontendObject($ui);
+        $this->debug = $this->config->get('verbose');
+    }
+
+    function setOptions($options)
+    {
+        $this->_options = $options;
+    }
+
+    function setConfig(&$config)
+    {
+        $this->config    = &$config;
+        $this->_registry = &$config->getRegistry();
+    }
+
+    // }}}
+
+    function _removeBackups($files)
+    {
+        foreach ($files as $path) {
+            $this->addFileOperation('removebackup', array($path));
+        }
+    }
+
+    // {{{ _deletePackageFiles()
+
+    /**
+     * Delete a package's installed files, does not remove empty directories.
+     *
+     * @param string package name
+     * @param string channel name
+     * @param bool if true, then files are backed up first
+     * @return bool TRUE on success, or a PEAR error on failure
+     * @access protected
+     */
+    function _deletePackageFiles($package, $channel = false, $backup = false)
+    {
+        if (!$channel) {
+            $channel = 'pear.php.net';
+        }
+
+        if (!strlen($package)) {
+            return $this->raiseError("No package to uninstall given");
+        }
+
+        if (strtolower($package) == 'pear' && $channel == 'pear.php.net') {
+            // to avoid race conditions, include all possible needed files
+            require_once 'PEAR/Task/Common.php';
+            require_once 'PEAR/Task/Replace.php';
+            require_once 'PEAR/Task/Unixeol.php';
+            require_once 'PEAR/Task/Windowseol.php';
+            require_once 'PEAR/PackageFile/v1.php';
+            require_once 'PEAR/PackageFile/v2.php';
+            require_once 'PEAR/PackageFile/Generator/v1.php';
+            require_once 'PEAR/PackageFile/Generator/v2.php';
+        }
+
+        $filelist = $this->_registry->packageInfo($package, 'filelist', $channel);
+        if ($filelist == null) {
+            return $this->raiseError("$channel/$package not installed");
+        }
+
+        $ret = array();
+        foreach ($filelist as $file => $props) {
+            if (empty($props['installed_as'])) {
+                continue;
+            }
+
+            $path = $props['installed_as'];
+            if ($backup) {
+                $this->addFileOperation('backup', array($path));
+                $ret[] = $path;
+            }
+
+            $this->addFileOperation('delete', array($path));
+        }
+
+        if ($backup) {
+            return $ret;
+        }
+
+        return true;
+    }
+
+    // }}}
+    // {{{ _installFile()
+
+    /**
+     * @param string filename
+     * @param array attributes from <file> tag in package.xml
+     * @param string path to install the file in
+     * @param array options from command-line
+     * @access private
+     */
+    function _installFile($file, $atts, $tmp_path, $options)
+    {
+        // {{{ return if this file is meant for another platform
+        static $os;
+        if (!isset($this->_registry)) {
+            $this->_registry = &$this->config->getRegistry();
+        }
+
+        if (isset($atts['platform'])) {
+            if (empty($os)) {
+                $os = new OS_Guess();
+            }
+
+            if (strlen($atts['platform']) && $atts['platform']{0} == '!') {
+                $negate   = true;
+                $platform = substr($atts['platform'], 1);
+            } else {
+                $negate    = false;
+                $platform = $atts['platform'];
+            }
+
+            if ((bool) $os->matchSignature($platform) === $negate) {
+                $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")");
+                return PEAR_INSTALLER_SKIPPED;
+            }
+        }
+        // }}}
+
+        $channel = $this->pkginfo->getChannel();
+        // {{{ assemble the destination paths
+        switch ($atts['role']) {
+            case 'src':
+            case 'extsrc':
+                $this->source_files++;
+                return;
+            case 'doc':
+            case 'data':
+            case 'test':
+                $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel) .
+                            DIRECTORY_SEPARATOR . $this->pkginfo->getPackage();
+                unset($atts['baseinstalldir']);
+                break;
+            case 'ext':
+            case 'php':
+                $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel);
+                break;
+            case 'script':
+                $dest_dir = $this->config->get('bin_dir', null, $channel);
+                break;
+            default:
+                return $this->raiseError("Invalid role `$atts[role]' for file $file");
+        }
+
+        $save_destdir = $dest_dir;
+        if (!empty($atts['baseinstalldir'])) {
+            $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
+        }
+
+        if (dirname($file) != '.' && empty($atts['install-as'])) {
+            $dest_dir .= DIRECTORY_SEPARATOR . dirname($file);
+        }
+
+        if (empty($atts['install-as'])) {
+            $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file);
+        } else {
+            $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as'];
+        }
+        $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file;
+
+        // Clean up the DIRECTORY_SEPARATOR mess
+        $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
+        list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
+                                                    array(DIRECTORY_SEPARATOR,
+                                                          DIRECTORY_SEPARATOR,
+                                                          DIRECTORY_SEPARATOR),
+                                                    array($dest_file, $orig_file));
+        $final_dest_file = $installed_as = $dest_file;
+        if (isset($this->_options['packagingroot'])) {
+            $installedas_dest_dir  = dirname($final_dest_file);
+            $installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
+            $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']);
+        } else {
+            $installedas_dest_dir  = dirname($final_dest_file);
+            $installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
+        }
+
+        $dest_dir  = dirname($final_dest_file);
+        $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
+        if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) {
+            return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED);
+        }
+        // }}}
+
+        if (empty($this->_options['register-only']) &&
+              (!file_exists($dest_dir) || !is_dir($dest_dir))) {
+            if (!$this->mkDirHier($dest_dir)) {
+                return $this->raiseError("failed to mkdir $dest_dir",
+                                         PEAR_INSTALLER_FAILED);
+            }
+            $this->log(3, "+ mkdir $dest_dir");
+        }
+
+        // pretty much nothing happens if we are only registering the install
+        if (empty($this->_options['register-only'])) {
+            if (empty($atts['replacements'])) {
+                if (!file_exists($orig_file)) {
+                    return $this->raiseError("file $orig_file does not exist",
+                                             PEAR_INSTALLER_FAILED);
+                }
+
+                if (!@copy($orig_file, $dest_file)) {
+                    return $this->raiseError("failed to write $dest_file: $php_errormsg",
+                                             PEAR_INSTALLER_FAILED);
+                }
+
+                $this->log(3, "+ cp $orig_file $dest_file");
+                if (isset($atts['md5sum'])) {
+                    $md5sum = md5_file($dest_file);
+                }
+            } else {
+                // {{{ file with replacements
+                if (!file_exists($orig_file)) {
+                    return $this->raiseError("file does not exist",
+                                             PEAR_INSTALLER_FAILED);
+                }
+
+                $contents = file_get_contents($orig_file);
+                if ($contents === false) {
+                    $contents = '';
+                }
+
+                if (isset($atts['md5sum'])) {
+                    $md5sum = md5($contents);
+                }
+
+                $subst_from = $subst_to = array();
+                foreach ($atts['replacements'] as $a) {
+                    $to = '';
+                    if ($a['type'] == 'php-const') {
+                        if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) {
+                            eval("\$to = $a[to];");
+                        } else {
+                            if (!isset($options['soft'])) {
+                                $this->log(0, "invalid php-const replacement: $a[to]");
+                            }
+                            continue;
+                        }
+                    } elseif ($a['type'] == 'pear-config') {
+                        if ($a['to'] == 'master_server') {
+                            $chan = $this->_registry->getChannel($channel);
+                            if (!PEAR::isError($chan)) {
+                                $to = $chan->getServer();
+                            } else {
+                                $to = $this->config->get($a['to'], null, $channel);
+                            }
+                        } else {
+                            $to = $this->config->get($a['to'], null, $channel);
+                        }
+                        if (is_null($to)) {
+                            if (!isset($options['soft'])) {
+                                $this->log(0, "invalid pear-config replacement: $a[to]");
+                            }
+                            continue;
+                        }
+                    } elseif ($a['type'] == 'package-info') {
+                        if ($t = $this->pkginfo->packageInfo($a['to'])) {
+                            $to = $t;
+                        } else {
+                            if (!isset($options['soft'])) {
+                                $this->log(0, "invalid package-info replacement: $a[to]");
+                            }
+                            continue;
+                        }
+                    }
+                    if (!is_null($to)) {
+                        $subst_from[] = $a['from'];
+                        $subst_to[] = $to;
+                    }
+                }
+
+                $this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file");
+                if (sizeof($subst_from)) {
+                    $contents = str_replace($subst_from, $subst_to, $contents);
+                }
+
+                $wp = @fopen($dest_file, "wb");
+                if (!is_resource($wp)) {
+                    return $this->raiseError("failed to create $dest_file: $php_errormsg",
+                                             PEAR_INSTALLER_FAILED);
+                }
+
+                if (@fwrite($wp, $contents) === false) {
+                    return $this->raiseError("failed writing to $dest_file: $php_errormsg",
+                                             PEAR_INSTALLER_FAILED);
+                }
+
+                fclose($wp);
+                // }}}
+            }
+
+            // {{{ check the md5
+            if (isset($md5sum)) {
+                if (strtolower($md5sum) === strtolower($atts['md5sum'])) {
+                    $this->log(2, "md5sum ok: $final_dest_file");
+                } else {
+                    if (empty($options['force'])) {
+                        // delete the file
+                        if (file_exists($dest_file)) {
+                            unlink($dest_file);
+                        }
+
+                        if (!isset($options['ignore-errors'])) {
+                            return $this->raiseError("bad md5sum for file $final_dest_file",
+                                                 PEAR_INSTALLER_FAILED);
+                        }
+
+                        if (!isset($options['soft'])) {
+                            $this->log(0, "warning : bad md5sum for file $final_dest_file");
+                        }
+                    } else {
+                        if (!isset($options['soft'])) {
+                            $this->log(0, "warning : bad md5sum for file $final_dest_file");
+                        }
+                    }
+                }
+            }
+            // }}}
+            // {{{ set file permissions
+            if (!OS_WINDOWS) {
+                if ($atts['role'] == 'script') {
+                    $mode = 0777 & ~(int)octdec($this->config->get('umask'));
+                    $this->log(3, "+ chmod +x $dest_file");
+                } else {
+                    $mode = 0666 & ~(int)octdec($this->config->get('umask'));
+                }
+
+                if ($atts['role'] != 'src') {
+                    $this->addFileOperation("chmod", array($mode, $dest_file));
+                    if (!@chmod($dest_file, $mode)) {
+                        if (!isset($options['soft'])) {
+                            $this->log(0, "failed to change mode of $dest_file: $php_errormsg");
+                        }
+                    }
+                }
+            }
+            // }}}
+
+            if ($atts['role'] == 'src') {
+                rename($dest_file, $final_dest_file);
+                $this->log(2, "renamed source file $dest_file to $final_dest_file");
+            } else {
+                $this->addFileOperation("rename", array($dest_file, $final_dest_file,
+                    $atts['role'] == 'ext'));
+            }
+        }
+
+        // Store the full path where the file was installed for easy unistall
+        if ($atts['role'] != 'script') {
+            $loc = $this->config->get($atts['role'] . '_dir');
+        } else {
+            $loc = $this->config->get('bin_dir');
+        }
+
+        if ($atts['role'] != 'src') {
+            $this->addFileOperation("installed_as", array($file, $installed_as,
+                                    $loc,
+                                    dirname(substr($installedas_dest_file, strlen($loc)))));
+        }
+
+        //$this->log(2, "installed: $dest_file");
+        return PEAR_INSTALLER_OK;
+    }
+
+    // }}}
+    // {{{ _installFile2()
+
+    /**
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @param string filename
+     * @param array attributes from <file> tag in package.xml
+     * @param string path to install the file in
+     * @param array options from command-line
+     * @access private
+     */
+    function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options)
+    {
+        $atts = $real_atts;
+        if (!isset($this->_registry)) {
+            $this->_registry = &$this->config->getRegistry();
+        }
+
+        $channel = $pkg->getChannel();
+        // {{{ assemble the destination paths
+        if (!in_array($atts['attribs']['role'],
+              PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) {
+            return $this->raiseError('Invalid role `' . $atts['attribs']['role'] .
+                    "' for file $file");
+        }
+
+        $role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config);
+        $err  = $role->setup($this, $pkg, $atts['attribs'], $file);
+        if (PEAR::isError($err)) {
+            return $err;
+        }
+
+        if (!$role->isInstallable()) {
+            return;
+        }
+
+        $info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path);
+        if (PEAR::isError($info)) {
+            return $info;
+        }
+
+        list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info;
+        if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) {
+            return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED);
+        }
+
+        $final_dest_file = $installed_as = $dest_file;
+        if (isset($this->_options['packagingroot'])) {
+            $final_dest_file = $this->_prependPath($final_dest_file,
+                $this->_options['packagingroot']);
+        }
+
+        $dest_dir  = dirname($final_dest_file);
+        $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
+        // }}}
+
+        if (empty($this->_options['register-only'])) {
+            if (!file_exists($dest_dir) || !is_dir($dest_dir)) {
+                if (!$this->mkDirHier($dest_dir)) {
+                    return $this->raiseError("failed to mkdir $dest_dir",
+                                             PEAR_INSTALLER_FAILED);
+                }
+                $this->log(3, "+ mkdir $dest_dir");
+            }
+        }
+
+        $attribs = $atts['attribs'];
+        unset($atts['attribs']);
+        // pretty much nothing happens if we are only registering the install
+        if (empty($this->_options['register-only'])) {
+            if (!count($atts)) { // no tasks
+                if (!file_exists($orig_file)) {
+                    return $this->raiseError("file $orig_file does not exist",
+                                             PEAR_INSTALLER_FAILED);
+                }
+
+                if (!@copy($orig_file, $dest_file)) {
+                    return $this->raiseError("failed to write $dest_file: $php_errormsg",
+                                             PEAR_INSTALLER_FAILED);
+                }
+
+                $this->log(3, "+ cp $orig_file $dest_file");
+                if (isset($attribs['md5sum'])) {
+                    $md5sum = md5_file($dest_file);
+                }
+            } else { // file with tasks
+                if (!file_exists($orig_file)) {
+                    return $this->raiseError("file $orig_file does not exist",
+                                             PEAR_INSTALLER_FAILED);
+                }
+
+                $contents = file_get_contents($orig_file);
+                if ($contents === false) {
+                    $contents = '';
+                }
+
+                if (isset($attribs['md5sum'])) {
+                    $md5sum = md5($contents);
+                }
+
+                foreach ($atts as $tag => $raw) {
+                    $tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag);
+                    $task = "PEAR_Task_$tag";
+                    $task = &new $task($this->config, $this, PEAR_TASK_INSTALL);
+                    if (!$task->isScript()) { // scripts are only handled after installation
+                        $task->init($raw, $attribs, $pkg->getLastInstalledVersion());
+                        $res = $task->startSession($pkg, $contents, $final_dest_file);
+                        if ($res === false) {
+                            continue; // skip this file
+                        }
+
+                        if (PEAR::isError($res)) {
+                            return $res;
+                        }
+
+                        $contents = $res; // save changes
+                    }
+
+                    $wp = @fopen($dest_file, "wb");
+                    if (!is_resource($wp)) {
+                        return $this->raiseError("failed to create $dest_file: $php_errormsg",
+                                                 PEAR_INSTALLER_FAILED);
+                    }
+
+                    if (fwrite($wp, $contents) === false) {
+                        return $this->raiseError("failed writing to $dest_file: $php_errormsg",
+                                                 PEAR_INSTALLER_FAILED);
+                    }
+
+                    fclose($wp);
+                }
+            }
+
+            // {{{ check the md5
+            if (isset($md5sum)) {
+                // Make sure the original md5 sum matches with expected
+                if (strtolower($md5sum) === strtolower($attribs['md5sum'])) {
+                    $this->log(2, "md5sum ok: $final_dest_file");
+
+                    if (isset($contents)) {
+                        // set md5 sum based on $content in case any tasks were run.
+                        $real_atts['attribs']['md5sum'] = md5($contents);
+                    }
+                } else {
+                    if (empty($options['force'])) {
+                        // delete the file
+                        if (file_exists($dest_file)) {
+                            unlink($dest_file);
+                        }
+
+                        if (!isset($options['ignore-errors'])) {
+                            return $this->raiseError("bad md5sum for file $final_dest_file",
+                                                     PEAR_INSTALLER_FAILED);
+                        }
+
+                        if (!isset($options['soft'])) {
+                            $this->log(0, "warning : bad md5sum for file $final_dest_file");
+                        }
+                    } else {
+                        if (!isset($options['soft'])) {
+                            $this->log(0, "warning : bad md5sum for file $final_dest_file");
+                        }
+                    }
+                }
+            } else {
+                $real_atts['attribs']['md5sum'] = md5_file($dest_file);
+            }
+
+            // }}}
+            // {{{ set file permissions
+            if (!OS_WINDOWS) {
+                if ($role->isExecutable()) {
+                    $mode = 0777 & ~(int)octdec($this->config->get('umask'));
+                    $this->log(3, "+ chmod +x $dest_file");
+                } else {
+                    $mode = 0666 & ~(int)octdec($this->config->get('umask'));
+                }
+
+                if ($attribs['role'] != 'src') {
+                    $this->addFileOperation("chmod", array($mode, $dest_file));
+                    if (!@chmod($dest_file, $mode)) {
+                        if (!isset($options['soft'])) {
+                            $this->log(0, "failed to change mode of $dest_file: $php_errormsg");
+                        }
+                    }
+                }
+            }
+            // }}}
+
+            if ($attribs['role'] == 'src') {
+                rename($dest_file, $final_dest_file);
+                $this->log(2, "renamed source file $dest_file to $final_dest_file");
+            } else {
+                $this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension()));
+            }
+        }
+
+        // Store the full path where the file was installed for easy uninstall
+        if ($attribs['role'] != 'src') {
+            $loc = $this->config->get($role->getLocationConfig(), null, $channel);
+            $this->addFileOperation('installed_as', array($file, $installed_as,
+                                $loc,
+                                dirname(substr($installed_as, strlen($loc)))));
+        }
+
+        //$this->log(2, "installed: $dest_file");
+        return PEAR_INSTALLER_OK;
+    }
+
+    // }}}
+    // {{{ addFileOperation()
+
+    /**
+     * Add a file operation to the current file transaction.
+     *
+     * @see startFileTransaction()
+     * @param string $type This can be one of:
+     *    - rename:  rename a file ($data has 3 values)
+     *    - backup:  backup an existing file ($data has 1 value)
+     *    - removebackup:  clean up backups created during install ($data has 1 value)
+     *    - chmod:   change permissions on a file ($data has 2 values)
+     *    - delete:  delete a file ($data has 1 value)
+     *    - rmdir:   delete a directory if empty ($data has 1 value)
+     *    - installed_as: mark a file as installed ($data has 4 values).
+     * @param array $data For all file operations, this array must contain the
+     *    full path to the file or directory that is being operated on.  For
+     *    the rename command, the first parameter must be the file to rename,
+     *    the second its new name, the third whether this is a PHP extension.
+     *
+     *    The installed_as operation contains 4 elements in this order:
+     *    1. Filename as listed in the filelist element from package.xml
+     *    2. Full path to the installed file
+     *    3. Full path from the php_dir configuration variable used in this
+     *       installation
+     *    4. Relative path from the php_dir that this file is installed in
+     */
+    function addFileOperation($type, $data)
+    {
+        if (!is_array($data)) {
+            return $this->raiseError('Internal Error: $data in addFileOperation'
+                . ' must be an array, was ' . gettype($data));
+        }
+
+        if ($type == 'chmod') {
+            $octmode = decoct($data[0]);
+            $this->log(3, "adding to transaction: $type $octmode $data[1]");
+        } else {
+            $this->log(3, "adding to transaction: $type " . implode(" ", $data));
+        }
+        $this->file_operations[] = array($type, $data);
+    }
+
+    // }}}
+    // {{{ startFileTransaction()
+
+    function startFileTransaction($rollback_in_case = false)
+    {
+        if (count($this->file_operations) && $rollback_in_case) {
+            $this->rollbackFileTransaction();
+        }
+        $this->file_operations = array();
+    }
+
+    // }}}
+    // {{{ commitFileTransaction()
+
+    function commitFileTransaction()
+    {
+        $n = count($this->file_operations);
+        $this->log(2, "about to commit $n file operations");
+        // {{{ first, check permissions and such manually
+        $errors = array();
+        foreach ($this->file_operations as $tr) {
+            list($type, $data) = $tr;
+            switch ($type) {
+                case 'rename':
+                    if (!file_exists($data[0])) {
+                        $errors[] = "cannot rename file $data[0], doesn't exist";
+                    }
+
+                    // check that dest dir. is writable
+                    if (!is_writable(dirname($data[1]))) {
+                        $errors[] = "permission denied ($type): $data[1]";
+                    }
+                    break;
+                case 'chmod':
+                    // check that file is writable
+                    if (!is_writable($data[1])) {
+                        $errors[] = "permission denied ($type): $data[1] " . decoct($data[0]);
+                    }
+                    break;
+                case 'delete':
+                    if (!file_exists($data[0])) {
+                        $this->log(2, "warning: file $data[0] doesn't exist, can't be deleted");
+                    }
+                    // check that directory is writable
+                    if (file_exists($data[0])) {
+                        if (!is_writable(dirname($data[0]))) {
+                            $errors[] = "permission denied ($type): $data[0]";
+                        } else {
+                            // make sure the file to be deleted can be opened for writing
+                            $fp = false;
+                            if (!is_dir($data[0]) &&
+                                  (!is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) {
+                                $errors[] = "permission denied ($type): $data[0]";
+                            } elseif ($fp) {
+                                fclose($fp);
+                            }
+                        }
+                    }
+                    break;
+            }
+
+        }
+        // }}}
+        $m = count($errors);
+        if ($m > 0) {
+            foreach ($errors as $error) {
+                if (!isset($this->_options['soft'])) {
+                    $this->log(1, $error);
+                }
+            }
+
+            if (!isset($this->_options['ignore-errors'])) {
+                return false;
+            }
+        }
+
+        $this->_dirtree = array();
+        // {{{ really commit the transaction
+        foreach ($this->file_operations as $i => $tr) {
+            if (!$tr) {
+                // support removal of non-existing backups
+                continue;
+            }
+
+            list($type, $data) = $tr;
+            switch ($type) {
+                case 'backup':
+                    if (!file_exists($data[0])) {
+                        $this->file_operations[$i] = false;
+                        break;
+                    }
+
+                    if (!@copy($data[0], $data[0] . '.bak')) {
+                        $this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] .
+                            '.bak ' . $php_errormsg);
+                        return false;
+                    }
+                    $this->log(3, "+ backup $data[0] to $data[0].bak");
+                    break;
+                case 'removebackup':
+                    if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) {
+                        unlink($data[0] . '.bak');
+                        $this->log(3, "+ rm backup of $data[0] ($data[0].bak)");
+                    }
+                    break;
+                case 'rename':
+                    $test = file_exists($data[1]) ? @unlink($data[1]) : null;
+                    if (!$test && file_exists($data[1])) {
+                        if ($data[2]) {
+                            $extra = ', this extension must be installed manually.  Rename to "' .
+                                basename($data[1]) . '"';
+                        } else {
+                            $extra = '';
+                        }
+
+                        if (!isset($this->_options['soft'])) {
+                            $this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' .
+                                $data[0] . $extra);
+                        }
+
+                        if (!isset($this->_options['ignore-errors'])) {
+                            return false;
+                        }
+                    }
+
+                    // permissions issues with rename - copy() is far superior
+                    $perms = @fileperms($data[0]);
+                    if (!@copy($data[0], $data[1])) {
+                        $this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] .
+                            ' ' . $php_errormsg);
+                        return false;
+                    }
+
+                    // copy over permissions, otherwise they are lost
+                    @chmod($data[1], $perms);
+                    @unlink($data[0]);
+                    $this->log(3, "+ mv $data[0] $data[1]");
+                    break;
+                case 'chmod':
+                    if (!@chmod($data[1], $data[0])) {
+                        $this->log(1, 'Could not chmod ' . $data[1] . ' to ' .
+                            decoct($data[0]) . ' ' . $php_errormsg);
+                        return false;
+                    }
+
+                    $octmode = decoct($data[0]);
+                    $this->log(3, "+ chmod $octmode $data[1]");
+                    break;
+                case 'delete':
+                    if (file_exists($data[0])) {
+                        if (!@unlink($data[0])) {
+                            $this->log(1, 'Could not delete ' . $data[0] . ' ' .
+                                $php_errormsg);
+                            return false;
+                        }
+                        $this->log(3, "+ rm $data[0]");
+                    }
+                    break;
+                case 'rmdir':
+                    if (file_exists($data[0])) {
+                        do {
+                            $testme = opendir($data[0]);
+                            while (false !== ($entry = readdir($testme))) {
+                                if ($entry == '.' || $entry == '..') {
+                                    continue;
+                                }
+                                closedir($testme);
+                                break 2; // this directory is not empty and can't be
+                                         // deleted
+                            }
+
+                            closedir($testme);
+                            if (!@rmdir($data[0])) {
+                                $this->log(1, 'Could not rmdir ' . $data[0] . ' ' .
+                                    $php_errormsg);
+                                return false;
+                            }
+                            $this->log(3, "+ rmdir $data[0]");
+                        } while (false);
+                    }
+                    break;
+                case 'installed_as':
+                    $this->pkginfo->setInstalledAs($data[0], $data[1]);
+                    if (!isset($this->_dirtree[dirname($data[1])])) {
+                        $this->_dirtree[dirname($data[1])] = true;
+                        $this->pkginfo->setDirtree(dirname($data[1]));
+
+                        while(!empty($data[3]) && dirname($data[3]) != $data[3] &&
+                                $data[3] != '/' && $data[3] != '\\') {
+                            $this->pkginfo->setDirtree($pp =
+                                $this->_prependPath($data[3], $data[2]));
+                            $this->_dirtree[$pp] = true;
+                            $data[3] = dirname($data[3]);
+                        }
+                    }
+                    break;
+            }
+        }
+        // }}}
+        $this->log(2, "successfully committed $n file operations");
+        $this->file_operations = array();
+        return true;
+    }
+
+    // }}}
+    // {{{ rollbackFileTransaction()
+
+    function rollbackFileTransaction()
+    {
+        $n = count($this->file_operations);
+        $this->log(2, "rolling back $n file operations");
+        foreach ($this->file_operations as $tr) {
+            list($type, $data) = $tr;
+            switch ($type) {
+                case 'backup':
+                    if (file_exists($data[0] . '.bak')) {
+                        if (file_exists($data[0] && is_writable($data[0]))) {
+                            unlink($data[0]);
+                        }
+                        @copy($data[0] . '.bak', $data[0]);
+                        $this->log(3, "+ restore $data[0] from $data[0].bak");
+                    }
+                    break;
+                case 'removebackup':
+                    if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) {
+                        unlink($data[0] . '.bak');
+                        $this->log(3, "+ rm backup of $data[0] ($data[0].bak)");
+                    }
+                    break;
+                case 'rename':
+                    @unlink($data[0]);
+                    $this->log(3, "+ rm $data[0]");
+                    break;
+                case 'mkdir':
+                    @rmdir($data[0]);
+                    $this->log(3, "+ rmdir $data[0]");
+                    break;
+                case 'chmod':
+                    break;
+                case 'delete':
+                    break;
+                case 'installed_as':
+                    $this->pkginfo->setInstalledAs($data[0], false);
+                    break;
+            }
+        }
+        $this->pkginfo->resetDirtree();
+        $this->file_operations = array();
+    }
+
+    // }}}
+    // {{{ mkDirHier($dir)
+
+    function mkDirHier($dir)
+    {
+        $this->addFileOperation('mkdir', array($dir));
+        return parent::mkDirHier($dir);
+    }
+
+    // }}}
+    // {{{ download()
+
+    /**
+     * Download any files and their dependencies, if necessary
+     *
+     * @param array a mixed list of package names, local files, or package.xml
+     * @param PEAR_Config
+     * @param array options from the command line
+     * @param array this is the array that will be populated with packages to
+     *              install.  Format of each entry:
+     *
+     * <code>
+     * array('pkg' => 'package_name', 'file' => '/path/to/local/file',
+     *    'info' => array() // parsed package.xml
+     * );
+     * </code>
+     * @param array this will be populated with any error messages
+     * @param false private recursion variable
+     * @param false private recursion variable
+     * @param false private recursion variable
+     * @deprecated in favor of PEAR_Downloader
+     */
+    function download($packages, $options, &$config, &$installpackages,
+                      &$errors, $installed = false, $willinstall = false, $state = false)
+    {
+        // trickiness: initialize here
+        parent::PEAR_Downloader($this->ui, $options, $config);
+        $ret             = parent::download($packages);
+        $errors          = $this->getErrorMsgs();
+        $installpackages = $this->getDownloadedPackages();
+        trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " .
+                      "in favor of PEAR_Downloader class", E_USER_WARNING);
+        return $ret;
+    }
+
+    // }}}
+    // {{{ _parsePackageXml()
+
+    function _parsePackageXml(&$descfile, &$tmpdir)
+    {
+        if (substr($descfile, -4) == '.xml') {
+            $tmpdir = false;
+        } else {
+            // {{{ Decompress pack in tmp dir -------------------------------------
+
+            // To allow relative package file names
+            $descfile = realpath($descfile);
+
+            if (PEAR::isError($tmpdir = System::mktemp('-d'))) {
+                return $tmpdir;
+            }
+            $this->log(3, '+ tmp dir created at ' . $tmpdir);
+            // }}}
+        }
+
+        // Parse xml file -----------------------------------------------
+        $pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir);
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING);
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($p)) {
+            if (is_array($p->getUserInfo())) {
+                foreach ($p->getUserInfo() as $err) {
+                    $loglevel = $err['level'] == 'error' ? 0 : 1;
+                    if (!isset($this->_options['soft'])) {
+                        $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']);
+                    }
+                }
+            }
+            return $this->raiseError('Installation failed: invalid package file');
+        }
+
+        $descfile = $p->getPackageFile();
+        return $p;
+    }
+
+    // }}}
+    /**
+     * Set the list of PEAR_Downloader_Package objects to allow more sane
+     * dependency validation
+     * @param array
+     */
+    function setDownloadedPackages(&$pkgs)
+    {
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        $err = $this->analyzeDependencies($pkgs);
+        PEAR::popErrorHandling();
+        if (PEAR::isError($err)) {
+            return $err;
+        }
+        $this->_downloadedPackages = &$pkgs;
+    }
+
+    /**
+     * Set the list of PEAR_Downloader_Package objects to allow more sane
+     * dependency validation
+     * @param array
+     */
+    function setUninstallPackages(&$pkgs)
+    {
+        $this->_downloadedPackages = &$pkgs;
+    }
+
+    function getInstallPackages()
+    {
+        return $this->_downloadedPackages;
+    }
+
+    // {{{ install()
+
+    /**
+     * Installs the files within the package file specified.
+     *
+     * @param string|PEAR_Downloader_Package $pkgfile path to the package file,
+     *        or a pre-initialized packagefile object
+     * @param array $options
+     * recognized options:
+     * - installroot   : optional prefix directory for installation
+     * - force         : force installation
+     * - register-only : update registry but don't install files
+     * - upgrade       : upgrade existing install
+     * - soft          : fail silently
+     * - nodeps        : ignore dependency conflicts/missing dependencies
+     * - alldeps       : install all dependencies
+     * - onlyreqdeps   : install only required dependencies
+     *
+     * @return array|PEAR_Error package info if successful
+     */
+    function install($pkgfile, $options = array())
+    {
+        $this->_options = $options;
+        $this->_registry = &$this->config->getRegistry();
+        if (is_object($pkgfile)) {
+            $dlpkg    = &$pkgfile;
+            $pkg      = $pkgfile->getPackageFile();
+            $pkgfile  = $pkg->getArchiveFile();
+            $descfile = $pkg->getPackageFile();
+            $tmpdir   = dirname($descfile);
+        } else {
+            $descfile = $pkgfile;
+            $tmpdir   = '';
+            $pkg      = $this->_parsePackageXml($descfile, $tmpdir);
+            if (PEAR::isError($pkg)) {
+                return $pkg;
+            }
+        }
+
+        if (realpath($descfile) != realpath($pkgfile)) {
+            $tar = new Archive_Tar($pkgfile);
+            if (!$tar->extract($tmpdir)) {
+                return $this->raiseError("unable to unpack $pkgfile");
+            }
+        }
+
+        $pkgname = $pkg->getName();
+        $channel = $pkg->getChannel();
+        if (isset($this->_options['packagingroot'])) {
+            $regdir = $this->_prependPath(
+                $this->config->get('php_dir', null, 'pear.php.net'),
+                $this->_options['packagingroot']);
+
+            $packrootphp_dir = $this->_prependPath(
+                $this->config->get('php_dir', null, $channel),
+                $this->_options['packagingroot']);
+        }
+
+        if (isset($options['installroot'])) {
+            $this->config->setInstallRoot($options['installroot']);
+            $this->_registry = &$this->config->getRegistry();
+            $installregistry = &$this->_registry;
+            $this->installroot = ''; // all done automagically now
+            $php_dir = $this->config->get('php_dir', null, $channel);
+        } else {
+            $this->config->setInstallRoot(false);
+            $this->_registry = &$this->config->getRegistry();
+            if (isset($this->_options['packagingroot'])) {
+                $installregistry = &new PEAR_Registry($regdir);
+                if (!$installregistry->channelExists($channel, true)) {
+                    // we need to fake a channel-discover of this channel
+                    $chanobj = $this->_registry->getChannel($channel, true);
+                    $installregistry->addChannel($chanobj);
+                }
+                $php_dir = $packrootphp_dir;
+            } else {
+                $installregistry = &$this->_registry;
+                $php_dir = $this->config->get('php_dir', null, $channel);
+            }
+            $this->installroot = '';
+        }
+
+        // {{{ checks to do when not in "force" mode
+        if (empty($options['force']) &&
+              (file_exists($this->config->get('php_dir')) &&
+               is_dir($this->config->get('php_dir')))) {
+            $testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname);
+            $instfilelist = $pkg->getInstallationFileList(true);
+            if (PEAR::isError($instfilelist)) {
+                return $instfilelist;
+            }
+
+            // ensure we have the most accurate registry
+            $installregistry->flushFileMap();
+            $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1');
+            if (PEAR::isError($test)) {
+                return $test;
+            }
+
+            if (sizeof($test)) {
+                $pkgs = $this->getInstallPackages();
+                $found = false;
+                foreach ($pkgs as $param) {
+                    if ($pkg->isSubpackageOf($param)) {
+                        $found = true;
+                        break;
+                    }
+                }
+
+                if ($found) {
+                    // subpackages can conflict with earlier versions of parent packages
+                    $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel());
+                    $tmp = $test;
+                    foreach ($tmp as $file => $info) {
+                        if (is_array($info)) {
+                            if (strtolower($info[1]) == strtolower($param->getPackage()) &&
+                                  strtolower($info[0]) == strtolower($param->getChannel())
+                            ) {
+                                if (isset($parentreg['filelist'][$file])) {
+                                    unset($parentreg['filelist'][$file]);
+                                } else{
+                                    $pos     = strpos($file, '/');
+                                    $basedir = substr($file, 0, $pos);
+                                    $file2   = substr($file, $pos + 1);
+                                    if (isset($parentreg['filelist'][$file2]['baseinstalldir'])
+                                        && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir
+                                    ) {
+                                        unset($parentreg['filelist'][$file2]);
+                                    }
+                                }
+
+                                unset($test[$file]);
+                            }
+                        } else {
+                            if (strtolower($param->getChannel()) != 'pear.php.net') {
+                                continue;
+                            }
+
+                            if (strtolower($info) == strtolower($param->getPackage())) {
+                                if (isset($parentreg['filelist'][$file])) {
+                                    unset($parentreg['filelist'][$file]);
+                                } else{
+                                    $pos     = strpos($file, '/');
+                                    $basedir = substr($file, 0, $pos);
+                                    $file2   = substr($file, $pos + 1);
+                                    if (isset($parentreg['filelist'][$file2]['baseinstalldir'])
+                                        && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir
+                                    ) {
+                                        unset($parentreg['filelist'][$file2]);
+                                    }
+                                }
+
+                                unset($test[$file]);
+                            }
+                        }
+                    }
+
+                    $pfk = &new PEAR_PackageFile($this->config);
+                    $parentpkg = &$pfk->fromArray($parentreg);
+                    $installregistry->updatePackage2($parentpkg);
+                }
+
+                if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) {
+                    $tmp = $test;
+                    foreach ($tmp as $file => $info) {
+                        if (is_string($info)) {
+                            // pear.php.net packages are always stored as strings
+                            if (strtolower($info) == strtolower($param->getPackage())) {
+                                // upgrading existing package
+                                unset($test[$file]);
+                            }
+                        }
+                    }
+                }
+
+                if (count($test)) {
+                    $msg = "$channel/$pkgname: conflicting files found:\n";
+                    $longest = max(array_map("strlen", array_keys($test)));
+                    $fmt = "%${longest}s (%s)\n";
+                    foreach ($test as $file => $info) {
+                        if (!is_array($info)) {
+                            $info = array('pear.php.net', $info);
+                        }
+                        $info = $info[0] . '/' . $info[1];
+                        $msg .= sprintf($fmt, $file, $info);
+                    }
+
+                    if (!isset($options['ignore-errors'])) {
+                        return $this->raiseError($msg);
+                    }
+
+                    if (!isset($options['soft'])) {
+                        $this->log(0, "WARNING: $msg");
+                    }
+                }
+            }
+        }
+        // }}}
+
+        $this->startFileTransaction();
+
+        if (empty($options['upgrade']) && empty($options['soft'])) {
+            // checks to do only when installing new packages
+            if ($channel == 'pecl.php.net') {
+                $test = $installregistry->packageExists($pkgname, $channel);
+                if (!$test) {
+                    $test = $installregistry->packageExists($pkgname, 'pear.php.net');
+                }
+            } else {
+                $test = $installregistry->packageExists($pkgname, $channel);
+            }
+
+            if (empty($options['force']) && $test) {
+                return $this->raiseError("$channel/$pkgname is already installed");
+            }
+        } else {
+            $usechannel = $channel;
+            if ($channel == 'pecl.php.net') {
+                $test = $installregistry->packageExists($pkgname, $channel);
+                if (!$test) {
+                    $test = $installregistry->packageExists($pkgname, 'pear.php.net');
+                    $usechannel = 'pear.php.net';
+                }
+            } else {
+                $test = $installregistry->packageExists($pkgname, $channel);
+            }
+
+            if ($test) {
+                $v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel);
+                $v2 = $pkg->getVersion();
+                $cmp = version_compare("$v1", "$v2", 'gt');
+                if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) {
+                    return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)");
+                }
+
+                if (empty($options['register-only'])) {
+                    // when upgrading, remove old release's files first:
+                    if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel,
+                          true))) {
+                        if (!isset($options['ignore-errors'])) {
+                            return $this->raiseError($err);
+                        }
+
+                        if (!isset($options['soft'])) {
+                            $this->log(0, 'WARNING: ' . $err->getMessage());
+                        }
+                    } else {
+                        $backedup = $err;
+                    }
+                }
+            }
+        }
+
+        // {{{ Copy files to dest dir ---------------------------------------
+
+        // info from the package it self we want to access from _installFile
+        $this->pkginfo = &$pkg;
+        // used to determine whether we should build any C code
+        $this->source_files = 0;
+
+        $savechannel = $this->config->get('default_channel');
+        if (empty($options['register-only']) && !is_dir($php_dir)) {
+            if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) {
+                return $this->raiseError("no installation destination directory '$php_dir'\n");
+            }
+        }
+
+        $tmp_path = dirname($descfile);
+        if (substr($pkgfile, -4) != '.xml') {
+            $tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion();
+        }
+
+        $this->configSet('default_channel', $channel);
+        // {{{ install files
+
+        $ver = $pkg->getPackagexmlVersion();
+        if (version_compare($ver, '2.0', '>=')) {
+            $filelist = $pkg->getInstallationFilelist();
+        } else {
+            $filelist = $pkg->getFileList();
+        }
+
+        if (PEAR::isError($filelist)) {
+            return $filelist;
+        }
+
+        $p = &$installregistry->getPackage($pkgname, $channel);
+        $dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false;
+
+        $pkg->resetFilelist();
+        $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(),
+            'version', $pkg->getChannel()));
+        foreach ($filelist as $file => $atts) {
+            $this->expectError(PEAR_INSTALLER_FAILED);
+            if ($pkg->getPackagexmlVersion() == '1.0') {
+                $res = $this->_installFile($file, $atts, $tmp_path, $options);
+            } else {
+                $res = $this->_installFile2($pkg, $file, $atts, $tmp_path, $options);
+            }
+            $this->popExpect();
+
+            if (PEAR::isError($res)) {
+                if (empty($options['ignore-errors'])) {
+                    $this->rollbackFileTransaction();
+                    if ($res->getMessage() == "file does not exist") {
+                        $this->raiseError("file $file in package.xml does not exist");
+                    }
+
+                    return $this->raiseError($res);
+                }
+
+                if (!isset($options['soft'])) {
+                    $this->log(0, "Warning: " . $res->getMessage());
+                }
+            }
+
+            $real = isset($atts['attribs']) ? $atts['attribs'] : $atts;
+            if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') {
+                // Register files that were installed
+                $pkg->installedFile($file, $atts);
+            }
+        }
+        // }}}
+
+        // {{{ compile and install source files
+        if ($this->source_files > 0 && empty($options['nobuild'])) {
+            if (PEAR::isError($err =
+                  $this->_compileSourceFiles($savechannel, $pkg))) {
+                return $err;
+            }
+        }
+        // }}}
+
+        if (isset($backedup)) {
+            $this->_removeBackups($backedup);
+        }
+
+        if (!$this->commitFileTransaction()) {
+            $this->rollbackFileTransaction();
+            $this->configSet('default_channel', $savechannel);
+            return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED);
+        }
+        // }}}
+
+        $ret          = false;
+        $installphase = 'install';
+        $oldversion   = false;
+        // {{{ Register that the package is installed -----------------------
+        if (empty($options['upgrade'])) {
+            // if 'force' is used, replace the info in registry
+            $usechannel = $channel;
+            if ($channel == 'pecl.php.net') {
+                $test = $installregistry->packageExists($pkgname, $channel);
+                if (!$test) {
+                    $test = $installregistry->packageExists($pkgname, 'pear.php.net');
+                    $usechannel = 'pear.php.net';
+                }
+            } else {
+                $test = $installregistry->packageExists($pkgname, $channel);
+            }
+
+            if (!empty($options['force']) && $test) {
+                $oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel);
+                $installregistry->deletePackage($pkgname, $usechannel);
+            }
+            $ret = $installregistry->addPackage2($pkg);
+        } else {
+            if ($dirtree) {
+                $this->startFileTransaction();
+                // attempt to delete empty directories
+                uksort($dirtree, array($this, '_sortDirs'));
+                foreach($dirtree as $dir => $notused) {
+                    $this->addFileOperation('rmdir', array($dir));
+                }
+                $this->commitFileTransaction();
+            }
+
+            $usechannel = $channel;
+            if ($channel == 'pecl.php.net') {
+                $test = $installregistry->packageExists($pkgname, $channel);
+                if (!$test) {
+                    $test = $installregistry->packageExists($pkgname, 'pear.php.net');
+                    $usechannel = 'pear.php.net';
+                }
+            } else {
+                $test = $installregistry->packageExists($pkgname, $channel);
+            }
+
+            // new: upgrade installs a package if it isn't installed
+            if (!$test) {
+                $ret = $installregistry->addPackage2($pkg);
+            } else {
+                if ($usechannel != $channel) {
+                    $installregistry->deletePackage($pkgname, $usechannel);
+                    $ret = $installregistry->addPackage2($pkg);
+                } else {
+                    $ret = $installregistry->updatePackage2($pkg);
+                }
+                $installphase = 'upgrade';
+            }
+        }
+
+        if (!$ret) {
+            $this->configSet('default_channel', $savechannel);
+            return $this->raiseError("Adding package $channel/$pkgname to registry failed");
+        }
+        // }}}
+
+        $this->configSet('default_channel', $savechannel);
+        if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist
+            if (PEAR_Task_Common::hasPostinstallTasks()) {
+                PEAR_Task_Common::runPostinstallTasks($installphase);
+            }
+        }
+
+        return $pkg->toArray(true);
+    }
+
+    // }}}
+
+    // {{{ _compileSourceFiles()
+    /**
+     * @param string
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     */
+    function _compileSourceFiles($savechannel, &$filelist)
+    {
+        require_once 'PEAR/Builder.php';
+        $this->log(1, "$this->source_files source files, building");
+        $bob = &new PEAR_Builder($this->ui);
+        $bob->debug = $this->debug;
+        $built = $bob->build($filelist, array(&$this, '_buildCallback'));
+        if (PEAR::isError($built)) {
+            $this->rollbackFileTransaction();
+            $this->configSet('default_channel', $savechannel);
+            return $built;
+        }
+
+        $this->log(1, "\nBuild process completed successfully");
+        foreach ($built as $ext) {
+            $bn = basename($ext['file']);
+            list($_ext_name, $_ext_suff) = explode('.', $bn);
+            if ($_ext_suff == '.so' || $_ext_suff == '.dll') {
+                if (extension_loaded($_ext_name)) {
+                    $this->raiseError("Extension '$_ext_name' already loaded. " .
+                                      'Please unload it in your php.ini file ' .
+                                      'prior to install or upgrade');
+                }
+                $role = 'ext';
+            } else {
+                $role = 'src';
+            }
+
+            $dest = $ext['dest'];
+            $packagingroot = '';
+            if (isset($this->_options['packagingroot'])) {
+                $packagingroot = $this->_options['packagingroot'];
+            }
+
+            $copyto = $this->_prependPath($dest, $packagingroot);
+            $extra  = $copyto != $dest ? " as '$copyto'" : '';
+            $this->log(1, "Installing '$dest'$extra");
+
+            $copydir = dirname($copyto);
+            // pretty much nothing happens if we are only registering the install
+            if (empty($this->_options['register-only'])) {
+                if (!file_exists($copydir) || !is_dir($copydir)) {
+                    if (!$this->mkDirHier($copydir)) {
+                        return $this->raiseError("failed to mkdir $copydir",
+                            PEAR_INSTALLER_FAILED);
+                    }
+
+                    $this->log(3, "+ mkdir $copydir");
+                }
+
+                if (!@copy($ext['file'], $copyto)) {
+                    return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED);
+                }
+
+                $this->log(3, "+ cp $ext[file] $copyto");
+                $this->addFileOperation('rename', array($ext['file'], $copyto));
+                if (!OS_WINDOWS) {
+                    $mode = 0666 & ~(int)octdec($this->config->get('umask'));
+                    $this->addFileOperation('chmod', array($mode, $copyto));
+                    if (!@chmod($copyto, $mode)) {
+                        $this->log(0, "failed to change mode of $copyto ($php_errormsg)");
+                    }
+                }
+            }
+
+
+            $data = array(
+                'role'         => $role,
+                'name'         => $bn,
+                'installed_as' => $dest,
+                'php_api'      => $ext['php_api'],
+                'zend_mod_api' => $ext['zend_mod_api'],
+                'zend_ext_api' => $ext['zend_ext_api'],
+            );
+
+            if ($filelist->getPackageXmlVersion() == '1.0') {
+                $filelist->installedFile($bn, $data);
+            } else {
+                $filelist->installedFile($bn, array('attribs' => $data));
+            }
+        }
+    }
+
+    // }}}
+    function &getUninstallPackages()
+    {
+        return $this->_downloadedPackages;
+    }
+    // {{{ uninstall()
+
+    /**
+     * Uninstall a package
+     *
+     * This method removes all files installed by the application, and then
+     * removes any empty directories.
+     * @param string package name
+     * @param array Command-line options.  Possibilities include:
+     *
+     *              - installroot: base installation dir, if not the default
+     *              - register-only : update registry but don't remove files
+     *              - nodeps: do not process dependencies of other packages to ensure
+     *                        uninstallation does not break things
+     */
+    function uninstall($package, $options = array())
+    {
+        $installRoot = isset($options['installroot']) ? $options['installroot'] : '';
+        $this->config->setInstallRoot($installRoot);
+
+        $this->installroot = '';
+        $this->_registry = &$this->config->getRegistry();
+        if (is_object($package)) {
+            $channel = $package->getChannel();
+            $pkg     = $package;
+            $package = $pkg->getPackage();
+        } else {
+            $pkg = false;
+            $info = $this->_registry->parsePackageName($package,
+                $this->config->get('default_channel'));
+            $channel = $info['channel'];
+            $package = $info['package'];
+        }
+
+        $savechannel = $this->config->get('default_channel');
+        $this->configSet('default_channel', $channel);
+        if (!is_object($pkg)) {
+            $pkg = $this->_registry->getPackage($package, $channel);
+        }
+
+        if (!$pkg) {
+            $this->configSet('default_channel', $savechannel);
+            return $this->raiseError($this->_registry->parsedPackageNameToString(
+                array(
+                    'channel' => $channel,
+                    'package' => $package
+                ), true) . ' not installed');
+        }
+
+        if ($pkg->getInstalledBinary()) {
+            // this is just an alias for a binary package
+            return $this->_registry->deletePackage($package, $channel);
+        }
+
+        $filelist = $pkg->getFilelist();
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        if (!class_exists('PEAR_Dependency2')) {
+            require_once 'PEAR/Dependency2.php';
+        }
+
+        $depchecker = &new PEAR_Dependency2($this->config, $options,
+            array('channel' => $channel, 'package' => $package),
+            PEAR_VALIDATE_UNINSTALLING);
+        $e = $depchecker->validatePackageUninstall($this);
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($e)) {
+            if (!isset($options['ignore-errors'])) {
+                return $this->raiseError($e);
+            }
+
+            if (!isset($options['soft'])) {
+                $this->log(0, 'WARNING: ' . $e->getMessage());
+            }
+        } elseif (is_array($e)) {
+            if (!isset($options['soft'])) {
+                $this->log(0, $e[0]);
+            }
+        }
+
+        $this->pkginfo = &$pkg;
+        // pretty much nothing happens if we are only registering the uninstall
+        if (empty($options['register-only'])) {
+            // {{{ Delete the files
+            $this->startFileTransaction();
+            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+            if (PEAR::isError($err = $this->_deletePackageFiles($package, $channel))) {
+                PEAR::popErrorHandling();
+                $this->rollbackFileTransaction();
+                $this->configSet('default_channel', $savechannel);
+                if (!isset($options['ignore-errors'])) {
+                    return $this->raiseError($err);
+                }
+
+                if (!isset($options['soft'])) {
+                    $this->log(0, 'WARNING: ' . $err->getMessage());
+                }
+            } else {
+                PEAR::popErrorHandling();
+            }
+
+            if (!$this->commitFileTransaction()) {
+                $this->rollbackFileTransaction();
+                if (!isset($options['ignore-errors'])) {
+                    return $this->raiseError("uninstall failed");
+                }
+
+                if (!isset($options['soft'])) {
+                    $this->log(0, 'WARNING: uninstall failed');
+                }
+            } else {
+                $this->startFileTransaction();
+                $dirtree = $pkg->getDirTree();
+                if ($dirtree === false) {
+                    $this->configSet('default_channel', $savechannel);
+                    return $this->_registry->deletePackage($package, $channel);
+                }
+
+                // attempt to delete empty directories
+                uksort($dirtree, array($this, '_sortDirs'));
+                foreach($dirtree as $dir => $notused) {
+                    $this->addFileOperation('rmdir', array($dir));
+                }
+
+                if (!$this->commitFileTransaction()) {
+                    $this->rollbackFileTransaction();
+                    if (!isset($options['ignore-errors'])) {
+                        return $this->raiseError("uninstall failed");
+                    }
+
+                    if (!isset($options['soft'])) {
+                        $this->log(0, 'WARNING: uninstall failed');
+                    }
+                }
+            }
+            // }}}
+        }
+
+        $this->configSet('default_channel', $savechannel);
+        // Register that the package is no longer installed
+        return $this->_registry->deletePackage($package, $channel);
+    }
+
+    /**
+     * Sort a list of arrays of array(downloaded packagefilename) by dependency.
+     *
+     * It also removes duplicate dependencies
+     * @param array an array of PEAR_PackageFile_v[1/2] objects
+     * @return array|PEAR_Error array of array(packagefilename, package.xml contents)
+     */
+    function sortPackagesForUninstall(&$packages)
+    {
+        $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config);
+        if (PEAR::isError($this->_dependencyDB)) {
+            return $this->_dependencyDB;
+        }
+        usort($packages, array(&$this, '_sortUninstall'));
+    }
+
+    function _sortUninstall($a, $b)
+    {
+        if (!$a->getDeps() && !$b->getDeps()) {
+            return 0; // neither package has dependencies, order is insignificant
+        }
+        if ($a->getDeps() && !$b->getDeps()) {
+            return -1; // $a must be installed after $b because $a has dependencies
+        }
+        if (!$a->getDeps() && $b->getDeps()) {
+            return 1; // $b must be installed after $a because $b has dependencies
+        }
+        // both packages have dependencies
+        if ($this->_dependencyDB->dependsOn($a, $b)) {
+            return -1;
+        }
+        if ($this->_dependencyDB->dependsOn($b, $a)) {
+            return 1;
+        }
+        return 0;
+    }
+
+    // }}}
+    // {{{ _sortDirs()
+    function _sortDirs($a, $b)
+    {
+        if (strnatcmp($a, $b) == -1) return 1;
+        if (strnatcmp($a, $b) == 1) return -1;
+        return 0;
+    }
+
+    // }}}
+
+    // {{{ _buildCallback()
+
+    function _buildCallback($what, $data)
+    {
+        if (($what == 'cmdoutput' && $this->debug > 1) ||
+            ($what == 'output' && $this->debug > 0)) {
+            $this->ui->outputData(rtrim($data), 'build');
+        }
+    }
+
+    // }}}
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role.php b/lib/php/PEAR/Installer/Role.php
new file mode 100644
index 00000000..3d7e68d8
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role.php
@@ -0,0 +1,276 @@
+<?php
+/**
+ * PEAR_Installer_Role
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Role.php 278552 2009-04-10 19:42:49Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * base class for installer roles
+ */
+require_once 'PEAR/Installer/Role/Common.php';
+require_once 'PEAR/XMLParser.php';
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Installer_Role
+{
+    /**
+     * Set up any additional configuration variables that file roles require
+     *
+     * Never call this directly, it is called by the PEAR_Config constructor
+     * @param PEAR_Config
+     * @access private
+     * @static
+     */
+    function initializeConfig(&$config)
+    {
+        if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
+            PEAR_Installer_Role::registerRoles();
+        }
+
+        foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) {
+            if (!$info['config_vars']) {
+                continue;
+            }
+
+            $config->_addConfigVars($class, $info['config_vars']);
+        }
+    }
+
+    /**
+     * @param PEAR_PackageFile_v2
+     * @param string role name
+     * @param PEAR_Config
+     * @return PEAR_Installer_Role_Common
+     * @static
+     */
+    function &factory($pkg, $role, &$config)
+    {
+        if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
+            PEAR_Installer_Role::registerRoles();
+        }
+
+        if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) {
+            $a = false;
+            return $a;
+        }
+
+        $a = 'PEAR_Installer_Role_' . ucfirst($role);
+        if (!class_exists($a)) {
+            require_once str_replace('_', '/', $a) . '.php';
+        }
+
+        $b = new $a($config);
+        return $b;
+    }
+
+    /**
+     * Get a list of file roles that are valid for the particular release type.
+     *
+     * For instance, src files serve no purpose in regular php releases.
+     * @param string
+     * @param bool clear cache
+     * @return array
+     * @static
+     */
+    function getValidRoles($release, $clear = false)
+    {
+        if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
+            PEAR_Installer_Role::registerRoles();
+        }
+
+        static $ret = array();
+        if ($clear) {
+            $ret = array();
+        }
+
+        if (isset($ret[$release])) {
+            return $ret[$release];
+        }
+
+        $ret[$release] = array();
+        foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
+            if (in_array($release, $okreleases['releasetypes'])) {
+                $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
+            }
+        }
+
+        return $ret[$release];
+    }
+
+    /**
+     * Get a list of roles that require their files to be installed
+     *
+     * Most roles must be installed, but src and package roles, for instance
+     * are pseudo-roles.  src files are compiled into a new extension.  Package
+     * roles are actually fully bundled releases of a package
+     * @param bool clear cache
+     * @return array
+     * @static
+     */
+    function getInstallableRoles($clear = false)
+    {
+        if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
+            PEAR_Installer_Role::registerRoles();
+        }
+
+        static $ret;
+        if ($clear) {
+            unset($ret);
+        }
+
+        if (isset($ret)) {
+            return $ret;
+        }
+
+        $ret = array();
+        foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
+            if ($okreleases['installable']) {
+                $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
+            }
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Return an array of roles that are affected by the baseinstalldir attribute
+     *
+     * Most roles ignore this attribute, and instead install directly into:
+     * PackageName/filepath
+     * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php
+     * @param bool clear cache
+     * @return array
+     * @static
+     */
+    function getBaseinstallRoles($clear = false)
+    {
+        if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
+            PEAR_Installer_Role::registerRoles();
+        }
+
+        static $ret;
+        if ($clear) {
+            unset($ret);
+        }
+
+        if (isset($ret)) {
+            return $ret;
+        }
+
+        $ret = array();
+        foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
+            if ($okreleases['honorsbaseinstall']) {
+                $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
+            }
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Return an array of file roles that should be analyzed for PHP content at package time,
+     * like the "php" role.
+     * @param bool clear cache
+     * @return array
+     * @static
+     */
+    function getPhpRoles($clear = false)
+    {
+        if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
+            PEAR_Installer_Role::registerRoles();
+        }
+
+        static $ret;
+        if ($clear) {
+            unset($ret);
+        }
+
+        if (isset($ret)) {
+            return $ret;
+        }
+
+        $ret = array();
+        foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
+            if ($okreleases['phpfile']) {
+                $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
+            }
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Scan through the Command directory looking for classes
+     * and see what commands they implement.
+     * @param string which directory to look for classes, defaults to
+     *               the Installer/Roles subdirectory of
+     *               the directory from where this file (__FILE__) is
+     *               included.
+     *
+     * @return bool TRUE on success, a PEAR error on failure
+     * @access public
+     * @static
+     */
+    function registerRoles($dir = null)
+    {
+        $GLOBALS['_PEAR_INSTALLER_ROLES'] = array();
+        $parser = new PEAR_XMLParser;
+        if ($dir === null) {
+            $dir = dirname(__FILE__) . '/Role';
+        }
+
+        if (!file_exists($dir) || !is_dir($dir)) {
+            return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory");
+        }
+
+        $dp = @opendir($dir);
+        if (empty($dp)) {
+            return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg");
+        }
+
+        while ($entry = readdir($dp)) {
+            if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
+                continue;
+            }
+
+            $class = "PEAR_Installer_Role_".substr($entry, 0, -4);
+            // List of roles
+            if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) {
+                $file = "$dir/$entry";
+                $parser->parse(file_get_contents($file));
+                $data = $parser->getData();
+                if (!is_array($data['releasetypes'])) {
+                    $data['releasetypes'] = array($data['releasetypes']);
+                }
+
+                $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data;
+            }
+        }
+
+        closedir($dp);
+        ksort($GLOBALS['_PEAR_INSTALLER_ROLES']);
+        PEAR_Installer_Role::getBaseinstallRoles(true);
+        PEAR_Installer_Role::getInstallableRoles(true);
+        PEAR_Installer_Role::getPhpRoles(true);
+        PEAR_Installer_Role::getValidRoles('****', true);
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Cfg.php b/lib/php/PEAR/Installer/Role/Cfg.php
new file mode 100644
index 00000000..e7ea6e93
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Cfg.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * PEAR_Installer_Role_Cfg
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  2007-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Cfg.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.7.0
+ */
+
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  2007-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.7.0
+ */
+class PEAR_Installer_Role_Cfg extends PEAR_Installer_Role_Common
+{
+    /**
+     * @var PEAR_Installer
+     */
+    var $installer;
+
+    /**
+     * the md5 of the original file
+     *
+     * @var unknown_type
+     */
+    var $md5 = null;
+
+    /**
+     * Do any unusual setup here
+     * @param PEAR_Installer
+     * @param PEAR_PackageFile_v2
+     * @param array file attributes
+     * @param string file name
+     */
+    function setup(&$installer, $pkg, $atts, $file)
+    {
+        $this->installer = &$installer;
+        $reg = &$this->installer->config->getRegistry();
+        $package = $reg->getPackage($pkg->getPackage(), $pkg->getChannel());
+        if ($package) {
+            $filelist = $package->getFilelist();
+            if (isset($filelist[$file]) && isset($filelist[$file]['md5sum'])) {
+                $this->md5 = $filelist[$file]['md5sum'];
+            }
+        }
+    }
+
+    function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null)
+    {
+        $test = parent::processInstallation($pkg, $atts, $file, $tmp_path, $layer);
+        if (@file_exists($test[2]) && @file_exists($test[3])) {
+            $md5 = md5_file($test[2]);
+            // configuration has already been installed, check for mods
+            if ($md5 !== $this->md5 && $md5 !== md5_file($test[3])) {
+                // configuration has been modified, so save our version as
+                // configfile-version
+                $old = $test[2];
+                $test[2] .= '.new-' . $pkg->getVersion();
+                // backup original and re-install it
+                PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                $tmpcfg = $this->config->get('temp_dir');
+                $newloc = System::mkdir(array('-p', $tmpcfg));
+                if (!$newloc) {
+                    // try temp_dir
+                    $newloc = System::mktemp(array('-d'));
+                    if (!$newloc || PEAR::isError($newloc)) {
+                        PEAR::popErrorHandling();
+                        return PEAR::raiseError('Could not save existing configuration file '.
+                            $old . ', unable to install.  Please set temp_dir ' .
+                            'configuration variable to a writeable location and try again');
+                    }
+                } else {
+                    $newloc = $tmpcfg;
+                }
+
+                $temp_file = $newloc . DIRECTORY_SEPARATOR . uniqid('savefile');
+                if (!@copy($old, $temp_file)) {
+                    PEAR::popErrorHandling();
+                    return PEAR::raiseError('Could not save existing configuration file '.
+                        $old . ', unable to install.  Please set temp_dir ' .
+                        'configuration variable to a writeable location and try again');
+                }
+
+                PEAR::popErrorHandling();
+                $this->installer->log(0, "WARNING: configuration file $old is being installed as $test[2], you should manually merge in changes to the existing configuration file");
+                $this->installer->addFileOperation('rename', array($temp_file, $old, false));
+                $this->installer->addFileOperation('delete', array($temp_file));
+            }
+        }
+
+        return $test;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Cfg.xml b/lib/php/PEAR/Installer/Role/Cfg.xml
new file mode 100644
index 00000000..7a415dc4
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Cfg.xml
@@ -0,0 +1,15 @@
+<role version="1.0">
+ <releasetypes>php</releasetypes>
+ <releasetypes>extsrc</releasetypes>
+ <releasetypes>extbin</releasetypes>
+ <releasetypes>zendextsrc</releasetypes>
+ <releasetypes>zendextbin</releasetypes>
+ <installable>1</installable>
+ <locationconfig>cfg_dir</locationconfig>
+ <honorsbaseinstall />
+ <unusualbaseinstall>1</unusualbaseinstall>
+ <phpfile />
+ <executable />
+ <phpextension />
+ <config_vars />
+</role>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Common.php b/lib/php/PEAR/Installer/Role/Common.php
new file mode 100644
index 00000000..75145601
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Common.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * Base class for all installation roles.
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2006 The PHP Group
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * Base class for all installation roles.
+ *
+ * This class allows extensibility of file roles.  Packages with complex
+ * customization can now provide custom file roles along with the possibility of
+ * adding configuration values to match.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2006 The PHP Group
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Installer_Role_Common
+{
+    /**
+     * @var PEAR_Config
+     * @access protected
+     */
+    var $config;
+
+    /**
+     * @param PEAR_Config
+     */
+    function PEAR_Installer_Role_Common(&$config)
+    {
+        $this->config = $config;
+    }
+
+    /**
+     * Retrieve configuration information about a file role from its XML info
+     *
+     * @param string $role Role Classname, as in "PEAR_Installer_Role_Data"
+     * @return array
+     */
+    function getInfo($role)
+    {
+        if (empty($GLOBALS['_PEAR_INSTALLER_ROLES'][$role])) {
+            return PEAR::raiseError('Unknown Role class: "' . $role . '"');
+        }
+        return $GLOBALS['_PEAR_INSTALLER_ROLES'][$role];
+    }
+
+    /**
+     * This is called for each file to set up the directories and files
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @param array attributes from the <file> tag
+     * @param string file name
+     * @return array an array consisting of:
+     *
+     *    1 the original, pre-baseinstalldir installation directory
+     *    2 the final installation directory
+     *    3 the full path to the final location of the file
+     *    4 the location of the pre-installation file
+     */
+    function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null)
+    {
+        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . 
+            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
+        if (PEAR::isError($roleInfo)) {
+            return $roleInfo;
+        }
+        if (!$roleInfo['locationconfig']) {
+            return false;
+        }
+        if ($roleInfo['honorsbaseinstall']) {
+            $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer,
+                $pkg->getChannel());
+            if (!empty($atts['baseinstalldir'])) {
+                $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
+            }
+        } elseif ($roleInfo['unusualbaseinstall']) {
+            $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'],
+                    $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage();
+            if (!empty($atts['baseinstalldir'])) {
+                $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
+            }
+        } else {
+            $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'],
+                    $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage();
+        }
+        if (dirname($file) != '.' && empty($atts['install-as'])) {
+            $dest_dir .= DIRECTORY_SEPARATOR . dirname($file);
+        }
+        if (empty($atts['install-as'])) {
+            $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file);
+        } else {
+            $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as'];
+        }
+        $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file;
+
+        // Clean up the DIRECTORY_SEPARATOR mess
+        $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
+        
+        list($dest_dir, $dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
+                                                    array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR,
+                                                          DIRECTORY_SEPARATOR),
+                                                    array($dest_dir, $dest_file, $orig_file));
+        return array($save_destdir, $dest_dir, $dest_file, $orig_file);
+    }
+
+    /**
+     * Get the name of the configuration variable that specifies the location of this file
+     * @return string|false
+     */
+    function getLocationConfig()
+    {
+        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . 
+            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
+        if (PEAR::isError($roleInfo)) {
+            return $roleInfo;
+        }
+        return $roleInfo['locationconfig'];
+    }
+
+    /**
+     * Do any unusual setup here
+     * @param PEAR_Installer
+     * @param PEAR_PackageFile_v2
+     * @param array file attributes
+     * @param string file name
+     */
+    function setup(&$installer, $pkg, $atts, $file)
+    {
+    }
+
+    function isExecutable()
+    {
+        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . 
+            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
+        if (PEAR::isError($roleInfo)) {
+            return $roleInfo;
+        }
+        return $roleInfo['executable'];
+    }
+
+    function isInstallable()
+    {
+        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . 
+            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
+        if (PEAR::isError($roleInfo)) {
+            return $roleInfo;
+        }
+        return $roleInfo['installable'];
+    }
+
+    function isExtension()
+    {
+        $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . 
+            ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
+        if (PEAR::isError($roleInfo)) {
+            return $roleInfo;
+        }
+        return $roleInfo['phpextension'];
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Data.php b/lib/php/PEAR/Installer/Role/Data.php
new file mode 100644
index 00000000..7a1d4cc7
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Data.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * PEAR_Installer_Role_Data
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Data.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Data.xml b/lib/php/PEAR/Installer/Role/Data.xml
new file mode 100644
index 00000000..eae63720
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Data.xml
@@ -0,0 +1,15 @@
+<role version="1.0">
+ <releasetypes>php</releasetypes>
+ <releasetypes>extsrc</releasetypes>
+ <releasetypes>extbin</releasetypes>
+ <releasetypes>zendextsrc</releasetypes>
+ <releasetypes>zendextbin</releasetypes>
+ <installable>1</installable>
+ <locationconfig>data_dir</locationconfig>
+ <honorsbaseinstall />
+ <unusualbaseinstall />
+ <phpfile />
+ <executable />
+ <phpextension />
+ <config_vars />
+</role>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Doc.php b/lib/php/PEAR/Installer/Role/Doc.php
new file mode 100644
index 00000000..64c20034
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Doc.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * PEAR_Installer_Role_Doc
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Doc.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Doc.xml b/lib/php/PEAR/Installer/Role/Doc.xml
new file mode 100644
index 00000000..173afba0
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Doc.xml
@@ -0,0 +1,15 @@
+<role version="1.0">
+ <releasetypes>php</releasetypes>
+ <releasetypes>extsrc</releasetypes>
+ <releasetypes>extbin</releasetypes>
+ <releasetypes>zendextsrc</releasetypes>
+ <releasetypes>zendextbin</releasetypes>
+ <installable>1</installable>
+ <locationconfig>doc_dir</locationconfig>
+ <honorsbaseinstall />
+ <unusualbaseinstall />
+ <phpfile />
+ <executable />
+ <phpextension />
+ <config_vars />
+</role>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Ext.php b/lib/php/PEAR/Installer/Role/Ext.php
new file mode 100644
index 00000000..5784e95e
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Ext.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * PEAR_Installer_Role_Ext
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Ext.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Ext.xml b/lib/php/PEAR/Installer/Role/Ext.xml
new file mode 100644
index 00000000..e2940fe1
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Ext.xml
@@ -0,0 +1,12 @@
+<role version="1.0">
+ <releasetypes>extbin</releasetypes>
+ <releasetypes>zendextbin</releasetypes>
+ <installable>1</installable>
+ <locationconfig>ext_dir</locationconfig>
+ <honorsbaseinstall>1</honorsbaseinstall>
+ <unusualbaseinstall />
+ <phpfile />
+ <executable />
+ <phpextension>1</phpextension>
+ <config_vars />
+</role>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Php.php b/lib/php/PEAR/Installer/Role/Php.php
new file mode 100644
index 00000000..15bd163e
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Php.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * PEAR_Installer_Role_Php
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Php.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Php.xml b/lib/php/PEAR/Installer/Role/Php.xml
new file mode 100644
index 00000000..6b9a0e67
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Php.xml
@@ -0,0 +1,15 @@
+<role version="1.0">
+ <releasetypes>php</releasetypes>
+ <releasetypes>extsrc</releasetypes>
+ <releasetypes>extbin</releasetypes>
+ <releasetypes>zendextsrc</releasetypes>
+ <releasetypes>zendextbin</releasetypes>
+ <installable>1</installable>
+ <locationconfig>php_dir</locationconfig>
+ <honorsbaseinstall>1</honorsbaseinstall>
+ <unusualbaseinstall />
+ <phpfile>1</phpfile>
+ <executable />
+ <phpextension />
+ <config_vars />
+</role>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Script.php b/lib/php/PEAR/Installer/Role/Script.php
new file mode 100644
index 00000000..6169899b
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Script.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * PEAR_Installer_Role_Script
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Script.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Script.xml b/lib/php/PEAR/Installer/Role/Script.xml
new file mode 100644
index 00000000..e732cf2a
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Script.xml
@@ -0,0 +1,15 @@
+<role version="1.0">
+ <releasetypes>php</releasetypes>
+ <releasetypes>extsrc</releasetypes>
+ <releasetypes>extbin</releasetypes>
+ <releasetypes>zendextsrc</releasetypes>
+ <releasetypes>zendextbin</releasetypes>
+ <installable>1</installable>
+ <locationconfig>bin_dir</locationconfig>
+ <honorsbaseinstall>1</honorsbaseinstall>
+ <unusualbaseinstall />
+ <phpfile />
+ <executable>1</executable>
+ <phpextension />
+ <config_vars />
+</role>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Src.php b/lib/php/PEAR/Installer/Role/Src.php
new file mode 100644
index 00000000..918fff4a
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Src.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * PEAR_Installer_Role_Src
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Src.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common
+{
+    function setup(&$installer, $pkg, $atts, $file)
+    {
+        $installer->source_files++;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Src.xml b/lib/php/PEAR/Installer/Role/Src.xml
new file mode 100644
index 00000000..10348340
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Src.xml
@@ -0,0 +1,12 @@
+<role version="1.0">
+ <releasetypes>extsrc</releasetypes>
+ <releasetypes>zendextsrc</releasetypes>
+ <installable>1</installable>
+ <locationconfig>temp_dir</locationconfig>
+ <honorsbaseinstall />
+ <unusualbaseinstall />
+ <phpfile />
+ <executable />
+ <phpextension />
+ <config_vars />
+</role>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Test.php b/lib/php/PEAR/Installer/Role/Test.php
new file mode 100644
index 00000000..ad69def2
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Test.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * PEAR_Installer_Role_Test
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Test.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Test.xml b/lib/php/PEAR/Installer/Role/Test.xml
new file mode 100644
index 00000000..51d5b894
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Test.xml
@@ -0,0 +1,15 @@
+<role version="1.0">
+ <releasetypes>php</releasetypes>
+ <releasetypes>extsrc</releasetypes>
+ <releasetypes>extbin</releasetypes>
+ <releasetypes>zendextsrc</releasetypes>
+ <releasetypes>zendextbin</releasetypes>
+ <installable>1</installable>
+ <locationconfig>test_dir</locationconfig>
+ <honorsbaseinstall />
+ <unusualbaseinstall />
+ <phpfile />
+ <executable />
+ <phpextension />
+ <config_vars />
+</role>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Www.php b/lib/php/PEAR/Installer/Role/Www.php
new file mode 100644
index 00000000..bcc55d35
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Www.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * PEAR_Installer_Role_Www
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  2007-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Www.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.7.0
+ */
+
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  2007-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.7.0
+ */
+class PEAR_Installer_Role_Www extends PEAR_Installer_Role_Common {}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Installer/Role/Www.xml b/lib/php/PEAR/Installer/Role/Www.xml
new file mode 100644
index 00000000..7598be38
--- /dev/null
+++ b/lib/php/PEAR/Installer/Role/Www.xml
@@ -0,0 +1,15 @@
+<role version="1.0">
+ <releasetypes>php</releasetypes>
+ <releasetypes>extsrc</releasetypes>
+ <releasetypes>extbin</releasetypes>
+ <releasetypes>zendextsrc</releasetypes>
+ <releasetypes>zendextbin</releasetypes>
+ <installable>1</installable>
+ <locationconfig>www_dir</locationconfig>
+ <honorsbaseinstall>1</honorsbaseinstall>
+ <unusualbaseinstall />
+ <phpfile />
+ <executable />
+ <phpextension />
+ <config_vars />
+</role>
\ No newline at end of file
diff --git a/lib/php/PEAR/PackageFile.php b/lib/php/PEAR/PackageFile.php
new file mode 100644
index 00000000..e6979bff
--- /dev/null
+++ b/lib/php/PEAR/PackageFile.php
@@ -0,0 +1,501 @@
+<?php
+/**
+ * PEAR_PackageFile, package.xml parsing utility class
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: PackageFile.php 286670 2009-08-02 14:16:06Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * needed for PEAR_VALIDATE_* constants
+ */
+require_once 'PEAR/Validate.php';
+/**
+ * Error code if the package.xml <package> tag does not contain a valid version
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1);
+/**
+ * Error code if the package.xml <package> tag version is not supported (version 1.0 and 1.1 are the only supported versions,
+ * currently
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2);
+/**
+ * Abstraction for the package.xml package description file
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_PackageFile
+{
+    /**
+     * @var PEAR_Config
+     */
+    var $_config;
+    var $_debug;
+    /**
+     * Temp directory for uncompressing tgz files.
+     * @var string|false
+     */
+    var $_tmpdir;
+    var $_logger = false;
+    /**
+     * @var boolean
+     */
+    var $_rawReturn = false;
+
+    /**
+     *
+     * @param   PEAR_Config $config
+     * @param   ?   $debug
+     * @param   string @tmpdir Optional temporary directory for uncompressing
+     *          files
+     */
+    function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false)
+    {
+        $this->_config = $config;
+        $this->_debug = $debug;
+        $this->_tmpdir = $tmpdir;
+    }
+
+    /**
+     * Turn off validation - return a parsed package.xml without checking it
+     *
+     * This is used by the package-validate command
+     */
+    function rawReturn()
+    {
+        $this->_rawReturn = true;
+    }
+
+    function setLogger(&$l)
+    {
+        $this->_logger = &$l;
+    }
+
+    /**
+     * Create a PEAR_PackageFile_Parser_v* of a given version.
+     * @param   int $version
+     * @return  PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1
+     */
+    function &parserFactory($version)
+    {
+        if (!in_array($version{0}, array('1', '2'))) {
+            $a = false;
+            return $a;
+        }
+
+        include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php';
+        $version = $version{0};
+        $class = "PEAR_PackageFile_Parser_v$version";
+        $a = new $class;
+        return $a;
+    }
+
+    /**
+     * For simpler unit-testing
+     * @return string
+     */
+    function getClassPrefix()
+    {
+        return 'PEAR_PackageFile_v';
+    }
+
+    /**
+     * Create a PEAR_PackageFile_v* of a given version.
+     * @param   int $version
+     * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v1
+     */
+    function &factory($version)
+    {
+        if (!in_array($version{0}, array('1', '2'))) {
+            $a = false;
+            return $a;
+        }
+
+        include_once 'PEAR/PackageFile/v' . $version{0} . '.php';
+        $version = $version{0};
+        $class = $this->getClassPrefix() . $version;
+        $a = new $class;
+        return $a;
+    }
+
+    /**
+     * Create a PEAR_PackageFile_v* from its toArray() method
+     *
+     * WARNING: no validation is performed, the array is assumed to be valid,
+     * always parse from xml if you want validation.
+     * @param   array $arr
+     * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2
+     * @uses    factory() to construct the returned object.
+     */
+    function &fromArray($arr)
+    {
+        if (isset($arr['xsdversion'])) {
+            $obj = &$this->factory($arr['xsdversion']);
+            if ($this->_logger) {
+                $obj->setLogger($this->_logger);
+            }
+
+            $obj->setConfig($this->_config);
+            $obj->fromArray($arr);
+            return $obj;
+        }
+
+        if (isset($arr['package']['attribs']['version'])) {
+            $obj = &$this->factory($arr['package']['attribs']['version']);
+        } else {
+            $obj = &$this->factory('1.0');
+        }
+
+        if ($this->_logger) {
+            $obj->setLogger($this->_logger);
+        }
+
+        $obj->setConfig($this->_config);
+        $obj->fromArray($arr);
+        return $obj;
+    }
+
+    /**
+     * Create a PEAR_PackageFile_v* from an XML string.
+     * @access  public
+     * @param   string $data contents of package.xml file
+     * @param   int $state package state (one of PEAR_VALIDATE_* constants)
+     * @param   string $file full path to the package.xml file (and the files
+     *          it references)
+     * @param   string $archive optional name of the archive that the XML was
+     *          extracted from, if any
+     * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @uses    parserFactory() to construct a parser to load the package.
+     */
+    function &fromXmlString($data, $state, $file, $archive = false)
+    {
+        if (preg_match('/<package[^>]+version="([0-9]+\.[0-9]+)"/', $data, $packageversion)) {
+            if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) {
+                return PEAR::raiseError('package.xml version "' . $packageversion[1] .
+                    '" is not supported, only 1.0, 2.0, and 2.1 are supported.');
+            }
+
+            $object = &$this->parserFactory($packageversion[1]);
+            if ($this->_logger) {
+                $object->setLogger($this->_logger);
+            }
+
+            $object->setConfig($this->_config);
+            $pf = $object->parse($data, $file, $archive);
+            if (PEAR::isError($pf)) {
+                return $pf;
+            }
+
+            if ($this->_rawReturn) {
+                return $pf;
+            }
+
+            if (!$pf->validate($state)) {;
+                if ($this->_config->get('verbose') > 0
+                    && $this->_logger && $pf->getValidationWarnings(false)
+                ) {
+                    foreach ($pf->getValidationWarnings(false) as $warning) {
+                        $this->_logger->log(0, 'ERROR: ' . $warning['message']);
+                    }
+                }
+
+                $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed',
+                    2, null, null, $pf->getValidationWarnings());
+                return $a;
+            }
+
+            if ($this->_logger && $pf->getValidationWarnings(false)) {
+                foreach ($pf->getValidationWarnings() as $warning) {
+                    $this->_logger->log(0, 'WARNING: ' . $warning['message']);
+                }
+            }
+
+            if (method_exists($pf, 'flattenFilelist')) {
+                $pf->flattenFilelist(); // for v2
+            }
+
+            return $pf;
+        } elseif (preg_match('/<package[^>]+version="([^"]+)"/', $data, $packageversion)) {
+            $a = PEAR::raiseError('package.xml file "' . $file .
+                '" has unsupported package.xml <package> version "' . $packageversion[1] . '"');
+            return $a;
+        } else {
+            if (!class_exists('PEAR_ErrorStack')) {
+                require_once 'PEAR/ErrorStack.php';
+            }
+
+            PEAR_ErrorStack::staticPush('PEAR_PackageFile',
+                PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION,
+                'warning', array('xml' => $data), 'package.xml "' . $file .
+                    '" has no package.xml <package> version');
+            $object = &$this->parserFactory('1.0');
+            $object->setConfig($this->_config);
+            $pf = $object->parse($data, $file, $archive);
+            if (PEAR::isError($pf)) {
+                return $pf;
+            }
+
+            if ($this->_rawReturn) {
+                return $pf;
+            }
+
+            if (!$pf->validate($state)) {
+                $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed',
+                    2, null, null, $pf->getValidationWarnings());
+                return $a;
+            }
+
+            if ($this->_logger && $pf->getValidationWarnings(false)) {
+                foreach ($pf->getValidationWarnings() as $warning) {
+                    $this->_logger->log(0, 'WARNING: ' . $warning['message']);
+                }
+            }
+
+            if (method_exists($pf, 'flattenFilelist')) {
+                $pf->flattenFilelist(); // for v2
+            }
+
+            return $pf;
+        }
+    }
+
+    /**
+     * Register a temporary file or directory.  When the destructor is
+     * executed, all registered temporary files and directories are
+     * removed.
+     *
+     * @param string  $file  name of file or directory
+     * @return  void
+     */
+    function addTempFile($file)
+    {
+        $GLOBALS['_PEAR_Common_tempfiles'][] = $file;
+    }
+
+    /**
+     * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file.
+     * @access  public
+     * @param string contents of package.xml file
+     * @param int package state (one of PEAR_VALIDATE_* constants)
+     * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @using   Archive_Tar to extract the files
+     * @using   fromPackageFile() to load the package after the package.xml
+     *          file is extracted.
+     */
+    function &fromTgzFile($file, $state)
+    {
+        if (!class_exists('Archive_Tar')) {
+            require_once 'Archive/Tar.php';
+        }
+
+        $tar = new Archive_Tar($file);
+        if ($this->_debug <= 1) {
+            $tar->pushErrorHandling(PEAR_ERROR_RETURN);
+        }
+
+        $content = $tar->listContent();
+        if ($this->_debug <= 1) {
+            $tar->popErrorHandling();
+        }
+
+        if (!is_array($content)) {
+            if (is_string($file) && strlen($file < 255) &&
+                  (!file_exists($file) || !@is_file($file))) {
+                $ret = PEAR::raiseError("could not open file \"$file\"");
+                return $ret;
+            }
+
+            $file = realpath($file);
+            $ret = PEAR::raiseError("Could not get contents of package \"$file\"".
+                                     '. Invalid tgz file.');
+            return $ret;
+        }
+
+        if (!count($content) && !@is_file($file)) {
+            $ret = PEAR::raiseError("could not open file \"$file\"");
+            return $ret;
+        }
+
+        $xml      = null;
+        $origfile = $file;
+        foreach ($content as $file) {
+            $name = $file['filename'];
+            if ($name == 'package2.xml') { // allow a .tgz to distribute both versions
+                $xml = $name;
+                break;
+            }
+
+            if ($name == 'package.xml') {
+                $xml = $name;
+                break;
+            } elseif (preg_match('/package.xml$/', $name, $match)) {
+                $xml = $name;
+                break;
+            }
+        }
+
+        if ($this->_tmpdir) {
+            $tmpdir = $this->_tmpdir;
+        } else {
+            $tmpdir = System::mkTemp(array('-t', $this->_config->get('temp_dir'), '-d', 'pear'));
+            if ($tmpdir === false) {
+                $ret = PEAR::raiseError("there was a problem with getting the configured temp directory");
+                return $ret;
+            }
+
+            PEAR_PackageFile::addTempFile($tmpdir);
+        }
+
+        $this->_extractErrors();
+        PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors'));
+        if (!$xml || !$tar->extractList(array($xml), $tmpdir)) {
+            $extra = implode("\n", $this->_extractErrors());
+            if ($extra) {
+                $extra = ' ' . $extra;
+            }
+
+            PEAR::staticPopErrorHandling();
+            $ret = PEAR::raiseError('could not extract the package.xml file from "' .
+                $origfile . '"' . $extra);
+            return $ret;
+        }
+
+        PEAR::staticPopErrorHandling();
+        $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile);
+        return $ret;
+    }
+
+    /**
+     * helper for extracting Archive_Tar errors
+     * @var array
+     * @access private
+     */
+    var $_extractErrors = array();
+
+    /**
+     * helper callback for extracting Archive_Tar errors
+     *
+     * @param PEAR_Error|null $err
+     * @return array
+     * @access private
+     */
+    function _extractErrors($err = null)
+    {
+        static $errors = array();
+        if ($err === null) {
+            $e = $errors;
+            $errors = array();
+            return $e;
+        }
+        $errors[] = $err->getMessage();
+    }
+
+    /**
+     * Create a PEAR_PackageFile_v* from a package.xml file.
+     *
+     * @access public
+     * @param   string  $descfile  name of package xml file
+     * @param   int     $state package state (one of PEAR_VALIDATE_* constants)
+     * @param   string|false $archive name of the archive this package.xml came
+     *          from, if any
+     * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @uses    PEAR_PackageFile::fromXmlString to create the oject after the
+     *          XML is loaded from the package.xml file.
+     */
+    function &fromPackageFile($descfile, $state, $archive = false)
+    {
+        $fp = false;
+        if (is_string($descfile) && strlen($descfile) < 255 &&
+             (
+              !file_exists($descfile) || !is_file($descfile) || !is_readable($descfile)
+              || (!$fp = @fopen($descfile, 'r'))
+             )
+        ) {
+            $a = PEAR::raiseError("Unable to open $descfile");
+            return $a;
+        }
+
+        // read the whole thing so we only get one cdata callback
+        // for each block of cdata
+        fclose($fp);
+        $data = file_get_contents($descfile);
+        $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive);
+        return $ret;
+    }
+
+
+    /**
+     * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file.
+     *
+     * This method is able to extract information about a package from a .tgz
+     * archive or from a XML package definition file.
+     *
+     * @access public
+     * @param   string  $info file name
+     * @param   int     $state package state (one of PEAR_VALIDATE_* constants)
+     * @return  PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @uses    fromPackageFile() if the file appears to be XML
+     * @uses    fromTgzFile() to load all non-XML files
+     */
+    function &fromAnyFile($info, $state)
+    {
+        if (is_dir($info)) {
+            $dir_name = realpath($info);
+            if (file_exists($dir_name . '/package.xml')) {
+                $info = PEAR_PackageFile::fromPackageFile($dir_name .  '/package.xml', $state);
+            } elseif (file_exists($dir_name .  '/package2.xml')) {
+                $info = PEAR_PackageFile::fromPackageFile($dir_name .  '/package2.xml', $state);
+            } else {
+                $info = PEAR::raiseError("No package definition found in '$info' directory");
+            }
+
+            return $info;
+        }
+
+        $fp = false;
+        if (is_string($info) && strlen($info) < 255 &&
+             (file_exists($info) || ($fp = @fopen($info, 'r')))
+        ) {
+
+            if ($fp) {
+                fclose($fp);
+            }
+
+            $tmp = substr($info, -4);
+            if ($tmp == '.xml') {
+                $info = &PEAR_PackageFile::fromPackageFile($info, $state);
+            } elseif ($tmp == '.tar' || $tmp == '.tgz') {
+                $info = &PEAR_PackageFile::fromTgzFile($info, $state);
+            } else {
+                $fp   = fopen($info, 'r');
+                $test = fread($fp, 5);
+                fclose($fp);
+                if ($test == '<?xml') {
+                    $info = &PEAR_PackageFile::fromPackageFile($info, $state);
+                } else {
+                    $info = &PEAR_PackageFile::fromTgzFile($info, $state);
+                }
+            }
+
+            return $info;
+        }
+
+        $info = PEAR::raiseError("Cannot open '$info' for parsing");
+        return $info;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/PackageFile/Generator/v1.php b/lib/php/PEAR/PackageFile/Generator/v1.php
new file mode 100644
index 00000000..55993927
--- /dev/null
+++ b/lib/php/PEAR/PackageFile/Generator/v1.php
@@ -0,0 +1,1284 @@
+<?php
+/**
+ * package.xml generation class, package.xml version 1.0
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: v1.php 286494 2009-07-29 06:57:11Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * needed for PEAR_VALIDATE_* constants
+ */
+require_once 'PEAR/Validate.php';
+require_once 'System.php';
+require_once 'PEAR/PackageFile/v2.php';
+/**
+ * This class converts a PEAR_PackageFile_v1 object into any output format.
+ *
+ * Supported output formats include array, XML string, and a PEAR_PackageFile_v2
+ * object, for converting package.xml 1.0 into package.xml 2.0 with no sweat.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_PackageFile_Generator_v1
+{
+    /**
+     * @var PEAR_PackageFile_v1
+     */
+    var $_packagefile;
+    function PEAR_PackageFile_Generator_v1(&$packagefile)
+    {
+        $this->_packagefile = &$packagefile;
+    }
+
+    function getPackagerVersion()
+    {
+        return '1.9.0';
+    }
+
+    /**
+     * @param PEAR_Packager
+     * @param bool if true, a .tgz is written, otherwise a .tar is written
+     * @param string|null directory in which to save the .tgz
+     * @return string|PEAR_Error location of package or error object
+     */
+    function toTgz(&$packager, $compress = true, $where = null)
+    {
+        require_once 'Archive/Tar.php';
+        if ($where === null) {
+            if (!($where = System::mktemp(array('-d')))) {
+                return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: mktemp failed');
+            }
+        } elseif (!@System::mkDir(array('-p', $where))) {
+            return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: "' . $where . '" could' .
+                ' not be created');
+        }
+        if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') &&
+              !is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) {
+            return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: unable to save package.xml as' .
+                ' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"');
+        }
+        if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) {
+            return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: invalid package file');
+        }
+        $pkginfo = $this->_packagefile->getArray();
+        $ext = $compress ? '.tgz' : '.tar';
+        $pkgver = $pkginfo['package'] . '-' . $pkginfo['version'];
+        $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext;
+        if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) &&
+              !is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) {
+            return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: cannot create tgz file "' .
+                getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"');
+        }
+        if ($pkgfile = $this->_packagefile->getPackageFile()) {
+            $pkgdir = dirname(realpath($pkgfile));
+            $pkgfile = basename($pkgfile);
+        } else {
+            return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: package file object must ' .
+                'be created from a real file');
+        }
+        // {{{ Create the package file list
+        $filelist = array();
+        $i = 0;
+
+        foreach ($this->_packagefile->getFilelist() as $fname => $atts) {
+            $file = $pkgdir . DIRECTORY_SEPARATOR . $fname;
+            if (!file_exists($file)) {
+                return PEAR::raiseError("File does not exist: $fname");
+            } else {
+                $filelist[$i++] = $file;
+                if (!isset($atts['md5sum'])) {
+                    $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($file));
+                }
+                $packager->log(2, "Adding file $fname");
+            }
+        }
+        // }}}
+        $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true);
+        if ($packagexml) {
+            $tar =& new Archive_Tar($dest_package, $compress);
+            $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors
+            // ----- Creates with the package.xml file
+            $ok = $tar->createModify(array($packagexml), '', $where);
+            if (PEAR::isError($ok)) {
+                return $ok;
+            } elseif (!$ok) {
+                return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed');
+            }
+            // ----- Add the content of the package
+            if (!$tar->addModify($filelist, $pkgver, $pkgdir)) {
+                return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed');
+            }
+            return $dest_package;
+        }
+    }
+
+    /**
+     * @param string|null directory to place the package.xml in, or null for a temporary dir
+     * @param int one of the PEAR_VALIDATE_* constants
+     * @param string name of the generated file
+     * @param bool if true, then no analysis will be performed on role="php" files
+     * @return string|PEAR_Error path to the created file on success
+     */
+    function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml',
+                           $nofilechecking = false)
+    {
+        if (!$this->_packagefile->validate($state, $nofilechecking)) {
+            return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: invalid package.xml',
+                null, null, null, $this->_packagefile->getValidationWarnings());
+        }
+        if ($where === null) {
+            if (!($where = System::mktemp(array('-d')))) {
+                return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: mktemp failed');
+            }
+        } elseif (!@System::mkDir(array('-p', $where))) {
+            return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: "' . $where . '" could' .
+                ' not be created');
+        }
+        $newpkgfile = $where . DIRECTORY_SEPARATOR . $name;
+        $np = @fopen($newpkgfile, 'wb');
+        if (!$np) {
+            return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: unable to save ' .
+               "$name as $newpkgfile");
+        }
+        fwrite($np, $this->toXml($state, true));
+        fclose($np);
+        return $newpkgfile;
+    }
+
+    /**
+     * fix both XML encoding to be UTF8, and replace standard XML entities < > " & '
+     *
+     * @param string $string
+     * @return string
+     * @access private
+     */
+    function _fixXmlEncoding($string)
+    {
+        if (version_compare(phpversion(), '5.0.0', 'lt')) {
+            $string = utf8_encode($string);
+        }
+        return strtr($string, array(
+                                          '&'  => '&amp;',
+                                          '>'  => '&gt;',
+                                          '<'  => '&lt;',
+                                          '"'  => '&quot;',
+                                          '\'' => '&apos;' ));
+    }
+
+    /**
+     * Return an XML document based on the package info (as returned
+     * by the PEAR_Common::infoFrom* methods).
+     *
+     * @return string XML data
+     */
+    function toXml($state = PEAR_VALIDATE_NORMAL, $nofilevalidation = false)
+    {
+        $this->_packagefile->setDate(date('Y-m-d'));
+        if (!$this->_packagefile->validate($state, $nofilevalidation)) {
+            return false;
+        }
+        $pkginfo = $this->_packagefile->getArray();
+        static $maint_map = array(
+            "handle" => "user",
+            "name" => "name",
+            "email" => "email",
+            "role" => "role",
+            );
+        $ret = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+        $ret .= "<!DOCTYPE package SYSTEM \"http://pear.php.net/dtd/package-1.0\">\n";
+        $ret .= "<package version=\"1.0\" packagerversion=\"1.9.0\">\n" .
+" <name>$pkginfo[package]</name>";
+        if (isset($pkginfo['extends'])) {
+            $ret .= "\n<extends>$pkginfo[extends]</extends>";
+        }
+        $ret .=
+ "\n <summary>".$this->_fixXmlEncoding($pkginfo['summary'])."</summary>\n" .
+" <description>".trim($this->_fixXmlEncoding($pkginfo['description']))."\n </description>\n" .
+" <maintainers>\n";
+        foreach ($pkginfo['maintainers'] as $maint) {
+            $ret .= "  <maintainer>\n";
+            foreach ($maint_map as $idx => $elm) {
+                $ret .= "   <$elm>";
+                $ret .= $this->_fixXmlEncoding($maint[$idx]);
+                $ret .= "</$elm>\n";
+            }
+            $ret .= "  </maintainer>\n";
+        }
+        $ret .= "  </maintainers>\n";
+        $ret .= $this->_makeReleaseXml($pkginfo, false, $state);
+        if (isset($pkginfo['changelog']) && count($pkginfo['changelog']) > 0) {
+            $ret .= " <changelog>\n";
+            foreach ($pkginfo['changelog'] as $oldrelease) {
+                $ret .= $this->_makeReleaseXml($oldrelease, true);
+            }
+            $ret .= " </changelog>\n";
+        }
+        $ret .= "</package>\n";
+        return $ret;
+    }
+
+    // }}}
+    // {{{ _makeReleaseXml()
+
+    /**
+     * Generate part of an XML description with release information.
+     *
+     * @param array  $pkginfo    array with release information
+     * @param bool   $changelog  whether the result will be in a changelog element
+     *
+     * @return string XML data
+     *
+     * @access private
+     */
+    function _makeReleaseXml($pkginfo, $changelog = false, $state = PEAR_VALIDATE_NORMAL)
+    {
+        // XXX QUOTE ENTITIES IN PCDATA, OR EMBED IN CDATA BLOCKS!!
+        $indent = $changelog ? "  " : "";
+        $ret = "$indent <release>\n";
+        if (!empty($pkginfo['version'])) {
+            $ret .= "$indent  <version>$pkginfo[version]</version>\n";
+        }
+        if (!empty($pkginfo['release_date'])) {
+            $ret .= "$indent  <date>$pkginfo[release_date]</date>\n";
+        }
+        if (!empty($pkginfo['release_license'])) {
+            $ret .= "$indent  <license>$pkginfo[release_license]</license>\n";
+        }
+        if (!empty($pkginfo['release_state'])) {
+            $ret .= "$indent  <state>$pkginfo[release_state]</state>\n";
+        }
+        if (!empty($pkginfo['release_notes'])) {
+            $ret .= "$indent  <notes>".trim($this->_fixXmlEncoding($pkginfo['release_notes']))
+            ."\n$indent  </notes>\n";
+        }
+        if (!empty($pkginfo['release_warnings'])) {
+            $ret .= "$indent  <warnings>".$this->_fixXmlEncoding($pkginfo['release_warnings'])."</warnings>\n";
+        }
+        if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) {
+            $ret .= "$indent  <deps>\n";
+            foreach ($pkginfo['release_deps'] as $dep) {
+                $ret .= "$indent   <dep type=\"$dep[type]\" rel=\"$dep[rel]\"";
+                if (isset($dep['version'])) {
+                    $ret .= " version=\"$dep[version]\"";
+                }
+                if (isset($dep['optional'])) {
+                    $ret .= " optional=\"$dep[optional]\"";
+                }
+                if (isset($dep['name'])) {
+                    $ret .= ">$dep[name]</dep>\n";
+                } else {
+                    $ret .= "/>\n";
+                }
+            }
+            $ret .= "$indent  </deps>\n";
+        }
+        if (isset($pkginfo['configure_options'])) {
+            $ret .= "$indent  <configureoptions>\n";
+            foreach ($pkginfo['configure_options'] as $c) {
+                $ret .= "$indent   <configureoption name=\"".
+                    $this->_fixXmlEncoding($c['name']) . "\"";
+                if (isset($c['default'])) {
+                    $ret .= " default=\"" . $this->_fixXmlEncoding($c['default']) . "\"";
+                }
+                $ret .= " prompt=\"" . $this->_fixXmlEncoding($c['prompt']) . "\"";
+                $ret .= "/>\n";
+            }
+            $ret .= "$indent  </configureoptions>\n";
+        }
+        if (isset($pkginfo['provides'])) {
+            foreach ($pkginfo['provides'] as $key => $what) {
+                $ret .= "$indent  <provides type=\"$what[type]\" ";
+                $ret .= "name=\"$what[name]\" ";
+                if (isset($what['extends'])) {
+                    $ret .= "extends=\"$what[extends]\" ";
+                }
+                $ret .= "/>\n";
+            }
+        }
+        if (isset($pkginfo['filelist'])) {
+            $ret .= "$indent  <filelist>\n";
+            if ($state ^ PEAR_VALIDATE_PACKAGING) {
+                $ret .= $this->recursiveXmlFilelist($pkginfo['filelist']);
+            } else {
+                foreach ($pkginfo['filelist'] as $file => $fa) {
+                    if (!isset($fa['role'])) {
+                        $fa['role'] = '';
+                    }
+                    $ret .= "$indent   <file role=\"$fa[role]\"";
+                    if (isset($fa['baseinstalldir'])) {
+                        $ret .= ' baseinstalldir="' .
+                            $this->_fixXmlEncoding($fa['baseinstalldir']) . '"';
+                    }
+                    if (isset($fa['md5sum'])) {
+                        $ret .= " md5sum=\"$fa[md5sum]\"";
+                    }
+                    if (isset($fa['platform'])) {
+                        $ret .= " platform=\"$fa[platform]\"";
+                    }
+                    if (!empty($fa['install-as'])) {
+                        $ret .= ' install-as="' .
+                            $this->_fixXmlEncoding($fa['install-as']) . '"';
+                    }
+                    $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"';
+                    if (empty($fa['replacements'])) {
+                        $ret .= "/>\n";
+                    } else {
+                        $ret .= ">\n";
+                        foreach ($fa['replacements'] as $r) {
+                            $ret .= "$indent    <replace";
+                            foreach ($r as $k => $v) {
+                                $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"';
+                            }
+                            $ret .= "/>\n";
+                        }
+                        $ret .= "$indent   </file>\n";
+                    }
+                }
+            }
+            $ret .= "$indent  </filelist>\n";
+        }
+        $ret .= "$indent </release>\n";
+        return $ret;
+    }
+
+    /**
+     * @param array
+     * @access protected
+     */
+    function recursiveXmlFilelist($list)
+    {
+        $this->_dirs = array();
+        foreach ($list as $file => $attributes) {
+            $this->_addDir($this->_dirs, explode('/', dirname($file)), $file, $attributes);
+        }
+        return $this->_formatDir($this->_dirs);
+    }
+
+    /**
+     * @param array
+     * @param array
+     * @param string|null
+     * @param array|null
+     * @access private
+     */
+    function _addDir(&$dirs, $dir, $file = null, $attributes = null)
+    {
+        if ($dir == array() || $dir == array('.')) {
+            $dirs['files'][basename($file)] = $attributes;
+            return;
+        }
+        $curdir = array_shift($dir);
+        if (!isset($dirs['dirs'][$curdir])) {
+            $dirs['dirs'][$curdir] = array();
+        }
+        $this->_addDir($dirs['dirs'][$curdir], $dir, $file, $attributes);
+    }
+
+    /**
+     * @param array
+     * @param string
+     * @param string
+     * @access private
+     */
+    function _formatDir($dirs, $indent = '', $curdir = '')
+    {
+        $ret = '';
+        if (!count($dirs)) {
+            return '';
+        }
+        if (isset($dirs['dirs'])) {
+            uksort($dirs['dirs'], 'strnatcasecmp');
+            foreach ($dirs['dirs'] as $dir => $contents) {
+                $usedir = "$curdir/$dir";
+                $ret .= "$indent   <dir name=\"$dir\">\n";
+                $ret .= $this->_formatDir($contents, "$indent ", $usedir);
+                $ret .= "$indent   </dir> <!-- $usedir -->\n";
+            }
+        }
+        if (isset($dirs['files'])) {
+            uksort($dirs['files'], 'strnatcasecmp');
+            foreach ($dirs['files'] as $file => $attribs) {
+                $ret .= $this->_formatFile($file, $attribs, $indent);
+            }
+        }
+        return $ret;
+    }
+
+    /**
+     * @param string
+     * @param array
+     * @param string
+     * @access private
+     */
+    function _formatFile($file, $attributes, $indent)
+    {
+        $ret = "$indent   <file role=\"$attributes[role]\"";
+        if (isset($attributes['baseinstalldir'])) {
+            $ret .= ' baseinstalldir="' .
+                $this->_fixXmlEncoding($attributes['baseinstalldir']) . '"';
+        }
+        if (isset($attributes['md5sum'])) {
+            $ret .= " md5sum=\"$attributes[md5sum]\"";
+        }
+        if (isset($attributes['platform'])) {
+            $ret .= " platform=\"$attributes[platform]\"";
+        }
+        if (!empty($attributes['install-as'])) {
+            $ret .= ' install-as="' .
+                $this->_fixXmlEncoding($attributes['install-as']) . '"';
+        }
+        $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"';
+        if (empty($attributes['replacements'])) {
+            $ret .= "/>\n";
+        } else {
+            $ret .= ">\n";
+            foreach ($attributes['replacements'] as $r) {
+                $ret .= "$indent    <replace";
+                foreach ($r as $k => $v) {
+                    $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"';
+                }
+                $ret .= "/>\n";
+            }
+            $ret .= "$indent   </file>\n";
+        }
+        return $ret;
+    }
+
+    // {{{ _unIndent()
+
+    /**
+     * Unindent given string (?)
+     *
+     * @param string $str The string that has to be unindented.
+     * @return string
+     * @access private
+     */
+    function _unIndent($str)
+    {
+        // remove leading newlines
+        $str = preg_replace('/^[\r\n]+/', '', $str);
+        // find whitespace at the beginning of the first line
+        $indent_len = strspn($str, " \t");
+        $indent = substr($str, 0, $indent_len);
+        $data = '';
+        // remove the same amount of whitespace from following lines
+        foreach (explode("\n", $str) as $line) {
+            if (substr($line, 0, $indent_len) == $indent) {
+                $data .= substr($line, $indent_len) . "\n";
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * @return array
+     */
+    function dependenciesToV2()
+    {
+        $arr = array();
+        $this->_convertDependencies2_0($arr);
+        return $arr['dependencies'];
+    }
+
+    /**
+     * Convert a package.xml version 1.0 into version 2.0
+     *
+     * Note that this does a basic conversion, to allow more advanced
+     * features like bundles and multiple releases
+     * @param string the classname to instantiate and return.  This must be
+     *               PEAR_PackageFile_v2 or a descendant
+     * @param boolean if true, only valid, deterministic package.xml 1.0 as defined by the
+     *                strictest parameters will be converted
+     * @return PEAR_PackageFile_v2|PEAR_Error
+     */
+    function &toV2($class = 'PEAR_PackageFile_v2', $strict = false)
+    {
+        if ($strict) {
+            if (!$this->_packagefile->validate()) {
+                $a = PEAR::raiseError('invalid package.xml version 1.0 cannot be converted' .
+                    ' to version 2.0', null, null, null,
+                    $this->_packagefile->getValidationWarnings(true));
+                return $a;
+            }
+        }
+
+        $arr = array(
+            'attribs' => array(
+                             'version' => '2.0',
+                             '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',
+                             'xsi:schemaLocation' => "http://pear.php.net/dtd/tasks-1.0\n" .
+"http://pear.php.net/dtd/tasks-1.0.xsd\n" .
+"http://pear.php.net/dtd/package-2.0\n" .
+'http://pear.php.net/dtd/package-2.0.xsd',
+                         ),
+            'name' => $this->_packagefile->getPackage(),
+            'channel' => 'pear.php.net',
+        );
+        $arr['summary'] = $this->_packagefile->getSummary();
+        $arr['description'] = $this->_packagefile->getDescription();
+        $maintainers = $this->_packagefile->getMaintainers();
+        foreach ($maintainers as $maintainer) {
+            if ($maintainer['role'] != 'lead') {
+                continue;
+            }
+            $new = array(
+                'name' => $maintainer['name'],
+                'user' => $maintainer['handle'],
+                'email' => $maintainer['email'],
+                'active' => 'yes',
+            );
+            $arr['lead'][] = $new;
+        }
+
+        if (!isset($arr['lead'])) { // some people... you know?
+            $arr['lead'] = array(
+                'name' => 'unknown',
+                'user' => 'unknown',
+                'email' => 'noleadmaintainer@example.com',
+                'active' => 'no',
+            );
+        }
+
+        if (count($arr['lead']) == 1) {
+            $arr['lead'] = $arr['lead'][0];
+        }
+
+        foreach ($maintainers as $maintainer) {
+            if ($maintainer['role'] == 'lead') {
+                continue;
+            }
+            $new = array(
+                'name' => $maintainer['name'],
+                'user' => $maintainer['handle'],
+                'email' => $maintainer['email'],
+                'active' => 'yes',
+            );
+            $arr[$maintainer['role']][] = $new;
+        }
+
+        if (isset($arr['developer']) && count($arr['developer']) == 1) {
+            $arr['developer'] = $arr['developer'][0];
+        }
+
+        if (isset($arr['contributor']) && count($arr['contributor']) == 1) {
+            $arr['contributor'] = $arr['contributor'][0];
+        }
+
+        if (isset($arr['helper']) && count($arr['helper']) == 1) {
+            $arr['helper'] = $arr['helper'][0];
+        }
+
+        $arr['date'] = $this->_packagefile->getDate();
+        $arr['version'] =
+            array(
+                'release' => $this->_packagefile->getVersion(),
+                'api' => $this->_packagefile->getVersion(),
+            );
+        $arr['stability'] =
+            array(
+                'release' => $this->_packagefile->getState(),
+                'api' => $this->_packagefile->getState(),
+            );
+        $licensemap =
+            array(
+                'php' => 'http://www.php.net/license',
+                'php license' => 'http://www.php.net/license',
+                'lgpl' => 'http://www.gnu.org/copyleft/lesser.html',
+                'bsd' => 'http://www.opensource.org/licenses/bsd-license.php',
+                'bsd style' => 'http://www.opensource.org/licenses/bsd-license.php',
+                'bsd-style' => 'http://www.opensource.org/licenses/bsd-license.php',
+                'mit' => 'http://www.opensource.org/licenses/mit-license.php',
+                'gpl' => 'http://www.gnu.org/copyleft/gpl.html',
+                'apache' => 'http://www.opensource.org/licenses/apache2.0.php'
+            );
+
+        if (isset($licensemap[strtolower($this->_packagefile->getLicense())])) {
+            $arr['license'] = array(
+                'attribs' => array('uri' =>
+                    $licensemap[strtolower($this->_packagefile->getLicense())]),
+                '_content' => $this->_packagefile->getLicense()
+                );
+        } else {
+            // don't use bogus uri
+            $arr['license'] = $this->_packagefile->getLicense();
+        }
+
+        $arr['notes'] = $this->_packagefile->getNotes();
+        $temp = array();
+        $arr['contents'] = $this->_convertFilelist2_0($temp);
+        $this->_convertDependencies2_0($arr);
+        $release = ($this->_packagefile->getConfigureOptions() || $this->_isExtension) ?
+            'extsrcrelease' : 'phprelease';
+        if ($release == 'extsrcrelease') {
+            $arr['channel'] = 'pecl.php.net';
+            $arr['providesextension'] = $arr['name']; // assumption
+        }
+
+        $arr[$release] = array();
+        if ($this->_packagefile->getConfigureOptions()) {
+            $arr[$release]['configureoption'] = $this->_packagefile->getConfigureOptions();
+            foreach ($arr[$release]['configureoption'] as $i => $opt) {
+                $arr[$release]['configureoption'][$i] = array('attribs' => $opt);
+            }
+            if (count($arr[$release]['configureoption']) == 1) {
+                $arr[$release]['configureoption'] = $arr[$release]['configureoption'][0];
+            }
+        }
+
+        $this->_convertRelease2_0($arr[$release], $temp);
+        if ($release == 'extsrcrelease' && count($arr[$release]) > 1) {
+            // multiple extsrcrelease tags added in PEAR 1.4.1
+            $arr['dependencies']['required']['pearinstaller']['min'] = '1.4.1';
+        }
+
+        if ($cl = $this->_packagefile->getChangelog()) {
+            foreach ($cl as $release) {
+                $rel = array();
+                $rel['version'] =
+                    array(
+                        'release' => $release['version'],
+                        'api' => $release['version'],
+                    );
+                if (!isset($release['release_state'])) {
+                    $release['release_state'] = 'stable';
+                }
+
+                $rel['stability'] =
+                    array(
+                        'release' => $release['release_state'],
+                        'api' => $release['release_state'],
+                    );
+                if (isset($release['release_date'])) {
+                    $rel['date'] = $release['release_date'];
+                } else {
+                    $rel['date'] = date('Y-m-d');
+                }
+
+                if (isset($release['release_license'])) {
+                    if (isset($licensemap[strtolower($release['release_license'])])) {
+                        $uri = $licensemap[strtolower($release['release_license'])];
+                    } else {
+                        $uri = 'http://www.example.com';
+                    }
+                    $rel['license'] = array(
+                            'attribs' => array('uri' => $uri),
+                            '_content' => $release['release_license']
+                        );
+                } else {
+                    $rel['license'] = $arr['license'];
+                }
+
+                if (!isset($release['release_notes'])) {
+                    $release['release_notes'] = 'no release notes';
+                }
+
+                $rel['notes'] = $release['release_notes'];
+                $arr['changelog']['release'][] = $rel;
+            }
+        }
+
+        $ret = new $class;
+        $ret->setConfig($this->_packagefile->_config);
+        if (isset($this->_packagefile->_logger) && is_object($this->_packagefile->_logger)) {
+            $ret->setLogger($this->_packagefile->_logger);
+        }
+
+        $ret->fromArray($arr);
+        return $ret;
+    }
+
+    /**
+     * @param array
+     * @param bool
+     * @access private
+     */
+    function _convertDependencies2_0(&$release, $internal = false)
+    {
+        $peardep = array('pearinstaller' =>
+            array('min' => '1.4.0b1')); // this is a lot safer
+        $required = $optional = array();
+        $release['dependencies'] = array('required' => array());
+        if ($this->_packagefile->hasDeps()) {
+            foreach ($this->_packagefile->getDeps() as $dep) {
+                if (!isset($dep['optional']) || $dep['optional'] == 'no') {
+                    $required[] = $dep;
+                } else {
+                    $optional[] = $dep;
+                }
+            }
+            foreach (array('required', 'optional') as $arr) {
+                $deps = array();
+                foreach ($$arr as $dep) {
+                    // organize deps by dependency type and name
+                    if (!isset($deps[$dep['type']])) {
+                        $deps[$dep['type']] = array();
+                    }
+                    if (isset($dep['name'])) {
+                        $deps[$dep['type']][$dep['name']][] = $dep;
+                    } else {
+                        $deps[$dep['type']][] = $dep;
+                    }
+                }
+                do {
+                    if (isset($deps['php'])) {
+                        $php = array();
+                        if (count($deps['php']) > 1) {
+                            $php = $this->_processPhpDeps($deps['php']);
+                        } else {
+                            if (!isset($deps['php'][0])) {
+                                list($key, $blah) = each ($deps['php']); // stupid buggy versions
+                                $deps['php'] = array($blah[0]);
+                            }
+                            $php = $this->_processDep($deps['php'][0]);
+                            if (!$php) {
+                                break; // poor mans throw
+                            }
+                        }
+                        $release['dependencies'][$arr]['php'] = $php;
+                    }
+                } while (false);
+                do {
+                    if (isset($deps['pkg'])) {
+                        $pkg = array();
+                        $pkg = $this->_processMultipleDepsName($deps['pkg']);
+                        if (!$pkg) {
+                            break; // poor mans throw
+                        }
+                        $release['dependencies'][$arr]['package'] = $pkg;
+                    }
+                } while (false);
+                do {
+                    if (isset($deps['ext'])) {
+                        $pkg = array();
+                        $pkg = $this->_processMultipleDepsName($deps['ext']);
+                        $release['dependencies'][$arr]['extension'] = $pkg;
+                    }
+                } while (false);
+                // skip sapi - it's not supported so nobody will have used it
+                // skip os - it's not supported in 1.0
+            }
+        }
+        if (isset($release['dependencies']['required'])) {
+            $release['dependencies']['required'] =
+                array_merge($peardep, $release['dependencies']['required']);
+        } else {
+            $release['dependencies']['required'] = $peardep;
+        }
+        if (!isset($release['dependencies']['required']['php'])) {
+            $release['dependencies']['required']['php'] =
+                array('min' => '4.0.0');
+        }
+        $order = array();
+        $bewm = $release['dependencies']['required'];
+        $order['php'] = $bewm['php'];
+        $order['pearinstaller'] = $bewm['pearinstaller'];
+        isset($bewm['package']) ? $order['package'] = $bewm['package'] :0;
+        isset($bewm['extension']) ? $order['extension'] = $bewm['extension'] :0;
+        $release['dependencies']['required'] = $order;
+    }
+
+    /**
+     * @param array
+     * @access private
+     */
+    function _convertFilelist2_0(&$package)
+    {
+        $ret = array('dir' =>
+                    array(
+                        'attribs' => array('name' => '/'),
+                        'file' => array()
+                        )
+                    );
+        $package['platform'] =
+        $package['install-as'] = array();
+        $this->_isExtension = false;
+        foreach ($this->_packagefile->getFilelist() as $name => $file) {
+            $file['name'] = $name;
+            if (isset($file['role']) && $file['role'] == 'src') {
+                $this->_isExtension = true;
+            }
+            if (isset($file['replacements'])) {
+                $repl = $file['replacements'];
+                unset($file['replacements']);
+            } else {
+                unset($repl);
+            }
+            if (isset($file['install-as'])) {
+                $package['install-as'][$name] = $file['install-as'];
+                unset($file['install-as']);
+            }
+            if (isset($file['platform'])) {
+                $package['platform'][$name] = $file['platform'];
+                unset($file['platform']);
+            }
+            $file = array('attribs' => $file);
+            if (isset($repl)) {
+                foreach ($repl as $replace ) {
+                    $file['tasks:replace'][] = array('attribs' => $replace);
+                }
+                if (count($repl) == 1) {
+                    $file['tasks:replace'] = $file['tasks:replace'][0];
+                }
+            }
+            $ret['dir']['file'][] = $file;
+        }
+        return $ret;
+    }
+
+    /**
+     * Post-process special files with install-as/platform attributes and
+     * make the release tag.
+     *
+     * This complex method follows this work-flow to create the release tags:
+     *
+     * <pre>
+     * - if any install-as/platform exist, create a generic release and fill it with
+     *   o <install as=..> tags for <file name=... install-as=...>
+     *   o <install as=..> tags for <file name=... platform=!... install-as=..>
+     *   o <ignore> tags for <file name=... platform=...>
+     *   o <ignore> tags for <file name=... platform=... install-as=..>
+     * - create a release for each platform encountered and fill with
+     *   o <install as..> tags for <file name=... install-as=...>
+     *   o <install as..> tags for <file name=... platform=this platform install-as=..>
+     *   o <install as..> tags for <file name=... platform=!other platform install-as=..>
+     *   o <ignore> tags for <file name=... platform=!this platform>
+     *   o <ignore> tags for <file name=... platform=other platform>
+     *   o <ignore> tags for <file name=... platform=other platform install-as=..>
+     *   o <ignore> tags for <file name=... platform=!this platform install-as=..>
+     * </pre>
+     *
+     * It does this by accessing the $package parameter, which contains an array with
+     * indices:
+     *
+     *  - platform: mapping of file => OS the file should be installed on
+     *  - install-as: mapping of file => installed name
+     *  - osmap: mapping of OS => list of files that should be installed
+     *    on that OS
+     *  - notosmap: mapping of OS => list of files that should not be
+     *    installed on that OS
+     *
+     * @param array
+     * @param array
+     * @access private
+     */
+    function _convertRelease2_0(&$release, $package)
+    {
+        //- if any install-as/platform exist, create a generic release and fill it with
+        if (count($package['platform']) || count($package['install-as'])) {
+            $generic = array();
+            $genericIgnore = array();
+            foreach ($package['install-as'] as $file => $as) {
+                //o <install as=..> tags for <file name=... install-as=...>
+                if (!isset($package['platform'][$file])) {
+                    $generic[] = $file;
+                    continue;
+                }
+                //o <install as=..> tags for <file name=... platform=!... install-as=..>
+                if (isset($package['platform'][$file]) &&
+                      $package['platform'][$file]{0} == '!') {
+                    $generic[] = $file;
+                    continue;
+                }
+                //o <ignore> tags for <file name=... platform=... install-as=..>
+                if (isset($package['platform'][$file]) &&
+                      $package['platform'][$file]{0} != '!') {
+                    $genericIgnore[] = $file;
+                    continue;
+                }
+            }
+            foreach ($package['platform'] as $file => $platform) {
+                if (isset($package['install-as'][$file])) {
+                    continue;
+                }
+                if ($platform{0} != '!') {
+                    //o <ignore> tags for <file name=... platform=...>
+                    $genericIgnore[] = $file;
+                }
+            }
+            if (count($package['platform'])) {
+                $oses = $notplatform = $platform = array();
+                foreach ($package['platform'] as $file => $os) {
+                    // get a list of oses
+                    if ($os{0} == '!') {
+                        if (isset($oses[substr($os, 1)])) {
+                            continue;
+                        }
+                        $oses[substr($os, 1)] = count($oses);
+                    } else {
+                        if (isset($oses[$os])) {
+                            continue;
+                        }
+                        $oses[$os] = count($oses);
+                    }
+                }
+                //- create a release for each platform encountered and fill with
+                foreach ($oses as $os => $releaseNum) {
+                    $release[$releaseNum]['installconditions']['os']['name'] = $os;
+                    $release[$releaseNum]['filelist'] = array('install' => array(),
+                        'ignore' => array());
+                    foreach ($package['install-as'] as $file => $as) {
+                        //o <install as=..> tags for <file name=... install-as=...>
+                        if (!isset($package['platform'][$file])) {
+                            $release[$releaseNum]['filelist']['install'][] =
+                                array(
+                                    'attribs' => array(
+                                        'name' => $file,
+                                        'as' => $as,
+                                    ),
+                                );
+                            continue;
+                        }
+                        //o <install as..> tags for
+                        //  <file name=... platform=this platform install-as=..>
+                        if (isset($package['platform'][$file]) &&
+                              $package['platform'][$file] == $os) {
+                            $release[$releaseNum]['filelist']['install'][] =
+                                array(
+                                    'attribs' => array(
+                                        'name' => $file,
+                                        'as' => $as,
+                                    ),
+                                );
+                            continue;
+                        }
+                        //o <install as..> tags for
+                        //  <file name=... platform=!other platform install-as=..>
+                        if (isset($package['platform'][$file]) &&
+                              $package['platform'][$file] != "!$os" &&
+                              $package['platform'][$file]{0} == '!') {
+                            $release[$releaseNum]['filelist']['install'][] =
+                                array(
+                                    'attribs' => array(
+                                        'name' => $file,
+                                        'as' => $as,
+                                    ),
+                                );
+                            continue;
+                        }
+                        //o <ignore> tags for
+                        //  <file name=... platform=!this platform install-as=..>
+                        if (isset($package['platform'][$file]) &&
+                              $package['platform'][$file] == "!$os") {
+                            $release[$releaseNum]['filelist']['ignore'][] =
+                                array(
+                                    'attribs' => array(
+                                        'name' => $file,
+                                    ),
+                                );
+                            continue;
+                        }
+                        //o <ignore> tags for
+                        //  <file name=... platform=other platform install-as=..>
+                        if (isset($package['platform'][$file]) &&
+                              $package['platform'][$file]{0} != '!' &&
+                              $package['platform'][$file] != $os) {
+                            $release[$releaseNum]['filelist']['ignore'][] =
+                                array(
+                                    'attribs' => array(
+                                        'name' => $file,
+                                    ),
+                                );
+                            continue;
+                        }
+                    }
+                    foreach ($package['platform'] as $file => $platform) {
+                        if (isset($package['install-as'][$file])) {
+                            continue;
+                        }
+                        //o <ignore> tags for <file name=... platform=!this platform>
+                        if ($platform == "!$os") {
+                            $release[$releaseNum]['filelist']['ignore'][] =
+                                array(
+                                    'attribs' => array(
+                                        'name' => $file,
+                                    ),
+                                );
+                            continue;
+                        }
+                        //o <ignore> tags for <file name=... platform=other platform>
+                        if ($platform{0} != '!' && $platform != $os) {
+                            $release[$releaseNum]['filelist']['ignore'][] =
+                                array(
+                                    'attribs' => array(
+                                        'name' => $file,
+                                    ),
+                                );
+                        }
+                    }
+                    if (!count($release[$releaseNum]['filelist']['install'])) {
+                        unset($release[$releaseNum]['filelist']['install']);
+                    }
+                    if (!count($release[$releaseNum]['filelist']['ignore'])) {
+                        unset($release[$releaseNum]['filelist']['ignore']);
+                    }
+                }
+                if (count($generic) || count($genericIgnore)) {
+                    $release[count($oses)] = array();
+                    if (count($generic)) {
+                        foreach ($generic as $file) {
+                            if (isset($package['install-as'][$file])) {
+                                $installas = $package['install-as'][$file];
+                            } else {
+                                $installas = $file;
+                            }
+                            $release[count($oses)]['filelist']['install'][] =
+                                array(
+                                    'attribs' => array(
+                                        'name' => $file,
+                                        'as' => $installas,
+                                    )
+                                );
+                        }
+                    }
+                    if (count($genericIgnore)) {
+                        foreach ($genericIgnore as $file) {
+                            $release[count($oses)]['filelist']['ignore'][] =
+                                array(
+                                    'attribs' => array(
+                                        'name' => $file,
+                                    )
+                                );
+                        }
+                    }
+                }
+                // cleanup
+                foreach ($release as $i => $rel) {
+                    if (isset($rel['filelist']['install']) &&
+                          count($rel['filelist']['install']) == 1) {
+                        $release[$i]['filelist']['install'] =
+                            $release[$i]['filelist']['install'][0];
+                    }
+                    if (isset($rel['filelist']['ignore']) &&
+                          count($rel['filelist']['ignore']) == 1) {
+                        $release[$i]['filelist']['ignore'] =
+                            $release[$i]['filelist']['ignore'][0];
+                    }
+                }
+                if (count($release) == 1) {
+                    $release = $release[0];
+                }
+            } else {
+                // no platform atts, but some install-as atts
+                foreach ($package['install-as'] as $file => $value) {
+                    $release['filelist']['install'][] =
+                        array(
+                            'attribs' => array(
+                                'name' => $file,
+                                'as' => $value
+                            )
+                        );
+                }
+                if (count($release['filelist']['install']) == 1) {
+                    $release['filelist']['install'] = $release['filelist']['install'][0];
+                }
+            }
+        }
+    }
+
+    /**
+     * @param array
+     * @return array
+     * @access private
+     */
+    function _processDep($dep)
+    {
+        if ($dep['type'] == 'php') {
+            if ($dep['rel'] == 'has') {
+                // come on - everyone has php!
+                return false;
+            }
+        }
+        $php = array();
+        if ($dep['type'] != 'php') {
+            $php['name'] = $dep['name'];
+            if ($dep['type'] == 'pkg') {
+                $php['channel'] = 'pear.php.net';
+            }
+        }
+        switch ($dep['rel']) {
+            case 'gt' :
+                $php['min'] = $dep['version'];
+                $php['exclude'] = $dep['version'];
+            break;
+            case 'ge' :
+                if (!isset($dep['version'])) {
+                    if ($dep['type'] == 'php') {
+                        if (isset($dep['name'])) {
+                            $dep['version'] = $dep['name'];
+                        }
+                    }
+                }
+                $php['min'] = $dep['version'];
+            break;
+            case 'lt' :
+                $php['max'] = $dep['version'];
+                $php['exclude'] = $dep['version'];
+            break;
+            case 'le' :
+                $php['max'] = $dep['version'];
+            break;
+            case 'eq' :
+                $php['min'] = $dep['version'];
+                $php['max'] = $dep['version'];
+            break;
+            case 'ne' :
+                $php['exclude'] = $dep['version'];
+            break;
+            case 'not' :
+                $php['conflicts'] = 'yes';
+            break;
+        }
+        return $php;
+    }
+
+    /**
+     * @param array
+     * @return array
+     */
+    function _processPhpDeps($deps)
+    {
+        $test = array();
+        foreach ($deps as $dep) {
+            $test[] = $this->_processDep($dep);
+        }
+        $min = array();
+        $max = array();
+        foreach ($test as $dep) {
+            if (!$dep) {
+                continue;
+            }
+            if (isset($dep['min'])) {
+                $min[$dep['min']] = count($min);
+            }
+            if (isset($dep['max'])) {
+                $max[$dep['max']] = count($max);
+            }
+        }
+        if (count($min) > 0) {
+            uksort($min, 'version_compare');
+        }
+        if (count($max) > 0) {
+            uksort($max, 'version_compare');
+        }
+        if (count($min)) {
+            // get the highest minimum
+            $min = array_pop($a = array_flip($min));
+        } else {
+            $min = false;
+        }
+        if (count($max)) {
+            // get the lowest maximum
+            $max = array_shift($a = array_flip($max));
+        } else {
+            $max = false;
+        }
+        if ($min) {
+            $php['min'] = $min;
+        }
+        if ($max) {
+            $php['max'] = $max;
+        }
+        $exclude = array();
+        foreach ($test as $dep) {
+            if (!isset($dep['exclude'])) {
+                continue;
+            }
+            $exclude[] = $dep['exclude'];
+        }
+        if (count($exclude)) {
+            $php['exclude'] = $exclude;
+        }
+        return $php;
+    }
+
+    /**
+     * process multiple dependencies that have a name, like package deps
+     * @param array
+     * @return array
+     * @access private
+     */
+    function _processMultipleDepsName($deps)
+    {
+        $ret = $tests = array();
+        foreach ($deps as $name => $dep) {
+            foreach ($dep as $d) {
+                $tests[$name][] = $this->_processDep($d);
+            }
+        }
+
+        foreach ($tests as $name => $test) {
+            $max = $min = $php = array();
+            $php['name'] = $name;
+            foreach ($test as $dep) {
+                if (!$dep) {
+                    continue;
+                }
+                if (isset($dep['channel'])) {
+                    $php['channel'] = 'pear.php.net';
+                }
+                if (isset($dep['conflicts']) && $dep['conflicts'] == 'yes') {
+                    $php['conflicts'] = 'yes';
+                }
+                if (isset($dep['min'])) {
+                    $min[$dep['min']] = count($min);
+                }
+                if (isset($dep['max'])) {
+                    $max[$dep['max']] = count($max);
+                }
+            }
+            if (count($min) > 0) {
+                uksort($min, 'version_compare');
+            }
+            if (count($max) > 0) {
+                uksort($max, 'version_compare');
+            }
+            if (count($min)) {
+                // get the highest minimum
+                $min = array_pop($a = array_flip($min));
+            } else {
+                $min = false;
+            }
+            if (count($max)) {
+                // get the lowest maximum
+                $max = array_shift($a = array_flip($max));
+            } else {
+                $max = false;
+            }
+            if ($min) {
+                $php['min'] = $min;
+            }
+            if ($max) {
+                $php['max'] = $max;
+            }
+            $exclude = array();
+            foreach ($test as $dep) {
+                if (!isset($dep['exclude'])) {
+                    continue;
+                }
+                $exclude[] = $dep['exclude'];
+            }
+            if (count($exclude)) {
+                $php['exclude'] = $exclude;
+            }
+            $ret[] = $php;
+        }
+        return $ret;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/PackageFile/Generator/v2.php b/lib/php/PEAR/PackageFile/Generator/v2.php
new file mode 100644
index 00000000..d0a2df94
--- /dev/null
+++ b/lib/php/PEAR/PackageFile/Generator/v2.php
@@ -0,0 +1,893 @@
+<?php
+/**
+ * package.xml generation class, package.xml version 2.0
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @author     Stephan Schmidt (original XML_Serializer code)
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: v2.php 278907 2009-04-17 21:10:04Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * file/dir manipulation routines
+ */
+require_once 'System.php';
+require_once 'XML/Util.php';
+
+/**
+ * This class converts a PEAR_PackageFile_v2 object into any output format.
+ *
+ * Supported output formats include array, XML string (using S. Schmidt's
+ * XML_Serializer, slightly customized)
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @author     Stephan Schmidt (original XML_Serializer code)
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_PackageFile_Generator_v2
+{
+   /**
+    * default options for the serialization
+    * @access private
+    * @var array $_defaultOptions
+    */
+    var $_defaultOptions = array(
+        'indent'             => ' ',                    // string used for indentation
+        'linebreak'          => "\n",                  // string used for newlines
+        'typeHints'          => false,                 // automatically add type hin attributes
+        'addDecl'            => true,                 // add an XML declaration
+        'defaultTagName'     => 'XML_Serializer_Tag',  // tag used for indexed arrays or invalid names
+        'classAsTagName'     => false,                 // use classname for objects in indexed arrays
+        'keyAttribute'       => '_originalKey',        // attribute where original key is stored
+        'typeAttribute'      => '_type',               // attribute for type (only if typeHints => true)
+        'classAttribute'     => '_class',              // attribute for class of objects (only if typeHints => true)
+        'scalarAsAttributes' => false,                 // scalar values (strings, ints,..) will be serialized as attribute
+        'prependAttributes'  => '',                    // prepend string for attributes
+        'indentAttributes'   => false,                 // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column
+        'mode'               => 'simplexml',             // use 'simplexml' to use parent name as tagname if transforming an indexed array
+        'addDoctype'         => false,                 // add a doctype declaration
+        'doctype'            => null,                  // supply a string or an array with id and uri ({@see XML_Util::getDoctypeDeclaration()}
+        'rootName'           => 'package',                  // name of the root tag
+        'rootAttributes'     => array(
+            'version' => '2.0',
+            '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',
+            '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',
+        ),               // attributes of the root tag
+        'attributesArray'    => 'attribs',                  // all values in this key will be treated as attributes
+        'contentName'        => '_content',                   // this value will be used directly as content, instead of creating a new tag, may only be used in conjuction with attributesArray
+        'beautifyFilelist'   => false,
+        'encoding' => 'UTF-8',
+    );
+
+   /**
+    * options for the serialization
+    * @access private
+    * @var array $options
+    */
+    var $options = array();
+
+   /**
+    * current tag depth
+    * @var integer $_tagDepth
+    */
+    var $_tagDepth = 0;
+
+   /**
+    * serilialized representation of the data
+    * @var string $_serializedData
+    */
+    var $_serializedData = null;
+    /**
+     * @var PEAR_PackageFile_v2
+     */
+    var $_packagefile;
+    /**
+     * @param PEAR_PackageFile_v2
+     */
+    function PEAR_PackageFile_Generator_v2(&$packagefile)
+    {
+        $this->_packagefile = &$packagefile;
+        if (isset($this->_packagefile->encoding)) {
+            $this->_defaultOptions['encoding'] = $this->_packagefile->encoding;
+        }
+    }
+
+    /**
+     * @return string
+     */
+    function getPackagerVersion()
+    {
+        return '1.9.0';
+    }
+
+    /**
+     * @param PEAR_Packager
+     * @param bool generate a .tgz or a .tar
+     * @param string|null temporary directory to package in
+     */
+    function toTgz(&$packager, $compress = true, $where = null)
+    {
+        $a = null;
+        return $this->toTgz2($packager, $a, $compress, $where);
+    }
+
+    /**
+     * Package up both a package.xml and package2.xml for the same release
+     * @param PEAR_Packager
+     * @param PEAR_PackageFile_v1
+     * @param bool generate a .tgz or a .tar
+     * @param string|null temporary directory to package in
+     */
+    function toTgz2(&$packager, &$pf1, $compress = true, $where = null)
+    {
+        require_once 'Archive/Tar.php';
+        if (!$this->_packagefile->isEquivalent($pf1)) {
+            return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' .
+                basename($pf1->getPackageFile()) .
+                '" is not equivalent to "' . basename($this->_packagefile->getPackageFile())
+                . '"');
+        }
+
+        if ($where === null) {
+            if (!($where = System::mktemp(array('-d')))) {
+                return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: mktemp failed');
+            }
+        } elseif (!@System::mkDir(array('-p', $where))) {
+            return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . $where . '" could' .
+                ' not be created');
+        }
+
+        $file = $where . DIRECTORY_SEPARATOR . 'package.xml';
+        if (file_exists($file) && !is_file($file)) {
+            return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' .
+                ' "' . $file  .'"');
+        }
+
+        if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) {
+            return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: invalid package.xml');
+        }
+
+        $ext = $compress ? '.tgz' : '.tar';
+        $pkgver = $this->_packagefile->getPackage() . '-' . $this->_packagefile->getVersion();
+        $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext;
+        if (file_exists($dest_package) && !is_file($dest_package)) {
+            return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' .
+                $dest_package . '"');
+        }
+
+        $pkgfile = $this->_packagefile->getPackageFile();
+        if (!$pkgfile) {
+            return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' .
+                'be created from a real file');
+        }
+
+        $pkgdir  = dirname(realpath($pkgfile));
+        $pkgfile = basename($pkgfile);
+
+        // {{{ Create the package file list
+        $filelist = array();
+        $i = 0;
+        $this->_packagefile->flattenFilelist();
+        $contents = $this->_packagefile->getContents();
+        if (isset($contents['bundledpackage'])) { // bundles of packages
+            $contents = $contents['bundledpackage'];
+            if (!isset($contents[0])) {
+                $contents = array($contents);
+            }
+
+            $packageDir = $where;
+            foreach ($contents as $i => $package) {
+                $fname = $package;
+                $file = $pkgdir . DIRECTORY_SEPARATOR . $fname;
+                if (!file_exists($file)) {
+                    return $packager->raiseError("File does not exist: $fname");
+                }
+
+                $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname;
+                System::mkdir(array('-p', dirname($tfile)));
+                copy($file, $tfile);
+                $filelist[$i++] = $tfile;
+                $packager->log(2, "Adding package $fname");
+            }
+        } else { // normal packages
+            $contents = $contents['dir']['file'];
+            if (!isset($contents[0])) {
+                $contents = array($contents);
+            }
+
+            $packageDir = $where;
+            foreach ($contents as $i => $file) {
+                $fname = $file['attribs']['name'];
+                $atts = $file['attribs'];
+                $orig = $file;
+                $file = $pkgdir . DIRECTORY_SEPARATOR . $fname;
+                if (!file_exists($file)) {
+                    return $packager->raiseError("File does not exist: $fname");
+                }
+
+                $origperms = fileperms($file);
+                $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname;
+                unset($orig['attribs']);
+                if (count($orig)) { // file with tasks
+                    // run any package-time tasks
+                    $contents = file_get_contents($file);
+                    foreach ($orig as $tag => $raw) {
+                        $tag = str_replace(
+                            array($this->_packagefile->getTasksNs() . ':', '-'),
+                            array('', '_'), $tag);
+                        $task = "PEAR_Task_$tag";
+                        $task = &new $task($this->_packagefile->_config,
+                            $this->_packagefile->_logger,
+                            PEAR_TASK_PACKAGE);
+                        $task->init($raw, $atts, null);
+                        $res = $task->startSession($this->_packagefile, $contents, $tfile);
+                        if (!$res) {
+                            continue; // skip this task
+                        }
+
+                        if (PEAR::isError($res)) {
+                            return $res;
+                        }
+
+                        $contents = $res; // save changes
+                        System::mkdir(array('-p', dirname($tfile)));
+                        $wp = fopen($tfile, "wb");
+                        fwrite($wp, $contents);
+                        fclose($wp);
+                    }
+                }
+
+                if (!file_exists($tfile)) {
+                    System::mkdir(array('-p', dirname($tfile)));
+                    copy($file, $tfile);
+                }
+
+                chmod($tfile, $origperms);
+                $filelist[$i++] = $tfile;
+                $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1);
+                $packager->log(2, "Adding file $fname");
+            }
+        }
+            // }}}
+
+        $name       = $pf1 !== null ? 'package2.xml' : 'package.xml';
+        $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, $name);
+        if ($packagexml) {
+            $tar =& new Archive_Tar($dest_package, $compress);
+            $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors
+            // ----- Creates with the package.xml file
+            $ok = $tar->createModify(array($packagexml), '', $where);
+            if (PEAR::isError($ok)) {
+                return $packager->raiseError($ok);
+            } elseif (!$ok) {
+                return $packager->raiseError('PEAR_Packagefile_v2::toTgz(): adding ' . $name .
+                    ' failed');
+            }
+
+            // ----- Add the content of the package
+            if (!$tar->addModify($filelist, $pkgver, $where)) {
+                return $packager->raiseError(
+                    'PEAR_Packagefile_v2::toTgz(): tarball creation failed');
+            }
+
+            // add the package.xml version 1.0
+            if ($pf1 !== null) {
+                $pfgen = &$pf1->getDefaultGenerator();
+                $packagexml1 = $pfgen->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true);
+                if (!$tar->addModify(array($packagexml1), '', $where)) {
+                    return $packager->raiseError(
+                        'PEAR_Packagefile_v2::toTgz(): adding package.xml failed');
+                }
+            }
+
+            return $dest_package;
+        }
+    }
+
+    function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml')
+    {
+        if (!$this->_packagefile->validate($state)) {
+            return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml',
+                null, null, null, $this->_packagefile->getValidationWarnings());
+        }
+
+        if ($where === null) {
+            if (!($where = System::mktemp(array('-d')))) {
+                return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed');
+            }
+        } elseif (!@System::mkDir(array('-p', $where))) {
+            return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' .
+                ' not be created');
+        }
+
+        $newpkgfile = $where . DIRECTORY_SEPARATOR . $name;
+        $np = @fopen($newpkgfile, 'wb');
+        if (!$np) {
+            return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' .
+               "$name as $newpkgfile");
+        }
+        fwrite($np, $this->toXml($state));
+        fclose($np);
+        return $newpkgfile;
+    }
+
+    function &toV2()
+    {
+        return $this->_packagefile;
+    }
+
+    /**
+     * Return an XML document based on the package info (as returned
+     * by the PEAR_Common::infoFrom* methods).
+     *
+     * @return string XML data
+     */
+    function toXml($state = PEAR_VALIDATE_NORMAL, $options = array())
+    {
+        $this->_packagefile->setDate(date('Y-m-d'));
+        $this->_packagefile->setTime(date('H:i:s'));
+        if (!$this->_packagefile->validate($state)) {
+            return false;
+        }
+
+        if (is_array($options)) {
+            $this->options = array_merge($this->_defaultOptions, $options);
+        } else {
+            $this->options = $this->_defaultOptions;
+        }
+
+        $arr = $this->_packagefile->getArray();
+        if (isset($arr['filelist'])) {
+            unset($arr['filelist']);
+        }
+
+        if (isset($arr['_lastversion'])) {
+            unset($arr['_lastversion']);
+        }
+
+        // Fix the notes a little bit
+        if (isset($arr['notes'])) {
+            // This trims out the indenting, needs fixing
+            $arr['notes'] = "\n" . trim($arr['notes']) . "\n";
+        }
+
+        if (isset($arr['changelog']) && !empty($arr['changelog'])) {
+            // Fix for inconsistency how the array is filled depending on the changelog release amount
+            if (!isset($arr['changelog']['release'][0])) {
+                $release = $arr['changelog']['release'];
+                unset($arr['changelog']['release']);
+
+                $arr['changelog']['release']    = array();
+                $arr['changelog']['release'][0] = $release;
+            }
+
+            foreach (array_keys($arr['changelog']['release']) as $key) {
+                $c =& $arr['changelog']['release'][$key];
+                if (isset($c['notes'])) {
+                    // This trims out the indenting, needs fixing
+                    $c['notes'] = "\n" . trim($c['notes']) . "\n";
+                }
+            }
+        }
+
+        if ($state ^ PEAR_VALIDATE_PACKAGING && !isset($arr['bundle'])) {
+            $use = $this->_recursiveXmlFilelist($arr['contents']['dir']['file']);
+            unset($arr['contents']['dir']['file']);
+            if (isset($use['dir'])) {
+                $arr['contents']['dir']['dir'] = $use['dir'];
+            }
+            if (isset($use['file'])) {
+                $arr['contents']['dir']['file'] = $use['file'];
+            }
+            $this->options['beautifyFilelist'] = true;
+        }
+
+        $arr['attribs']['packagerversion'] = '1.9.0';
+        if ($this->serialize($arr, $options)) {
+            return $this->_serializedData . "\n";
+        }
+
+        return false;
+    }
+
+
+    function _recursiveXmlFilelist($list)
+    {
+        $dirs = array();
+        if (isset($list['attribs'])) {
+            $file = $list['attribs']['name'];
+            unset($list['attribs']['name']);
+            $attributes = $list['attribs'];
+            $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes);
+        } else {
+            foreach ($list as $a) {
+                $file = $a['attribs']['name'];
+                $attributes = $a['attribs'];
+                unset($a['attribs']);
+                $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes, $a);
+            }
+        }
+        $this->_formatDir($dirs);
+        $this->_deFormat($dirs);
+        return $dirs;
+    }
+
+    function _addDir(&$dirs, $dir, $file = null, $attributes = null, $tasks = null)
+    {
+        if (!$tasks) {
+            $tasks = array();
+        }
+        if ($dir == array() || $dir == array('.')) {
+            $dirs['file'][basename($file)] = $tasks;
+            $attributes['name'] = basename($file);
+            $dirs['file'][basename($file)]['attribs'] = $attributes;
+            return;
+        }
+        $curdir = array_shift($dir);
+        if (!isset($dirs['dir'][$curdir])) {
+            $dirs['dir'][$curdir] = array();
+        }
+        $this->_addDir($dirs['dir'][$curdir], $dir, $file, $attributes, $tasks);
+    }
+
+    function _formatDir(&$dirs)
+    {
+        if (!count($dirs)) {
+            return array();
+        }
+        $newdirs = array();
+        if (isset($dirs['dir'])) {
+            $newdirs['dir'] = $dirs['dir'];
+        }
+        if (isset($dirs['file'])) {
+            $newdirs['file'] = $dirs['file'];
+        }
+        $dirs = $newdirs;
+        if (isset($dirs['dir'])) {
+            uksort($dirs['dir'], 'strnatcasecmp');
+            foreach ($dirs['dir'] as $dir => $contents) {
+                $this->_formatDir($dirs['dir'][$dir]);
+            }
+        }
+        if (isset($dirs['file'])) {
+            uksort($dirs['file'], 'strnatcasecmp');
+        };
+    }
+
+    function _deFormat(&$dirs)
+    {
+        if (!count($dirs)) {
+            return array();
+        }
+        $newdirs = array();
+        if (isset($dirs['dir'])) {
+            foreach ($dirs['dir'] as $dir => $contents) {
+                $newdir = array();
+                $newdir['attribs']['name'] = $dir;
+                $this->_deFormat($contents);
+                foreach ($contents as $tag => $val) {
+                    $newdir[$tag] = $val;
+                }
+                $newdirs['dir'][] = $newdir;
+            }
+            if (count($newdirs['dir']) == 1) {
+                $newdirs['dir'] = $newdirs['dir'][0];
+            }
+        }
+        if (isset($dirs['file'])) {
+            foreach ($dirs['file'] as $name => $file) {
+                $newdirs['file'][] = $file;
+            }
+            if (count($newdirs['file']) == 1) {
+                $newdirs['file'] = $newdirs['file'][0];
+            }
+        }
+        $dirs = $newdirs;
+    }
+
+    /**
+    * reset all options to default options
+    *
+    * @access   public
+    * @see      setOption(), XML_Unserializer()
+    */
+    function resetOptions()
+    {
+        $this->options = $this->_defaultOptions;
+    }
+
+   /**
+    * set an option
+    *
+    * You can use this method if you do not want to set all options in the constructor
+    *
+    * @access   public
+    * @see      resetOption(), XML_Serializer()
+    */
+    function setOption($name, $value)
+    {
+        $this->options[$name] = $value;
+    }
+
+   /**
+    * sets several options at once
+    *
+    * You can use this method if you do not want to set all options in the constructor
+    *
+    * @access   public
+    * @see      resetOption(), XML_Unserializer(), setOption()
+    */
+    function setOptions($options)
+    {
+        $this->options = array_merge($this->options, $options);
+    }
+
+   /**
+    * serialize data
+    *
+    * @access   public
+    * @param    mixed    $data data to serialize
+    * @return   boolean  true on success, pear error on failure
+    */
+    function serialize($data, $options = null)
+    {
+        // if options have been specified, use them instead
+        // of the previously defined ones
+        if (is_array($options)) {
+            $optionsBak = $this->options;
+            if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) {
+                $this->options = array_merge($this->_defaultOptions, $options);
+            } else {
+                $this->options = array_merge($this->options, $options);
+            }
+        } else {
+            $optionsBak = null;
+        }
+
+        //  start depth is zero
+        $this->_tagDepth = 0;
+        $this->_serializedData = '';
+        // serialize an array
+        if (is_array($data)) {
+            $tagName = isset($this->options['rootName']) ? $this->options['rootName'] : 'array';
+            $this->_serializedData .= $this->_serializeArray($data, $tagName, $this->options['rootAttributes']);
+        }
+
+        // add doctype declaration
+        if ($this->options['addDoctype'] === true) {
+            $this->_serializedData = XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype'])
+                                   . $this->options['linebreak']
+                                   . $this->_serializedData;
+        }
+
+        //  build xml declaration
+        if ($this->options['addDecl']) {
+            $atts = array();
+            $encoding = isset($this->options['encoding']) ? $this->options['encoding'] : null;
+            $this->_serializedData = XML_Util::getXMLDeclaration('1.0', $encoding)
+                                   . $this->options['linebreak']
+                                   . $this->_serializedData;
+        }
+
+
+        if ($optionsBak !== null) {
+            $this->options = $optionsBak;
+        }
+
+        return  true;
+    }
+
+   /**
+    * get the result of the serialization
+    *
+    * @access public
+    * @return string serialized XML
+    */
+    function getSerializedData()
+    {
+        if ($this->_serializedData === null) {
+            return  $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.', XML_SERIALIZER_ERROR_NO_SERIALIZATION);
+        }
+        return $this->_serializedData;
+    }
+
+   /**
+    * serialize any value
+    *
+    * This method checks for the type of the value and calls the appropriate method
+    *
+    * @access private
+    * @param  mixed     $value
+    * @param  string    $tagName
+    * @param  array     $attributes
+    * @return string
+    */
+    function _serializeValue($value, $tagName = null, $attributes = array())
+    {
+        if (is_array($value)) {
+            $xml = $this->_serializeArray($value, $tagName, $attributes);
+        } elseif (is_object($value)) {
+            $xml = $this->_serializeObject($value, $tagName);
+        } else {
+            $tag = array(
+                          'qname'      => $tagName,
+                          'attributes' => $attributes,
+                          'content'    => $value
+                        );
+            $xml = $this->_createXMLTag($tag);
+        }
+        return $xml;
+    }
+
+   /**
+    * serialize an array
+    *
+    * @access   private
+    * @param    array   $array       array to serialize
+    * @param    string  $tagName     name of the root tag
+    * @param    array   $attributes  attributes for the root tag
+    * @return   string  $string      serialized data
+    * @uses     XML_Util::isValidName() to check, whether key has to be substituted
+    */
+    function _serializeArray(&$array, $tagName = null, $attributes = array())
+    {
+        $_content = null;
+
+        /**
+         * check for special attributes
+         */
+        if ($this->options['attributesArray'] !== null) {
+            if (isset($array[$this->options['attributesArray']])) {
+                $attributes = $array[$this->options['attributesArray']];
+                unset($array[$this->options['attributesArray']]);
+            }
+            /**
+             * check for special content
+             */
+            if ($this->options['contentName'] !== null) {
+                if (isset($array[$this->options['contentName']])) {
+                    $_content = $array[$this->options['contentName']];
+                    unset($array[$this->options['contentName']]);
+                }
+            }
+        }
+
+        /*
+        * if mode is set to simpleXML, check whether
+        * the array is associative or indexed
+        */
+        if (is_array($array) && $this->options['mode'] == 'simplexml') {
+            $indexed = true;
+            if (!count($array)) {
+                $indexed = false;
+            }
+            foreach ($array as $key => $val) {
+                if (!is_int($key)) {
+                    $indexed = false;
+                    break;
+                }
+            }
+
+            if ($indexed && $this->options['mode'] == 'simplexml') {
+                $string = '';
+                foreach ($array as $key => $val) {
+                    if ($this->options['beautifyFilelist'] && $tagName == 'dir') {
+                        if (!isset($this->_curdir)) {
+                            $this->_curdir = '';
+                        }
+                        $savedir = $this->_curdir;
+                        if (isset($val['attribs'])) {
+                            if ($val['attribs']['name'] == '/') {
+                                $this->_curdir = '/';
+                            } else {
+                                if ($this->_curdir == '/') {
+                                    $this->_curdir = '';
+                                }
+                                $this->_curdir .= '/' . $val['attribs']['name'];
+                            }
+                        }
+                    }
+                    $string .= $this->_serializeValue( $val, $tagName, $attributes);
+                    if ($this->options['beautifyFilelist'] && $tagName == 'dir') {
+                        $string .= ' <!-- ' . $this->_curdir . ' -->';
+                        if (empty($savedir)) {
+                            unset($this->_curdir);
+                        } else {
+                            $this->_curdir = $savedir;
+                        }
+                    }
+
+                    $string .= $this->options['linebreak'];
+                    // do indentation
+                    if ($this->options['indent'] !== null && $this->_tagDepth > 0) {
+                        $string .= str_repeat($this->options['indent'], $this->_tagDepth);
+                    }
+                }
+                return rtrim($string);
+            }
+        }
+
+        if ($this->options['scalarAsAttributes'] === true) {
+            foreach ($array as $key => $value) {
+                if (is_scalar($value) && (XML_Util::isValidName($key) === true)) {
+                    unset($array[$key]);
+                    $attributes[$this->options['prependAttributes'].$key] = $value;
+                }
+            }
+        }
+
+        // check for empty array => create empty tag
+        if (empty($array)) {
+            $tag = array(
+                            'qname'      => $tagName,
+                            'content'    => $_content,
+                            'attributes' => $attributes
+                        );
+
+        } else {
+            $this->_tagDepth++;
+            $tmp = $this->options['linebreak'];
+            foreach ($array as $key => $value) {
+                // do indentation
+                if ($this->options['indent'] !== null && $this->_tagDepth > 0) {
+                    $tmp .= str_repeat($this->options['indent'], $this->_tagDepth);
+                }
+
+                // copy key
+                $origKey = $key;
+                // key cannot be used as tagname => use default tag
+                $valid = XML_Util::isValidName($key);
+                if (PEAR::isError($valid)) {
+                    if ($this->options['classAsTagName'] && is_object($value)) {
+                        $key = get_class($value);
+                    } else {
+                        $key = $this->options['defaultTagName'];
+                    }
+                }
+                $atts = array();
+                if ($this->options['typeHints'] === true) {
+                    $atts[$this->options['typeAttribute']] = gettype($value);
+                    if ($key !== $origKey) {
+                        $atts[$this->options['keyAttribute']] = (string)$origKey;
+                    }
+
+                }
+                if ($this->options['beautifyFilelist'] && $key == 'dir') {
+                    if (!isset($this->_curdir)) {
+                        $this->_curdir = '';
+                    }
+                    $savedir = $this->_curdir;
+                    if (isset($value['attribs'])) {
+                        if ($value['attribs']['name'] == '/') {
+                            $this->_curdir = '/';
+                        } else {
+                            $this->_curdir .= '/' . $value['attribs']['name'];
+                        }
+                    }
+                }
+
+                if (is_string($value) && $value && ($value{strlen($value) - 1} == "\n")) {
+                    $value .= str_repeat($this->options['indent'], $this->_tagDepth);
+                }
+                $tmp .= $this->_createXMLTag(array(
+                                                    'qname'      => $key,
+                                                    'attributes' => $atts,
+                                                    'content'    => $value )
+                                            );
+                if ($this->options['beautifyFilelist'] && $key == 'dir') {
+                    if (isset($value['attribs'])) {
+                        $tmp .= ' <!-- ' . $this->_curdir . ' -->';
+                        if (empty($savedir)) {
+                            unset($this->_curdir);
+                        } else {
+                            $this->_curdir = $savedir;
+                        }
+                    }
+                }
+                $tmp .= $this->options['linebreak'];
+            }
+
+            $this->_tagDepth--;
+            if ($this->options['indent']!==null && $this->_tagDepth>0) {
+                $tmp .= str_repeat($this->options['indent'], $this->_tagDepth);
+            }
+
+            if (trim($tmp) === '') {
+                $tmp = null;
+            }
+
+            $tag = array(
+                'qname'      => $tagName,
+                'content'    => $tmp,
+                'attributes' => $attributes
+            );
+        }
+        if ($this->options['typeHints'] === true) {
+            if (!isset($tag['attributes'][$this->options['typeAttribute']])) {
+                $tag['attributes'][$this->options['typeAttribute']] = 'array';
+            }
+        }
+
+        $string = $this->_createXMLTag($tag, false);
+        return $string;
+    }
+
+   /**
+    * create a tag from an array
+    * this method awaits an array in the following format
+    * array(
+    *       'qname'        => $tagName,
+    *       'attributes'   => array(),
+    *       'content'      => $content,      // optional
+    *       'namespace'    => $namespace     // optional
+    *       'namespaceUri' => $namespaceUri  // optional
+    *   )
+    *
+    * @access   private
+    * @param    array   $tag tag definition
+    * @param    boolean $replaceEntities whether to replace XML entities in content or not
+    * @return   string  $string XML tag
+    */
+    function _createXMLTag($tag, $replaceEntities = true)
+    {
+        if ($this->options['indentAttributes'] !== false) {
+            $multiline = true;
+            $indent    = str_repeat($this->options['indent'], $this->_tagDepth);
+
+            if ($this->options['indentAttributes'] == '_auto') {
+                $indent .= str_repeat(' ', (strlen($tag['qname'])+2));
+
+            } else {
+                $indent .= $this->options['indentAttributes'];
+            }
+        } else {
+            $indent = $multiline = false;
+        }
+
+        if (is_array($tag['content'])) {
+            if (empty($tag['content'])) {
+                $tag['content'] = '';
+            }
+        } elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') {
+            $tag['content'] = '';
+        }
+
+        if (is_scalar($tag['content']) || is_null($tag['content'])) {
+            if ($this->options['encoding'] == 'UTF-8' &&
+                  version_compare(phpversion(), '5.0.0', 'lt')
+            ) {
+                $tag['content'] = utf8_encode($tag['content']);
+            }
+
+            if ($replaceEntities === true) {
+                $replaceEntities = XML_UTIL_ENTITIES_XML;
+            }
+
+            $tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak']);
+        } elseif (is_array($tag['content'])) {
+            $tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']);
+        } elseif (is_object($tag['content'])) {
+            $tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']);
+        } elseif (is_resource($tag['content'])) {
+            settype($tag['content'], 'string');
+            $tag = XML_Util::createTagFromArray($tag, $replaceEntities);
+        }
+        return  $tag;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/PackageFile/Parser/v1.php b/lib/php/PEAR/PackageFile/Parser/v1.php
new file mode 100644
index 00000000..294d2a76
--- /dev/null
+++ b/lib/php/PEAR/PackageFile/Parser/v1.php
@@ -0,0 +1,459 @@
+<?php
+/**
+ * package.xml parsing class, package.xml version 1.0
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: v1.php 276385 2009-02-24 23:46:03Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * package.xml abstraction class
+ */
+require_once 'PEAR/PackageFile/v1.php';
+/**
+ * Parser for package.xml version 1.0
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: @PEAR-VER@
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_PackageFile_Parser_v1
+{
+    var $_registry;
+    var $_config;
+    var $_logger;
+    /**
+     * BC hack to allow PEAR_Common::infoFromString() to sort of
+     * work with the version 2.0 format - there's no filelist though
+     * @param PEAR_PackageFile_v2
+     */
+    function fromV2($packagefile)
+    {
+        $info = $packagefile->getArray(true);
+        $ret = new PEAR_PackageFile_v1;
+        $ret->fromArray($info['old']);
+    }
+
+    function setConfig(&$c)
+    {
+        $this->_config = &$c;
+        $this->_registry = &$c->getRegistry();
+    }
+
+    function setLogger(&$l)
+    {
+        $this->_logger = &$l;
+    }
+
+    /**
+     * @param string contents of package.xml file, version 1.0
+     * @return bool success of parsing
+     */
+    function &parse($data, $file, $archive = false)
+    {
+        if (!extension_loaded('xml')) {
+            return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension');
+        }
+        $xp = xml_parser_create();
+        if (!$xp) {
+            $a = &PEAR::raiseError('Cannot create xml parser for parsing package.xml');
+            return $a;
+        }
+        xml_set_object($xp, $this);
+        xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0');
+        xml_set_character_data_handler($xp, '_pkginfo_cdata_1_0');
+        xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false);
+
+        $this->element_stack = array();
+        $this->_packageInfo = array('provides' => array());
+        $this->current_element = false;
+        unset($this->dir_install);
+        $this->_packageInfo['filelist'] = array();
+        $this->filelist =& $this->_packageInfo['filelist'];
+        $this->dir_names = array();
+        $this->in_changelog = false;
+        $this->d_i = 0;
+        $this->cdata = '';
+        $this->_isValid = true;
+
+        if (!xml_parse($xp, $data, 1)) {
+            $code = xml_get_error_code($xp);
+            $line = xml_get_current_line_number($xp);
+            xml_parser_free($xp);
+            $a = &PEAR::raiseError(sprintf("XML error: %s at line %d",
+                           $str = xml_error_string($code), $line), 2);
+            return $a;
+        }
+
+        xml_parser_free($xp);
+
+        $pf = new PEAR_PackageFile_v1;
+        $pf->setConfig($this->_config);
+        if (isset($this->_logger)) {
+            $pf->setLogger($this->_logger);
+        }
+        $pf->setPackagefile($file, $archive);
+        $pf->fromArray($this->_packageInfo);
+        return $pf;
+    }
+    // {{{ _unIndent()
+
+    /**
+     * Unindent given string
+     *
+     * @param string $str The string that has to be unindented.
+     * @return string
+     * @access private
+     */
+    function _unIndent($str)
+    {
+        // remove leading newlines
+        $str = preg_replace('/^[\r\n]+/', '', $str);
+        // find whitespace at the beginning of the first line
+        $indent_len = strspn($str, " \t");
+        $indent = substr($str, 0, $indent_len);
+        $data = '';
+        // remove the same amount of whitespace from following lines
+        foreach (explode("\n", $str) as $line) {
+            if (substr($line, 0, $indent_len) == $indent) {
+                $data .= substr($line, $indent_len) . "\n";
+            } elseif (trim(substr($line, 0, $indent_len))) {
+                $data .= ltrim($line);
+            }
+        }
+        return $data;
+    }
+
+    // Support for package DTD v1.0:
+    // {{{ _element_start_1_0()
+
+    /**
+     * XML parser callback for ending elements.  Used for version 1.0
+     * packages.
+     *
+     * @param resource  $xp    XML parser resource
+     * @param string    $name  name of ending element
+     *
+     * @return void
+     *
+     * @access private
+     */
+    function _element_start_1_0($xp, $name, $attribs)
+    {
+        array_push($this->element_stack, $name);
+        $this->current_element = $name;
+        $spos = sizeof($this->element_stack) - 2;
+        $this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : '';
+        $this->current_attributes = $attribs;
+        $this->cdata = '';
+        switch ($name) {
+            case 'dir':
+                if ($this->in_changelog) {
+                    break;
+                }
+                if (array_key_exists('name', $attribs) && $attribs['name'] != '/') {
+                    $attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
+                        $attribs['name']);
+                    if (strrpos($attribs['name'], '/') === strlen($attribs['name']) - 1) {
+                        $attribs['name'] = substr($attribs['name'], 0,
+                            strlen($attribs['name']) - 1);
+                    }
+                    if (strpos($attribs['name'], '/') === 0) {
+                        $attribs['name'] = substr($attribs['name'], 1);
+                    }
+                    $this->dir_names[] = $attribs['name'];
+                }
+                if (isset($attribs['baseinstalldir'])) {
+                    $this->dir_install = $attribs['baseinstalldir'];
+                }
+                if (isset($attribs['role'])) {
+                    $this->dir_role = $attribs['role'];
+                }
+                break;
+            case 'file':
+                if ($this->in_changelog) {
+                    break;
+                }
+                if (isset($attribs['name'])) {
+                    $path = '';
+                    if (count($this->dir_names)) {
+                        foreach ($this->dir_names as $dir) {
+                            $path .= $dir . '/';
+                        }
+                    }
+                    $path .= preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
+                        $attribs['name']);
+                    unset($attribs['name']);
+                    $this->current_path = $path;
+                    $this->filelist[$path] = $attribs;
+                    // Set the baseinstalldir only if the file don't have this attrib
+                    if (!isset($this->filelist[$path]['baseinstalldir']) &&
+                        isset($this->dir_install))
+                    {
+                        $this->filelist[$path]['baseinstalldir'] = $this->dir_install;
+                    }
+                    // Set the Role
+                    if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
+                        $this->filelist[$path]['role'] = $this->dir_role;
+                    }
+                }
+                break;
+            case 'replace':
+                if (!$this->in_changelog) {
+                    $this->filelist[$this->current_path]['replacements'][] = $attribs;
+                }
+                break;
+            case 'maintainers':
+                $this->_packageInfo['maintainers'] = array();
+                $this->m_i = 0; // maintainers array index
+                break;
+            case 'maintainer':
+                // compatibility check
+                if (!isset($this->_packageInfo['maintainers'])) {
+                    $this->_packageInfo['maintainers'] = array();
+                    $this->m_i = 0;
+                }
+                $this->_packageInfo['maintainers'][$this->m_i] = array();
+                $this->current_maintainer =& $this->_packageInfo['maintainers'][$this->m_i];
+                break;
+            case 'changelog':
+                $this->_packageInfo['changelog'] = array();
+                $this->c_i = 0; // changelog array index
+                $this->in_changelog = true;
+                break;
+            case 'release':
+                if ($this->in_changelog) {
+                    $this->_packageInfo['changelog'][$this->c_i] = array();
+                    $this->current_release = &$this->_packageInfo['changelog'][$this->c_i];
+                } else {
+                    $this->current_release = &$this->_packageInfo;
+                }
+                break;
+            case 'deps':
+                if (!$this->in_changelog) {
+                    $this->_packageInfo['release_deps'] = array();
+                }
+                break;
+            case 'dep':
+                // dependencies array index
+                if (!$this->in_changelog) {
+                    $this->d_i++;
+                    isset($attribs['type']) ? ($attribs['type'] = strtolower($attribs['type'])) : false;
+                    $this->_packageInfo['release_deps'][$this->d_i] = $attribs;
+                }
+                break;
+            case 'configureoptions':
+                if (!$this->in_changelog) {
+                    $this->_packageInfo['configure_options'] = array();
+                }
+                break;
+            case 'configureoption':
+                if (!$this->in_changelog) {
+                    $this->_packageInfo['configure_options'][] = $attribs;
+                }
+                break;
+            case 'provides':
+                if (empty($attribs['type']) || empty($attribs['name'])) {
+                    break;
+                }
+                $attribs['explicit'] = true;
+                $this->_packageInfo['provides']["$attribs[type];$attribs[name]"] = $attribs;
+                break;
+            case 'package' :
+                if (isset($attribs['version'])) {
+                    $this->_packageInfo['xsdversion'] = trim($attribs['version']);
+                } else {
+                    $this->_packageInfo['xsdversion'] = '1.0';
+                }
+                if (isset($attribs['packagerversion'])) {
+                    $this->_packageInfo['packagerversion'] = $attribs['packagerversion'];
+                }
+                break;
+        }
+    }
+
+    // }}}
+    // {{{ _element_end_1_0()
+
+    /**
+     * XML parser callback for ending elements.  Used for version 1.0
+     * packages.
+     *
+     * @param resource  $xp    XML parser resource
+     * @param string    $name  name of ending element
+     *
+     * @return void
+     *
+     * @access private
+     */
+    function _element_end_1_0($xp, $name)
+    {
+        $data = trim($this->cdata);
+        switch ($name) {
+            case 'name':
+                switch ($this->prev_element) {
+                    case 'package':
+                        $this->_packageInfo['package'] = $data;
+                        break;
+                    case 'maintainer':
+                        $this->current_maintainer['name'] = $data;
+                        break;
+                }
+                break;
+            case 'extends' :
+                $this->_packageInfo['extends'] = $data;
+                break;
+            case 'summary':
+                $this->_packageInfo['summary'] = $data;
+                break;
+            case 'description':
+                $data = $this->_unIndent($this->cdata);
+                $this->_packageInfo['description'] = $data;
+                break;
+            case 'user':
+                $this->current_maintainer['handle'] = $data;
+                break;
+            case 'email':
+                $this->current_maintainer['email'] = $data;
+                break;
+            case 'role':
+                $this->current_maintainer['role'] = $data;
+                break;
+            case 'version':
+                if ($this->in_changelog) {
+                    $this->current_release['version'] = $data;
+                } else {
+                    $this->_packageInfo['version'] = $data;
+                }
+                break;
+            case 'date':
+                if ($this->in_changelog) {
+                    $this->current_release['release_date'] = $data;
+                } else {
+                    $this->_packageInfo['release_date'] = $data;
+                }
+                break;
+            case 'notes':
+                // try to "de-indent" release notes in case someone
+                // has been over-indenting their xml ;-)
+                // Trim only on the right side
+                $data = rtrim($this->_unIndent($this->cdata));
+                if ($this->in_changelog) {
+                    $this->current_release['release_notes'] = $data;
+                } else {
+                    $this->_packageInfo['release_notes'] = $data;
+                }
+                break;
+            case 'warnings':
+                if ($this->in_changelog) {
+                    $this->current_release['release_warnings'] = $data;
+                } else {
+                    $this->_packageInfo['release_warnings'] = $data;
+                }
+                break;
+            case 'state':
+                if ($this->in_changelog) {
+                    $this->current_release['release_state'] = $data;
+                } else {
+                    $this->_packageInfo['release_state'] = $data;
+                }
+                break;
+            case 'license':
+                if ($this->in_changelog) {
+                    $this->current_release['release_license'] = $data;
+                } else {
+                    $this->_packageInfo['release_license'] = $data;
+                }
+                break;
+            case 'dep':
+                if ($data && !$this->in_changelog) {
+                    $this->_packageInfo['release_deps'][$this->d_i]['name'] = $data;
+                }
+                break;
+            case 'dir':
+                if ($this->in_changelog) {
+                    break;
+                }
+                array_pop($this->dir_names);
+                break;
+            case 'file':
+                if ($this->in_changelog) {
+                    break;
+                }
+                if ($data) {
+                    $path = '';
+                    if (count($this->dir_names)) {
+                        foreach ($this->dir_names as $dir) {
+                            $path .= $dir . '/';
+                        }
+                    }
+                    $path .= $data;
+                    $this->filelist[$path] = $this->current_attributes;
+                    // Set the baseinstalldir only if the file don't have this attrib
+                    if (!isset($this->filelist[$path]['baseinstalldir']) &&
+                        isset($this->dir_install))
+                    {
+                        $this->filelist[$path]['baseinstalldir'] = $this->dir_install;
+                    }
+                    // Set the Role
+                    if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
+                        $this->filelist[$path]['role'] = $this->dir_role;
+                    }
+                }
+                break;
+            case 'maintainer':
+                if (empty($this->_packageInfo['maintainers'][$this->m_i]['role'])) {
+                    $this->_packageInfo['maintainers'][$this->m_i]['role'] = 'lead';
+                }
+                $this->m_i++;
+                break;
+            case 'release':
+                if ($this->in_changelog) {
+                    $this->c_i++;
+                }
+                break;
+            case 'changelog':
+                $this->in_changelog = false;
+                break;
+        }
+        array_pop($this->element_stack);
+        $spos = sizeof($this->element_stack) - 1;
+        $this->current_element = ($spos > 0) ? $this->element_stack[$spos] : '';
+        $this->cdata = '';
+    }
+
+    // }}}
+    // {{{ _pkginfo_cdata_1_0()
+
+    /**
+     * XML parser callback for character data.  Used for version 1.0
+     * packages.
+     *
+     * @param resource  $xp    XML parser resource
+     * @param string    $name  character data
+     *
+     * @return void
+     *
+     * @access private
+     */
+    function _pkginfo_cdata_1_0($xp, $data)
+    {
+        if (isset($this->cdata)) {
+            $this->cdata .= $data;
+        }
+    }
+
+    // }}}
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/PackageFile/Parser/v2.php b/lib/php/PEAR/PackageFile/Parser/v2.php
new file mode 100644
index 00000000..98992340
--- /dev/null
+++ b/lib/php/PEAR/PackageFile/Parser/v2.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * package.xml parsing class, package.xml version 2.0
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: v2.php 276385 2009-02-24 23:46:03Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * base xml parser class
+ */
+require_once 'PEAR/XMLParser.php';
+require_once 'PEAR/PackageFile/v2.php';
+/**
+ * Parser for package.xml version 2.0
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: @PEAR-VER@
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser
+{
+    var $_config;
+    var $_logger;
+    var $_registry;
+
+    function setConfig(&$c)
+    {
+        $this->_config = &$c;
+        $this->_registry = &$c->getRegistry();
+    }
+
+    function setLogger(&$l)
+    {
+        $this->_logger = &$l;
+    }
+    /**
+     * Unindent given string
+     *
+     * @param string $str The string that has to be unindented.
+     * @return string
+     * @access private
+     */
+    function _unIndent($str)
+    {
+        // remove leading newlines
+        $str = preg_replace('/^[\r\n]+/', '', $str);
+        // find whitespace at the beginning of the first line
+        $indent_len = strspn($str, " \t");
+        $indent = substr($str, 0, $indent_len);
+        $data = '';
+        // remove the same amount of whitespace from following lines
+        foreach (explode("\n", $str) as $line) {
+            if (substr($line, 0, $indent_len) == $indent) {
+                $data .= substr($line, $indent_len) . "\n";
+            } else {
+                $data .= $line . "\n";
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * post-process data
+     *
+     * @param string $data
+     * @param string $element element name
+     */
+    function postProcess($data, $element)
+    {
+        if ($element == 'notes') {
+            return trim($this->_unIndent($data));
+        }
+        return trim($data);
+    }
+
+    /**
+     * @param string
+     * @param string file name of the package.xml
+     * @param string|false name of the archive this package.xml came from, if any
+     * @param string class name to instantiate and return.  This must be PEAR_PackageFile_v2 or
+     *               a subclass
+     * @return PEAR_PackageFile_v2
+     */
+    function &parse($data, $file, $archive = false, $class = 'PEAR_PackageFile_v2')
+    {
+        if (PEAR::isError($err = parent::parse($data, $file))) {
+            return $err;
+        }
+
+        $ret = new $class;
+        $ret->encoding = $this->encoding;
+        $ret->setConfig($this->_config);
+        if (isset($this->_logger)) {
+            $ret->setLogger($this->_logger);
+        }
+
+        $ret->fromArray($this->_unserializedData);
+        $ret->setPackagefile($file, $archive);
+        return $ret;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/PackageFile/v1.php b/lib/php/PEAR/PackageFile/v1.php
new file mode 100644
index 00000000..80f71fab
--- /dev/null
+++ b/lib/php/PEAR/PackageFile/v1.php
@@ -0,0 +1,1612 @@
+<?php
+/**
+ * PEAR_PackageFile_v1, package.xml version 1.0
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: v1.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * For error handling
+ */
+require_once 'PEAR/ErrorStack.php';
+
+/**
+ * Error code if parsing is attempted with no xml extension
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3);
+
+/**
+ * Error code if creating the xml parser resource fails
+ */
+define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4);
+
+/**
+ * Error code used for all sax xml parsing errors
+ */
+define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5);
+
+/**
+ * Error code used when there is no name
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6);
+
+/**
+ * Error code when a package name is not valid
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7);
+
+/**
+ * Error code used when no summary is parsed
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8);
+
+/**
+ * Error code for summaries that are more than 1 line
+ */
+define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9);
+
+/**
+ * Error code used when no description is present
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10);
+
+/**
+ * Error code used when no license is present
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11);
+
+/**
+ * Error code used when a <version> version number is not present
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12);
+
+/**
+ * Error code used when a <version> version number is invalid
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13);
+
+/**
+ * Error code when release state is missing
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14);
+
+/**
+ * Error code when release state is invalid
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15);
+
+/**
+ * Error code when release state is missing
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16);
+
+/**
+ * Error code when release state is invalid
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17);
+
+/**
+ * Error code when no release notes are found
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18);
+
+/**
+ * Error code when no maintainers are found
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19);
+
+/**
+ * Error code when a maintainer has no handle
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20);
+
+/**
+ * Error code when a maintainer has no handle
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21);
+
+/**
+ * Error code when a maintainer has no name
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22);
+
+/**
+ * Error code when a maintainer has no email
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23);
+
+/**
+ * Error code when a maintainer has no handle
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24);
+
+/**
+ * Error code when a dependency is not a PHP dependency, but has no name
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25);
+
+/**
+ * Error code when a dependency has no type (pkg, php, etc.)
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26);
+
+/**
+ * Error code when a dependency has no relation (lt, ge, has, etc.)
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27);
+
+/**
+ * Error code when a dependency is not a 'has' relation, but has no version
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28);
+
+/**
+ * Error code when a dependency has an invalid relation
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29);
+
+/**
+ * Error code when a dependency has an invalid type
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30);
+
+/**
+ * Error code when a dependency has an invalid optional option
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31);
+
+/**
+ * Error code when a dependency is a pkg dependency, and has an invalid package name
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32);
+
+/**
+ * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel
+ */
+define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33);
+
+/**
+ * Error code when rel="has" and version attribute is present.
+ */
+define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34);
+
+/**
+ * Error code when type="php" and dependency name is present
+ */
+define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35);
+
+/**
+ * Error code when a configure option has no name
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36);
+
+/**
+ * Error code when a configure option has no name
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37);
+
+/**
+ * Error code when a file in the filelist has an invalid role
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38);
+
+/**
+ * Error code when a file in the filelist has no role
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39);
+
+/**
+ * Error code when analyzing a php source file that has parse errors
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40);
+
+/**
+ * Error code when analyzing a php source file reveals a source element
+ * without a package name prefix
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41);
+
+/**
+ * Error code when an unknown channel is specified
+ */
+define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42);
+
+/**
+ * Error code when no files are found in the filelist
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43);
+
+/**
+ * Error code when a file is not valid php according to _analyzeSourceCode()
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44);
+
+/**
+ * Error code when the channel validator returns an error or warning
+ */
+define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45);
+
+/**
+ * Error code when a php5 package is packaged in php4 (analysis doesn't work)
+ */
+define('PEAR_PACKAGEFILE_ERROR_PHP5', 46);
+
+/**
+ * Error code when a file is listed in package.xml but does not exist
+ */
+define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47);
+
+/**
+ * Error code when a <dep type="php" rel="not"... is encountered (use rel="ne")
+ */
+define('PEAR_PACKAGEFILE_PHP_NO_NOT', 48);
+
+/**
+ * Error code when a package.xml contains non-ISO-8859-1 characters
+ */
+define('PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS', 49);
+
+/**
+ * Error code when a dependency is not a 'has' relation, but has no version
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION', 50);
+
+/**
+ * Error code when a package has no lead developer
+ */
+define('PEAR_PACKAGEFILE_ERROR_NO_LEAD', 51);
+
+/**
+ * Error code when a filename begins with "."
+ */
+define('PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME', 52);
+/**
+ * package.xml encapsulator
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_PackageFile_v1
+{
+    /**
+     * @access private
+     * @var PEAR_ErrorStack
+     * @access private
+     */
+    var $_stack;
+
+    /**
+     * A registry object, used to access the package name validation regex for non-standard channels
+     * @var PEAR_Registry
+     * @access private
+     */
+    var $_registry;
+
+    /**
+     * An object that contains a log method that matches PEAR_Common::log's signature
+     * @var object
+     * @access private
+     */
+    var $_logger;
+
+    /**
+     * Parsed package information
+     * @var array
+     * @access private
+     */
+    var $_packageInfo;
+
+    /**
+     * path to package.xml
+     * @var string
+     * @access private
+     */
+    var $_packageFile;
+
+    /**
+     * path to package .tgz or false if this is a local/extracted package.xml
+     * @var string
+     * @access private
+     */
+    var $_archiveFile;
+
+    /**
+     * @var int
+     * @access private
+     */
+    var $_isValid = 0;
+
+    /**
+     * Determines whether this packagefile was initialized only with partial package info
+     *
+     * If this package file was constructed via parsing REST, it will only contain
+     *
+     * - package name
+     * - channel name
+     * - dependencies 
+     * @var boolean
+     * @access private
+     */
+    var $_incomplete = true;
+
+    /**
+     * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack
+     * @param string Name of Error Stack class to use.
+     */
+    function PEAR_PackageFile_v1()
+    {
+        $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1');
+        $this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
+        $this->_isValid = 0;
+    }
+
+    function installBinary($installer)
+    {
+        return false;
+    }
+
+    function isExtension($name)
+    {
+        return false;
+    }
+
+    function setConfig(&$config)
+    {
+        $this->_config = &$config;
+        $this->_registry = &$config->getRegistry();
+    }
+
+    function setRequestedGroup()
+    {
+        // placeholder
+    }
+
+    /**
+     * For saving in the registry.
+     *
+     * Set the last version that was installed
+     * @param string
+     */
+    function setLastInstalledVersion($version)
+    {
+        $this->_packageInfo['_lastversion'] = $version;
+    }
+
+    /**
+     * @return string|false
+     */
+    function getLastInstalledVersion()
+    {
+        if (isset($this->_packageInfo['_lastversion'])) {
+            return $this->_packageInfo['_lastversion'];
+        }
+        return false;
+    }
+
+    function getInstalledBinary()
+    {
+        return false;
+    }
+
+    function listPostinstallScripts()
+    {
+        return false;
+    }
+
+    function initPostinstallScripts()
+    {
+        return false;
+    }
+
+    function setLogger(&$logger)
+    {
+        if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) {
+            return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
+        }
+        $this->_logger = &$logger;
+    }
+
+    function setPackagefile($file, $archive = false)
+    {
+        $this->_packageFile = $file;
+        $this->_archiveFile = $archive ? $archive : $file;
+    }
+
+    function getPackageFile()
+    {
+        return isset($this->_packageFile) ? $this->_packageFile : false;
+    }
+
+    function getPackageType()
+    {
+        return 'php';
+    }
+
+    function getArchiveFile()
+    {
+        return $this->_archiveFile;
+    }
+
+    function packageInfo($field)
+    {
+        if (!is_string($field) || empty($field) ||
+            !isset($this->_packageInfo[$field])) {
+            return false;
+        }
+        return $this->_packageInfo[$field];
+    }
+
+    function setDirtree($path)
+    {
+        if (!isset($this->_packageInfo['dirtree'])) {
+            $this->_packageInfo['dirtree'] = array();
+        }
+        $this->_packageInfo['dirtree'][$path] = true;
+    }
+
+    function getDirtree()
+    {
+        if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
+            return $this->_packageInfo['dirtree'];
+        }
+        return false;
+    }
+
+    function resetDirtree()
+    {
+        unset($this->_packageInfo['dirtree']);
+    }
+
+    function fromArray($pinfo)
+    {
+        $this->_incomplete = false;
+        $this->_packageInfo = $pinfo;
+    }
+
+    function isIncomplete()
+    {
+        return $this->_incomplete;
+    }
+
+    function getChannel()
+    {
+        return 'pear.php.net';
+    }
+
+    function getUri()
+    {
+        return false;
+    }
+
+    function getTime()
+    {
+        return false;
+    }
+
+    function getExtends()
+    {
+        if (isset($this->_packageInfo['extends'])) {
+            return $this->_packageInfo['extends'];
+        }
+        return false;
+    }
+
+    /**
+     * @return array
+     */
+    function toArray()
+    {
+        if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
+            return false;
+        }
+        return $this->getArray();
+    }
+
+    function getArray()
+    {
+        return $this->_packageInfo;
+    }
+
+    function getName()
+    {
+        return $this->getPackage();
+    }
+
+    function getPackage()
+    {
+        if (isset($this->_packageInfo['package'])) {
+            return $this->_packageInfo['package'];
+        }
+        return false;
+    }
+
+    /**
+     * WARNING - don't use this unless you know what you are doing
+     */
+    function setRawPackage($package)
+    {
+        $this->_packageInfo['package'] = $package;
+    }
+
+    function setPackage($package)
+    {
+        $this->_packageInfo['package'] = $package;
+        $this->_isValid = false;
+    }
+
+    function getVersion()
+    {
+        if (isset($this->_packageInfo['version'])) {
+            return $this->_packageInfo['version'];
+        }
+        return false;
+    }
+
+    function setVersion($version)
+    {
+        $this->_packageInfo['version'] = $version;
+        $this->_isValid = false;
+    }
+
+    function clearMaintainers()
+    {
+        unset($this->_packageInfo['maintainers']);
+    }
+
+    function getMaintainers()
+    {
+        if (isset($this->_packageInfo['maintainers'])) {
+            return $this->_packageInfo['maintainers'];
+        }
+        return false;
+    }
+
+    /**
+     * Adds a new maintainer - no checking of duplicates is performed, use
+     * updatemaintainer for that purpose.
+     */
+    function addMaintainer($role, $handle, $name, $email)
+    {
+        $this->_packageInfo['maintainers'][] =
+            array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name);
+        $this->_isValid = false;
+    }
+
+    function updateMaintainer($role, $handle, $name, $email)
+    {
+        $found = false;
+        if (!isset($this->_packageInfo['maintainers']) ||
+              !is_array($this->_packageInfo['maintainers'])) {
+            return $this->addMaintainer($role, $handle, $name, $email);
+        }
+        foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
+            if ($maintainer['handle'] == $handle) {
+                $found = $i;
+                break;
+            }
+        }
+        if ($found !== false) {
+            unset($this->_packageInfo['maintainers'][$found]);
+            $this->_packageInfo['maintainers'] =
+                array_values($this->_packageInfo['maintainers']);
+        }
+        $this->addMaintainer($role, $handle, $name, $email);
+    }
+
+    function deleteMaintainer($handle)
+    {
+        $found = false;
+        foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) {
+            if ($maintainer['handle'] == $handle) {
+                $found = $i;
+                break;
+            }
+        }
+        if ($found !== false) {
+            unset($this->_packageInfo['maintainers'][$found]);
+            $this->_packageInfo['maintainers'] =
+                array_values($this->_packageInfo['maintainers']);
+            return true;
+        }
+        return false;
+    }
+
+    function getState()
+    {
+        if (isset($this->_packageInfo['release_state'])) {
+            return $this->_packageInfo['release_state'];
+        }
+        return false;
+    }
+
+    function setRawState($state)
+    {
+        $this->_packageInfo['release_state'] = $state;
+    }
+
+    function setState($state)
+    {
+        $this->_packageInfo['release_state'] = $state;
+        $this->_isValid = false;
+    }
+
+    function getDate()
+    {
+        if (isset($this->_packageInfo['release_date'])) {
+            return $this->_packageInfo['release_date'];
+        }
+        return false;
+    }
+
+    function setDate($date)
+    {
+        $this->_packageInfo['release_date'] = $date;
+        $this->_isValid = false;
+    }
+
+    function getLicense()
+    {
+        if (isset($this->_packageInfo['release_license'])) {
+            return $this->_packageInfo['release_license'];
+        }
+        return false;
+    }
+
+    function setLicense($date)
+    {
+        $this->_packageInfo['release_license'] = $date;
+        $this->_isValid = false;
+    }
+
+    function getSummary()
+    {
+        if (isset($this->_packageInfo['summary'])) {
+            return $this->_packageInfo['summary'];
+        }
+        return false;
+    }
+
+    function setSummary($summary)
+    {
+        $this->_packageInfo['summary'] = $summary;
+        $this->_isValid = false;
+    }
+
+    function getDescription()
+    {
+        if (isset($this->_packageInfo['description'])) {
+            return $this->_packageInfo['description'];
+        }
+        return false;
+    }
+
+    function setDescription($desc)
+    {
+        $this->_packageInfo['description'] = $desc;
+        $this->_isValid = false;
+    }
+
+    function getNotes()
+    {
+        if (isset($this->_packageInfo['release_notes'])) {
+            return $this->_packageInfo['release_notes'];
+        }
+        return false;
+    }
+
+    function setNotes($notes)
+    {
+        $this->_packageInfo['release_notes'] = $notes;
+        $this->_isValid = false;
+    }
+
+    function getDeps()
+    {
+        if (isset($this->_packageInfo['release_deps'])) {
+            return $this->_packageInfo['release_deps'];
+        }
+        return false;
+    }
+
+    /**
+     * Reset dependencies prior to adding new ones
+     */
+    function clearDeps()
+    {
+        unset($this->_packageInfo['release_deps']);
+    }
+
+    function addPhpDep($version, $rel)
+    {
+        $this->_isValid = false;
+        $this->_packageInfo['release_deps'][] =
+            array('type' => 'php',
+                  'rel' => $rel,
+                  'version' => $version);
+    }
+
+    function addPackageDep($name, $version, $rel, $optional = 'no')
+    {
+        $this->_isValid = false;
+        $dep =
+            array('type' => 'pkg',
+                  'name' => $name,
+                  'rel' => $rel,
+                  'optional' => $optional);
+        if ($rel != 'has' && $rel != 'not') {
+            $dep['version'] = $version;
+        }
+        $this->_packageInfo['release_deps'][] = $dep;
+    }
+
+    function addExtensionDep($name, $version, $rel, $optional = 'no')
+    {
+        $this->_isValid = false;
+        $this->_packageInfo['release_deps'][] =
+            array('type' => 'ext',
+                  'name' => $name,
+                  'rel' => $rel,
+                  'version' => $version,
+                  'optional' => $optional);
+    }
+
+    /**
+     * WARNING - do not use this function directly unless you know what you're doing
+     */
+    function setDeps($deps)
+    {
+        $this->_packageInfo['release_deps'] = $deps;
+    }
+
+    function hasDeps()
+    {
+        return isset($this->_packageInfo['release_deps']) &&
+            count($this->_packageInfo['release_deps']);
+    }
+
+    function getDependencyGroup($group)
+    {
+        return false;
+    }
+
+    function isCompatible($pf)
+    {
+        return false;
+    }
+
+    function isSubpackageOf($p)
+    {
+        return $p->isSubpackage($this);
+    }
+
+    function isSubpackage($p)
+    {
+        return false;
+    }
+
+    function dependsOn($package, $channel)
+    {
+        if (strtolower($channel) != 'pear.php.net') {
+            return false;
+        }
+        if (!($deps = $this->getDeps())) {
+            return false;
+        }
+        foreach ($deps as $dep) {
+            if ($dep['type'] != 'pkg') {
+                continue;
+            }
+            if (strtolower($dep['name']) == strtolower($package)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    function getConfigureOptions()
+    {
+        if (isset($this->_packageInfo['configure_options'])) {
+            return $this->_packageInfo['configure_options'];
+        }
+        return false;
+    }
+
+    function hasConfigureOptions()
+    {
+        return isset($this->_packageInfo['configure_options']) &&
+            count($this->_packageInfo['configure_options']);
+    }
+
+    function addConfigureOption($name, $prompt, $default = false)
+    {
+        $o = array('name' => $name, 'prompt' => $prompt);
+        if ($default !== false) {
+            $o['default'] = $default;
+        }
+        if (!isset($this->_packageInfo['configure_options'])) {
+            $this->_packageInfo['configure_options'] = array();
+        }
+        $this->_packageInfo['configure_options'][] = $o;
+    }
+
+    function clearConfigureOptions()
+    {
+        unset($this->_packageInfo['configure_options']);
+    }
+
+    function getProvides()
+    {
+        if (isset($this->_packageInfo['provides'])) {
+            return $this->_packageInfo['provides'];
+        }
+        return false;
+    }
+
+    function getProvidesExtension()
+    {
+        return false;
+    }
+
+    function addFile($dir, $file, $attrs)
+    {
+        $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
+        if ($dir == '/' || $dir == '') {
+            $dir = '';
+        } else {
+            $dir .= '/';
+        }
+        $file = $dir . $file;
+        $file = preg_replace('![\\/]+!', '/', $file);
+        $this->_packageInfo['filelist'][$file] = $attrs;
+    }
+
+    function getInstallationFilelist()
+    {
+        return $this->getFilelist();
+    }
+
+    function getFilelist()
+    {
+        if (isset($this->_packageInfo['filelist'])) {
+            return $this->_packageInfo['filelist'];
+        }
+        return false;
+    }
+
+    function setFileAttribute($file, $attr, $value)
+    {
+        $this->_packageInfo['filelist'][$file][$attr] = $value;
+    }
+
+    function resetFilelist()
+    {
+        $this->_packageInfo['filelist'] = array();
+    }
+
+    function setInstalledAs($file, $path)
+    {
+        if ($path) {
+            return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
+        }
+        unset($this->_packageInfo['filelist'][$file]['installed_as']);
+    }
+
+    function installedFile($file, $atts)
+    {
+        if (isset($this->_packageInfo['filelist'][$file])) {
+            $this->_packageInfo['filelist'][$file] =
+                array_merge($this->_packageInfo['filelist'][$file], $atts);
+        } else {
+            $this->_packageInfo['filelist'][$file] = $atts;
+        }
+    }
+
+    function getChangelog()
+    {
+        if (isset($this->_packageInfo['changelog'])) {
+            return $this->_packageInfo['changelog'];
+        }
+        return false;
+    }
+
+    function getPackagexmlVersion()
+    {
+        return '1.0';
+    }
+
+    /**
+     * Wrapper to {@link PEAR_ErrorStack::getErrors()}
+     * @param boolean determines whether to purge the error stack after retrieving
+     * @return array
+     */
+    function getValidationWarnings($purge = true)
+    {
+        return $this->_stack->getErrors($purge);
+    }
+
+    // }}}
+    /**
+     * Validation error.  Also marks the object contents as invalid
+     * @param error code
+     * @param array error information
+     * @access private
+     */
+    function _validateError($code, $params = array())
+    {
+        $this->_stack->push($code, 'error', $params, false, false, debug_backtrace());
+        $this->_isValid = false;
+    }
+
+    /**
+     * Validation warning.  Does not mark the object contents invalid.
+     * @param error code
+     * @param array error information
+     * @access private
+     */
+    function _validateWarning($code, $params = array())
+    {
+        $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace());
+    }
+
+    /**
+     * @param integer error code
+     * @access protected
+     */
+    function _getErrorMessage()
+    {
+        return array(
+                PEAR_PACKAGEFILE_ERROR_NO_NAME =>
+                    'Missing Package Name',
+                PEAR_PACKAGEFILE_ERROR_NO_SUMMARY =>
+                    'No summary found',
+                PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY =>
+                    'Summary should be on one line',
+                PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION =>
+                    'Missing description',
+                PEAR_PACKAGEFILE_ERROR_NO_LICENSE =>
+                    'Missing license',
+                PEAR_PACKAGEFILE_ERROR_NO_VERSION =>
+                    'No release version found',
+                PEAR_PACKAGEFILE_ERROR_NO_STATE =>
+                    'No release state found',
+                PEAR_PACKAGEFILE_ERROR_NO_DATE =>
+                    'No release date found',
+                PEAR_PACKAGEFILE_ERROR_NO_NOTES =>
+                    'No release notes found',
+                PEAR_PACKAGEFILE_ERROR_NO_LEAD =>
+                    'Package must have at least one lead maintainer',
+                PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS =>
+                    'No maintainers found, at least one must be defined',
+                PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE =>
+                    'Maintainer %index% has no handle (user ID at channel server)',
+                PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE =>
+                    'Maintainer %index% has no role',
+                PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME =>
+                    'Maintainer %index% has no name',
+                PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL =>
+                    'Maintainer %index% has no email',
+                PEAR_PACKAGEFILE_ERROR_NO_DEPNAME =>
+                    'Dependency %index% is not a php dependency, and has no name',
+                PEAR_PACKAGEFILE_ERROR_NO_DEPREL =>
+                    'Dependency %index% has no relation (rel)',
+                PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE =>
+                    'Dependency %index% has no type',
+                PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED =>
+                    'PHP Dependency %index% has a name attribute of "%name%" which will be' .
+                        ' ignored!',
+                PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION =>
+                    'Dependency %index% is not a rel="has" or rel="not" dependency, ' .
+                        'and has no version',
+                PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION =>
+                    'Dependency %index% is a type="php" dependency, ' .
+                        'and has no version',
+                PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED =>
+                    'Dependency %index% is a rel="%rel%" dependency, versioning is ignored',
+                PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL =>
+                    'Dependency %index% has invalid optional value "%opt%", should be yes or no',
+                PEAR_PACKAGEFILE_PHP_NO_NOT =>
+                    'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' .
+                        ' to exclude specific versions',
+                PEAR_PACKAGEFILE_ERROR_NO_CONFNAME =>
+                    'Configure Option %index% has no name',
+                PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT =>
+                    'Configure Option %index% has no prompt',
+                PEAR_PACKAGEFILE_ERROR_NO_FILES =>
+                    'No files in <filelist> section of package.xml',
+                PEAR_PACKAGEFILE_ERROR_NO_FILEROLE =>
+                    'File "%file%" has no role, expecting one of "%roles%"',
+                PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE =>
+                    'File "%file%" has invalid role "%role%", expecting one of "%roles%"',
+                PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME =>
+                    'File "%file%" cannot start with ".", cannot package or install',
+                PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE =>
+                    'Parser error: invalid PHP found in file "%file%"',
+                PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX =>
+                    'in %file%: %type% "%name%" not prefixed with package name "%package%"',
+                PEAR_PACKAGEFILE_ERROR_INVALID_FILE =>
+                    'Parser error: invalid PHP file "%file%"',
+                PEAR_PACKAGEFILE_ERROR_CHANNELVAL =>
+                    'Channel validator error: field "%field%" - %reason%',
+                PEAR_PACKAGEFILE_ERROR_PHP5 =>
+                    'Error, PHP5 token encountered in %file%, analysis should be in PHP5',
+                PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND =>
+                    'File "%file%" in package.xml does not exist',
+                PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS =>
+                    'Package.xml contains non-ISO-8859-1 characters, and may not validate',
+            );
+    }
+
+    /**
+     * Validate XML package definition file.
+     *
+     * @access public
+     * @return boolean
+     */
+    function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false)
+    {
+        if (($this->_isValid & $state) == $state) {
+            return true;
+        }
+        $this->_isValid = true;
+        $info = $this->_packageInfo;
+        if (empty($info['package'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME);
+            $this->_packageName = $pn = 'unknown';
+        } else {
+            $this->_packageName = $pn = $info['package'];
+        }
+
+        if (empty($info['summary'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY);
+        } elseif (strpos(trim($info['summary']), "\n") !== false) {
+            $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY,
+                array('summary' => $info['summary']));
+        }
+        if (empty($info['description'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION);
+        }
+        if (empty($info['release_license'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE);
+        }
+        if (empty($info['version'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION);
+        }
+        if (empty($info['release_state'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE);
+        }
+        if (empty($info['release_date'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE);
+        }
+        if (empty($info['release_notes'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES);
+        }
+        if (empty($info['maintainers'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS);
+        } else {
+            $haslead = false;
+            $i = 1;
+            foreach ($info['maintainers'] as $m) {
+                if (empty($m['handle'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE,
+                        array('index' => $i));
+                }
+                if (empty($m['role'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE,
+                        array('index' => $i, 'roles' => PEAR_Common::getUserRoles()));
+                } elseif ($m['role'] == 'lead') {
+                    $haslead = true;
+                }
+                if (empty($m['name'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME,
+                        array('index' => $i));
+                }
+                if (empty($m['email'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL,
+                        array('index' => $i));
+                }
+                $i++;
+            }
+            if (!$haslead) {
+                $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD);
+            }
+        }
+        if (!empty($info['release_deps'])) {
+            $i = 1;
+            foreach ($info['release_deps'] as $d) {
+                if (!isset($d['type']) || empty($d['type'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE,
+                        array('index' => $i, 'types' => PEAR_Common::getDependencyTypes()));
+                    continue;
+                }
+                if (!isset($d['rel']) || empty($d['rel'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL,
+                        array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations()));
+                    continue;
+                }
+                if (!empty($d['optional'])) {
+                    if (!in_array($d['optional'], array('yes', 'no'))) {
+                        $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL,
+                            array('index' => $i, 'opt' => $d['optional']));
+                    }
+                }
+                if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION,
+                        array('index' => $i));
+                } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) {
+                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED,
+                        array('index' => $i, 'rel' => $d['rel']));
+                }
+                if ($d['type'] == 'php' && !empty($d['name'])) {
+                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED,
+                        array('index' => $i, 'name' => $d['name']));
+                } elseif ($d['type'] != 'php' && empty($d['name'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME,
+                        array('index' => $i));
+                }
+                if ($d['type'] == 'php' && empty($d['version'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION,
+                        array('index' => $i));
+                }
+                if (($d['rel'] == 'not') && ($d['type'] == 'php')) {
+                    $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT,
+                        array('index' => $i));
+                }
+                $i++;
+            }
+        }
+        if (!empty($info['configure_options'])) {
+            $i = 1;
+            foreach ($info['configure_options'] as $c) {
+                if (empty($c['name'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME,
+                        array('index' => $i));
+                }
+                if (empty($c['prompt'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT,
+                        array('index' => $i));
+                }
+                $i++;
+            }
+        }
+        if (empty($info['filelist'])) {
+            $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES);
+            $errors[] = 'no files';
+        } else {
+            foreach ($info['filelist'] as $file => $fa) {
+                if (empty($fa['role'])) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE,
+                        array('file' => $file, 'roles' => PEAR_Common::getFileRoles()));
+                    continue;
+                } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) {
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE,
+                        array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles()));
+                }
+                if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) {
+                    // file contains .. parent directory or . cur directory references
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
+                        array('file' => $file));
+                }
+                if (isset($fa['install-as']) &&
+                      preg_match('~/\.\.?(/|\\z)|^\.\.?/~', 
+                                 str_replace('\\', '/', $fa['install-as']))) {
+                    // install-as contains .. parent directory or . cur directory references
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
+                        array('file' => $file . ' [installed as ' . $fa['install-as'] . ']'));
+                }
+                if (isset($fa['baseinstalldir']) &&
+                      preg_match('~/\.\.?(/|\\z)|^\.\.?/~', 
+                                 str_replace('\\', '/', $fa['baseinstalldir']))) {
+                    // install-as contains .. parent directory or . cur directory references
+                    $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
+                        array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']'));
+                }
+            }
+        }
+        if (isset($this->_registry) && $this->_isValid) {
+            $chan = $this->_registry->getChannel('pear.php.net');
+            if (PEAR::isError($chan)) {
+                $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage());
+                return $this->_isValid = 0;
+            }
+            $validator = $chan->getValidationObject();
+            $validator->setPackageFile($this);
+            $validator->validate($state);
+            $failures = $validator->getFailures();
+            foreach ($failures['errors'] as $error) {
+                $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error);
+            }
+            foreach ($failures['warnings'] as $warning) {
+                $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning);
+            }
+        }
+        if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) {
+            if ($this->_analyzePhpFiles()) {
+                $this->_isValid = true;
+            }
+        }
+        if ($this->_isValid) {
+            return $this->_isValid = $state;
+        }
+        return $this->_isValid = 0;
+    }
+
+    function _analyzePhpFiles()
+    {
+        if (!$this->_isValid) {
+            return false;
+        }
+        if (!isset($this->_packageFile)) {
+            return false;
+        }
+        $dir_prefix = dirname($this->_packageFile);
+        $common = new PEAR_Common;
+        $log = isset($this->_logger) ? array(&$this->_logger, 'log') :
+            array($common, 'log');
+        $info = $this->getFilelist();
+        foreach ($info as $file => $fa) {
+            if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
+                $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND,
+                    array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file));
+                continue;
+            }
+            if ($fa['role'] == 'php' && $dir_prefix) {
+                call_user_func_array($log, array(1, "Analyzing $file"));
+                $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file);
+                if ($srcinfo) {
+                    $this->_buildProvidesArray($srcinfo);
+                }
+            }
+        }
+        $this->_packageName = $pn = $this->getPackage();
+        $pnl = strlen($pn);
+        if (isset($this->_packageInfo['provides'])) {
+            foreach ((array) $this->_packageInfo['provides'] as $key => $what) {
+                if (isset($what['explicit'])) {
+                    // skip conformance checks if the provides entry is
+                    // specified in the package.xml file
+                    continue;
+                }
+                extract($what);
+                if ($type == 'class') {
+                    if (!strncasecmp($name, $pn, $pnl)) {
+                        continue;
+                    }
+                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
+                        array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
+                } elseif ($type == 'function') {
+                    if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) {
+                        continue;
+                    }
+                    $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX,
+                        array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn));
+                }
+            }
+        }
+        return $this->_isValid;
+    }
+
+    /**
+     * Get the default xml generator object
+     *
+     * @return PEAR_PackageFile_Generator_v1
+     */
+    function &getDefaultGenerator()
+    {
+        if (!class_exists('PEAR_PackageFile_Generator_v1')) {
+            require_once 'PEAR/PackageFile/Generator/v1.php';
+        }
+        $a = &new PEAR_PackageFile_Generator_v1($this);
+        return $a;
+    }
+
+    /**
+     * Get the contents of a file listed within the package.xml
+     * @param string
+     * @return string
+     */
+    function getFileContents($file)
+    {
+        if ($this->_archiveFile == $this->_packageFile) { // unpacked
+            $dir = dirname($this->_packageFile);
+            $file = $dir . DIRECTORY_SEPARATOR . $file;
+            $file = str_replace(array('/', '\\'),
+                array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
+            if (file_exists($file) && is_readable($file)) {
+                return implode('', file($file));
+            }
+        } else { // tgz
+            if (!class_exists('Archive_Tar')) {
+                require_once 'Archive/Tar.php';
+            }
+            $tar = &new Archive_Tar($this->_archiveFile);
+            $tar->pushErrorHandling(PEAR_ERROR_RETURN);
+            if ($file != 'package.xml' && $file != 'package2.xml') {
+                $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
+            }
+            $file = $tar->extractInString($file);
+            $tar->popErrorHandling();
+            if (PEAR::isError($file)) {
+                return PEAR::raiseError("Cannot locate file '$file' in archive");
+            }
+            return $file;
+        }
+    }
+
+    // {{{ analyzeSourceCode()
+    /**
+     * Analyze the source code of the given PHP file
+     *
+     * @param  string Filename of the PHP file
+     * @return mixed
+     * @access private
+     */
+    function _analyzeSourceCode($file)
+    {
+        if (!function_exists("token_get_all")) {
+            return false;
+        }
+        if (!defined('T_DOC_COMMENT')) {
+            define('T_DOC_COMMENT', T_COMMENT);
+        }
+        if (!defined('T_INTERFACE')) {
+            define('T_INTERFACE', -1);
+        }
+        if (!defined('T_IMPLEMENTS')) {
+            define('T_IMPLEMENTS', -1);
+        }
+        if (!$fp = @fopen($file, "r")) {
+            return false;
+        }
+        fclose($fp);
+        $contents = file_get_contents($file);
+        $tokens = token_get_all($contents);
+/*
+        for ($i = 0; $i < sizeof($tokens); $i++) {
+            @list($token, $data) = $tokens[$i];
+            if (is_string($token)) {
+                var_dump($token);
+            } else {
+                print token_name($token) . ' ';
+                var_dump(rtrim($data));
+            }
+        }
+*/
+        $look_for = 0;
+        $paren_level = 0;
+        $bracket_level = 0;
+        $brace_level = 0;
+        $lastphpdoc = '';
+        $current_class = '';
+        $current_interface = '';
+        $current_class_level = -1;
+        $current_function = '';
+        $current_function_level = -1;
+        $declared_classes = array();
+        $declared_interfaces = array();
+        $declared_functions = array();
+        $declared_methods = array();
+        $used_classes = array();
+        $used_functions = array();
+        $extends = array();
+        $implements = array();
+        $nodeps = array();
+        $inquote = false;
+        $interface = false;
+        for ($i = 0; $i < sizeof($tokens); $i++) {
+            if (is_array($tokens[$i])) {
+                list($token, $data) = $tokens[$i];
+            } else {
+                $token = $tokens[$i];
+                $data = '';
+            }
+            if ($inquote) {
+                if ($token != '"' && $token != T_END_HEREDOC) {
+                    continue;
+                } else {
+                    $inquote = false;
+                    continue;
+                }
+            }
+            switch ($token) {
+                case T_WHITESPACE :
+                    continue;
+                case ';':
+                    if ($interface) {
+                        $current_function = '';
+                        $current_function_level = -1;
+                    }
+                    break;
+                case '"':
+                case T_START_HEREDOC:
+                    $inquote = true;
+                    break;
+                case T_CURLY_OPEN:
+                case T_DOLLAR_OPEN_CURLY_BRACES:
+                case '{': $brace_level++; continue 2;
+                case '}':
+                    $brace_level--;
+                    if ($current_class_level == $brace_level) {
+                        $current_class = '';
+                        $current_class_level = -1;
+                    }
+                    if ($current_function_level == $brace_level) {
+                        $current_function = '';
+                        $current_function_level = -1;
+                    }
+                    continue 2;
+                case '[': $bracket_level++; continue 2;
+                case ']': $bracket_level--; continue 2;
+                case '(': $paren_level++;   continue 2;
+                case ')': $paren_level--;   continue 2;
+                case T_INTERFACE:
+                    $interface = true;
+                case T_CLASS:
+                    if (($current_class_level != -1) || ($current_function_level != -1)) {
+                        $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
+                            array('file' => $file));
+                        return false;
+                    }
+                case T_FUNCTION:
+                case T_NEW:
+                case T_EXTENDS:
+                case T_IMPLEMENTS:
+                    $look_for = $token;
+                    continue 2;
+                case T_STRING:
+                    if (version_compare(zend_version(), '2.0', '<')) {
+                        if (in_array(strtolower($data),
+                            array('public', 'private', 'protected', 'abstract',
+                                  'interface', 'implements', 'throw') 
+                                 )) {
+                            $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5,
+                                array($file));
+                        }
+                    }
+                    if ($look_for == T_CLASS) {
+                        $current_class = $data;
+                        $current_class_level = $brace_level;
+                        $declared_classes[] = $current_class;
+                    } elseif ($look_for == T_INTERFACE) {
+                        $current_interface = $data;
+                        $current_class_level = $brace_level;
+                        $declared_interfaces[] = $current_interface;
+                    } elseif ($look_for == T_IMPLEMENTS) {
+                        $implements[$current_class] = $data;
+                    } elseif ($look_for == T_EXTENDS) {
+                        $extends[$current_class] = $data;
+                    } elseif ($look_for == T_FUNCTION) {
+                        if ($current_class) {
+                            $current_function = "$current_class::$data";
+                            $declared_methods[$current_class][] = $data;
+                        } elseif ($current_interface) {
+                            $current_function = "$current_interface::$data";
+                            $declared_methods[$current_interface][] = $data;
+                        } else {
+                            $current_function = $data;
+                            $declared_functions[] = $current_function;
+                        }
+                        $current_function_level = $brace_level;
+                        $m = array();
+                    } elseif ($look_for == T_NEW) {
+                        $used_classes[$data] = true;
+                    }
+                    $look_for = 0;
+                    continue 2;
+                case T_VARIABLE:
+                    $look_for = 0;
+                    continue 2;
+                case T_DOC_COMMENT:
+                case T_COMMENT:
+                    if (preg_match('!^/\*\*\s!', $data)) {
+                        $lastphpdoc = $data;
+                        if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
+                            $nodeps = array_merge($nodeps, $m[1]);
+                        }
+                    }
+                    continue 2;
+                case T_DOUBLE_COLON:
+                    if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
+                        $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE,
+                            array('file' => $file));
+                        return false;
+                    }
+                    $class = $tokens[$i - 1][1];
+                    if (strtolower($class) != 'parent') {
+                        $used_classes[$class] = true;
+                    }
+                    continue 2;
+            }
+        }
+        return array(
+            "source_file" => $file,
+            "declared_classes" => $declared_classes,
+            "declared_interfaces" => $declared_interfaces,
+            "declared_methods" => $declared_methods,
+            "declared_functions" => $declared_functions,
+            "used_classes" => array_diff(array_keys($used_classes), $nodeps),
+            "inheritance" => $extends,
+            "implements" => $implements,
+            );
+    }
+
+    /**
+     * Build a "provides" array from data returned by
+     * analyzeSourceCode().  The format of the built array is like
+     * this:
+     *
+     *  array(
+     *    'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
+     *    ...
+     *  )
+     *
+     *
+     * @param array $srcinfo array with information about a source file
+     * as returned by the analyzeSourceCode() method.
+     *
+     * @return void
+     *
+     * @access private
+     *
+     */
+    function _buildProvidesArray($srcinfo)
+    {
+        if (!$this->_isValid) {
+            return false;
+        }
+        $file = basename($srcinfo['source_file']);
+        $pn = $this->getPackage();
+        $pnl = strlen($pn);
+        foreach ($srcinfo['declared_classes'] as $class) {
+            $key = "class;$class";
+            if (isset($this->_packageInfo['provides'][$key])) {
+                continue;
+            }
+            $this->_packageInfo['provides'][$key] =
+                array('file'=> $file, 'type' => 'class', 'name' => $class);
+            if (isset($srcinfo['inheritance'][$class])) {
+                $this->_packageInfo['provides'][$key]['extends'] =
+                    $srcinfo['inheritance'][$class];
+            }
+        }
+        foreach ($srcinfo['declared_methods'] as $class => $methods) {
+            foreach ($methods as $method) {
+                $function = "$class::$method";
+                $key = "function;$function";
+                if ($method{0} == '_' || !strcasecmp($method, $class) ||
+                    isset($this->_packageInfo['provides'][$key])) {
+                    continue;
+                }
+                $this->_packageInfo['provides'][$key] =
+                    array('file'=> $file, 'type' => 'function', 'name' => $function);
+            }
+        }
+
+        foreach ($srcinfo['declared_functions'] as $function) {
+            $key = "function;$function";
+            if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) {
+                continue;
+            }
+            if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
+                $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
+            }
+            $this->_packageInfo['provides'][$key] =
+                array('file'=> $file, 'type' => 'function', 'name' => $function);
+        }
+    }
+
+    // }}}
+}
+?>
diff --git a/lib/php/PEAR/PackageFile/v2.php b/lib/php/PEAR/PackageFile/v2.php
new file mode 100644
index 00000000..78932a57
--- /dev/null
+++ b/lib/php/PEAR/PackageFile/v2.php
@@ -0,0 +1,2045 @@
+<?php
+/**
+ * PEAR_PackageFile_v2, package.xml version 2.0
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: v2.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * For error handling
+ */
+require_once 'PEAR/ErrorStack.php';
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_PackageFile_v2
+{
+
+    /**
+     * Parsed package information
+     * @var array
+     * @access private
+     */
+    var $_packageInfo = array();
+
+    /**
+     * path to package .tgz or false if this is a local/extracted package.xml
+     * @var string|false
+     * @access private
+     */
+    var $_archiveFile;
+
+    /**
+     * path to package .xml or false if this is an abstract parsed-from-string xml
+     * @var string|false
+     * @access private
+     */
+    var $_packageFile;
+
+    /**
+     * This is used by file analysis routines to log progress information
+     * @var PEAR_Common
+     * @access protected
+     */
+    var $_logger;
+
+    /**
+     * This is set to the highest validation level that has been validated
+     *
+     * If the package.xml is invalid or unknown, this is set to 0.  If
+     * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL.  If
+     * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING
+     * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING.  This allows validation
+     * "caching" to occur, which is particularly important for package validation, so
+     * that PHP files are not validated twice
+     * @var int
+     * @access private
+     */
+    var $_isValid = 0;
+
+    /**
+     * True if the filelist has been validated
+     * @param bool
+     */
+    var $_filesValid = false;
+
+    /**
+     * @var PEAR_Registry
+     * @access protected
+     */
+    var $_registry;
+
+    /**
+     * @var PEAR_Config
+     * @access protected
+     */
+    var $_config;
+
+    /**
+     * Optional Dependency group requested for installation
+     * @var string
+     * @access private
+     */
+    var $_requestedGroup = false;
+
+    /**
+     * @var PEAR_ErrorStack
+     * @access protected
+     */
+    var $_stack;
+
+    /**
+     * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible
+     */
+    var $_tasksNs;
+
+    /**
+     * Determines whether this packagefile was initialized only with partial package info
+     *
+     * If this package file was constructed via parsing REST, it will only contain
+     *
+     * - package name
+     * - channel name
+     * - dependencies
+     * @var boolean
+     * @access private
+     */
+    var $_incomplete = true;
+
+    /**
+     * @var PEAR_PackageFile_v2_Validator
+     */
+    var $_v2Validator;
+
+    /**
+     * The constructor merely sets up the private error stack
+     */
+    function PEAR_PackageFile_v2()
+    {
+        $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null);
+        $this->_isValid = false;
+    }
+
+    /**
+     * To make unit-testing easier
+     * @param PEAR_Frontend_*
+     * @param array options
+     * @param PEAR_Config
+     * @return PEAR_Downloader
+     * @access protected
+     */
+    function &getPEARDownloader(&$i, $o, &$c)
+    {
+        $z = &new PEAR_Downloader($i, $o, $c);
+        return $z;
+    }
+
+    /**
+     * To make unit-testing easier
+     * @param PEAR_Config
+     * @param array options
+     * @param array package name as returned from {@link PEAR_Registry::parsePackageName()}
+     * @param int PEAR_VALIDATE_* constant
+     * @return PEAR_Dependency2
+     * @access protected
+     */
+    function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING)
+    {
+        if (!class_exists('PEAR_Dependency2')) {
+            require_once 'PEAR/Dependency2.php';
+        }
+        $z = &new PEAR_Dependency2($c, $o, $p, $s);
+        return $z;
+    }
+
+    function getInstalledBinary()
+    {
+        return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] :
+            false;
+    }
+
+    /**
+     * Installation of source package has failed, attempt to download and install the
+     * binary version of this package.
+     * @param PEAR_Installer
+     * @return array|false
+     */
+    function installBinary(&$installer)
+    {
+        if (!OS_WINDOWS) {
+            $a = false;
+            return $a;
+        }
+        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
+            $releasetype = $this->getPackageType() . 'release';
+            if (!is_array($installer->getInstallPackages())) {
+                $a = false;
+                return $a;
+            }
+            foreach ($installer->getInstallPackages() as $p) {
+                if ($p->isExtension($this->_packageInfo['providesextension'])) {
+                    if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') {
+                        $a = false;
+                        return $a; // the user probably downloaded it separately
+                    }
+                }
+            }
+            if (isset($this->_packageInfo[$releasetype]['binarypackage'])) {
+                $installer->log(0, 'Attempting to download binary version of extension "' .
+                    $this->_packageInfo['providesextension'] . '"');
+                $params = $this->_packageInfo[$releasetype]['binarypackage'];
+                if (!is_array($params) || !isset($params[0])) {
+                    $params = array($params);
+                }
+                if (isset($this->_packageInfo['channel'])) {
+                    foreach ($params as $i => $param) {
+                        $params[$i] = array('channel' => $this->_packageInfo['channel'],
+                            'package' => $param, 'version' => $this->getVersion());
+                    }
+                }
+                $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(),
+                    $installer->config);
+                $verbose = $dl->config->get('verbose');
+                $dl->config->set('verbose', -1);
+                foreach ($params as $param) {
+                    PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                    $ret = $dl->download(array($param));
+                    PEAR::popErrorHandling();
+                    if (is_array($ret) && count($ret)) {
+                        break;
+                    }
+                }
+                $dl->config->set('verbose', $verbose);
+                if (is_array($ret)) {
+                    if (count($ret) == 1) {
+                        $pf = $ret[0]->getPackageFile();
+                        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                        $err = $installer->install($ret[0]);
+                        PEAR::popErrorHandling();
+                        if (is_array($err)) {
+                            $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage();
+                            // "install" self, so all dependencies will work transparently
+                            $this->_registry->addPackage2($this);
+                            $installer->log(0, 'Download and install of binary extension "' .
+                                $this->_registry->parsedPackageNameToString(
+                                    array('channel' => $pf->getChannel(),
+                                          'package' => $pf->getPackage()), true) . '" successful');
+                            $a = array($ret[0], $err);
+                            return $a;
+                        }
+                        $installer->log(0, 'Download and install of binary extension "' .
+                            $this->_registry->parsedPackageNameToString(
+                                    array('channel' => $pf->getChannel(),
+                                          'package' => $pf->getPackage()), true) . '" failed');
+                    }
+                }
+            }
+        }
+        $a = false;
+        return $a;
+    }
+
+    /**
+     * @return string|false Extension name
+     */
+    function getProvidesExtension()
+    {
+        if (in_array($this->getPackageType(),
+              array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
+            if (isset($this->_packageInfo['providesextension'])) {
+                return $this->_packageInfo['providesextension'];
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @param string Extension name
+     * @return bool
+     */
+    function isExtension($extension)
+    {
+        if (in_array($this->getPackageType(),
+              array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
+            return $this->_packageInfo['providesextension'] == $extension;
+        }
+        return false;
+    }
+
+    /**
+     * Tests whether every part of the package.xml 1.0 is represented in
+     * this package.xml 2.0
+     * @param PEAR_PackageFile_v1
+     * @return bool
+     */
+    function isEquivalent($pf1)
+    {
+        if (!$pf1) {
+            return true;
+        }
+        if ($this->getPackageType() == 'bundle') {
+            return false;
+        }
+        $this->_stack->getErrors(true);
+        if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) {
+            return false;
+        }
+        $pass = true;
+        if ($pf1->getPackage() != $this->getPackage()) {
+            $this->_differentPackage($pf1->getPackage());
+            $pass = false;
+        }
+        if ($pf1->getVersion() != $this->getVersion()) {
+            $this->_differentVersion($pf1->getVersion());
+            $pass = false;
+        }
+        if (trim($pf1->getSummary()) != $this->getSummary()) {
+            $this->_differentSummary($pf1->getSummary());
+            $pass = false;
+        }
+        if (preg_replace('/\s+/', '', $pf1->getDescription()) !=
+              preg_replace('/\s+/', '', $this->getDescription())) {
+            $this->_differentDescription($pf1->getDescription());
+            $pass = false;
+        }
+        if ($pf1->getState() != $this->getState()) {
+            $this->_differentState($pf1->getState());
+            $pass = false;
+        }
+        if (!strstr(preg_replace('/\s+/', '', $this->getNotes()),
+              preg_replace('/\s+/', '', $pf1->getNotes()))) {
+            $this->_differentNotes($pf1->getNotes());
+            $pass = false;
+        }
+        $mymaintainers = $this->getMaintainers();
+        $yourmaintainers = $pf1->getMaintainers();
+        for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) {
+            $reset = false;
+            for ($i2 = 0; $i2 < count($mymaintainers); $i2++) {
+                if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) {
+                    if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) {
+                        $this->_differentRole($mymaintainers[$i2]['handle'],
+                            $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']);
+                        $pass = false;
+                    }
+                    if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) {
+                        $this->_differentEmail($mymaintainers[$i2]['handle'],
+                            $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']);
+                        $pass = false;
+                    }
+                    if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) {
+                        $this->_differentName($mymaintainers[$i2]['handle'],
+                            $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']);
+                        $pass = false;
+                    }
+                    unset($mymaintainers[$i2]);
+                    $mymaintainers = array_values($mymaintainers);
+                    unset($yourmaintainers[$i1]);
+                    $yourmaintainers = array_values($yourmaintainers);
+                    $reset = true;
+                    break;
+                }
+            }
+            if ($reset) {
+                $i1 = -1;
+            }
+        }
+        $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers);
+        $filelist = $this->getFilelist();
+        foreach ($pf1->getFilelist() as $file => $atts) {
+            if (!isset($filelist[$file])) {
+                $this->_missingFile($file);
+                $pass = false;
+            }
+        }
+        return $pass;
+    }
+
+    function _differentPackage($package)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('package' => $package,
+            'self' => $this->getPackage()),
+            'package.xml 1.0 package "%package%" does not match "%self%"');
+    }
+
+    function _differentVersion($version)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('version' => $version,
+            'self' => $this->getVersion()),
+            'package.xml 1.0 version "%version%" does not match "%self%"');
+    }
+
+    function _differentState($state)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('state' => $state,
+            'self' => $this->getState()),
+            'package.xml 1.0 state "%state%" does not match "%self%"');
+    }
+
+    function _differentRole($handle, $role, $selfrole)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
+            'role' => $role, 'self' => $selfrole),
+            'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"');
+    }
+
+    function _differentEmail($handle, $email, $selfemail)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
+            'email' => $email, 'self' => $selfemail),
+            'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"');
+    }
+
+    function _differentName($handle, $name, $selfname)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle,
+            'name' => $name, 'self' => $selfname),
+            'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"');
+    }
+
+    function _unmatchedMaintainers($my, $yours)
+    {
+        if ($my) {
+            array_walk($my, create_function('&$i, $k', '$i = $i["handle"];'));
+            $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my),
+                'package.xml 2.0 has unmatched extra maintainers "%handles%"');
+        }
+        if ($yours) {
+            array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];'));
+            $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours),
+                'package.xml 1.0 has unmatched extra maintainers "%handles%"');
+        }
+    }
+
+    function _differentNotes($notes)
+    {
+        $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...';
+        $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() :
+            substr($this->getNotes(), 0, 24) . '...';
+        $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes,
+            'self' => $truncmynotes),
+            'package.xml 1.0 release notes "%notes%" do not match "%self%"');
+    }
+
+    function _differentSummary($summary)
+    {
+        $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...';
+        $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() :
+            substr($this->getsummary(), 0, 24) . '...';
+        $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary,
+            'self' => $truncmysummary),
+            'package.xml 1.0 summary "%summary%" does not match "%self%"');
+    }
+
+    function _differentDescription($description)
+    {
+        $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...');
+        $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() :
+            substr($this->getdescription(), 0, 24) . '...');
+        $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription,
+            'self' => $truncmydescription),
+            'package.xml 1.0 description "%description%" does not match "%self%"');
+    }
+
+    function _missingFile($file)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
+            'package.xml 1.0 file "%file%" is not present in <contents>');
+    }
+
+    /**
+     * WARNING - do not use this function unless you know what you're doing
+     */
+    function setRawState($state)
+    {
+        if (!isset($this->_packageInfo['stability'])) {
+            $this->_packageInfo['stability'] = array();
+        }
+        $this->_packageInfo['stability']['release'] = $state;
+    }
+
+    /**
+     * WARNING - do not use this function unless you know what you're doing
+     */
+    function setRawCompatible($compatible)
+    {
+        $this->_packageInfo['compatible'] = $compatible;
+    }
+
+    /**
+     * WARNING - do not use this function unless you know what you're doing
+     */
+    function setRawPackage($package)
+    {
+        $this->_packageInfo['name'] = $package;
+    }
+
+    /**
+     * WARNING - do not use this function unless you know what you're doing
+     */
+    function setRawChannel($channel)
+    {
+        $this->_packageInfo['channel'] = $channel;
+    }
+
+    function setRequestedGroup($group)
+    {
+        $this->_requestedGroup = $group;
+    }
+
+    function getRequestedGroup()
+    {
+        if (isset($this->_requestedGroup)) {
+            return $this->_requestedGroup;
+        }
+        return false;
+    }
+
+    /**
+     * For saving in the registry.
+     *
+     * Set the last version that was installed
+     * @param string
+     */
+    function setLastInstalledVersion($version)
+    {
+        $this->_packageInfo['_lastversion'] = $version;
+    }
+
+    /**
+     * @return string|false
+     */
+    function getLastInstalledVersion()
+    {
+        if (isset($this->_packageInfo['_lastversion'])) {
+            return $this->_packageInfo['_lastversion'];
+        }
+        return false;
+    }
+
+    /**
+     * Determines whether this package.xml has post-install scripts or not
+     * @return array|false
+     */
+    function listPostinstallScripts()
+    {
+        $filelist = $this->getFilelist();
+        $contents = $this->getContents();
+        $contents = $contents['dir']['file'];
+        if (!is_array($contents) || !isset($contents[0])) {
+            $contents = array($contents);
+        }
+        $taskfiles = array();
+        foreach ($contents as $file) {
+            $atts = $file['attribs'];
+            unset($file['attribs']);
+            if (count($file)) {
+                $taskfiles[$atts['name']] = $file;
+            }
+        }
+        $common = new PEAR_Common;
+        $common->debug = $this->_config->get('verbose');
+        $this->_scripts = array();
+        $ret = array();
+        foreach ($taskfiles as $name => $tasks) {
+            if (!isset($filelist[$name])) {
+                // ignored files will not be in the filelist
+                continue;
+            }
+            $atts = $filelist[$name];
+            foreach ($tasks as $tag => $raw) {
+                $task = $this->getTask($tag);
+                $task = &new $task($this->_config, $common, PEAR_TASK_INSTALL);
+                if ($task->isScript()) {
+                    $ret[] = $filelist[$name]['installed_as'];
+                }
+            }
+        }
+        if (count($ret)) {
+            return $ret;
+        }
+        return false;
+    }
+
+    /**
+     * Initialize post-install scripts for running
+     *
+     * This method can be used to detect post-install scripts, as the return value
+     * indicates whether any exist
+     * @return bool
+     */
+    function initPostinstallScripts()
+    {
+        $filelist = $this->getFilelist();
+        $contents = $this->getContents();
+        $contents = $contents['dir']['file'];
+        if (!is_array($contents) || !isset($contents[0])) {
+            $contents = array($contents);
+        }
+        $taskfiles = array();
+        foreach ($contents as $file) {
+            $atts = $file['attribs'];
+            unset($file['attribs']);
+            if (count($file)) {
+                $taskfiles[$atts['name']] = $file;
+            }
+        }
+        $common = new PEAR_Common;
+        $common->debug = $this->_config->get('verbose');
+        $this->_scripts = array();
+        foreach ($taskfiles as $name => $tasks) {
+            if (!isset($filelist[$name])) {
+                // file was not installed due to installconditions
+                continue;
+            }
+            $atts = $filelist[$name];
+            foreach ($tasks as $tag => $raw) {
+                $taskname = $this->getTask($tag);
+                $task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL);
+                if (!$task->isScript()) {
+                    continue; // scripts are only handled after installation
+                }
+                $lastversion = isset($this->_packageInfo['_lastversion']) ?
+                    $this->_packageInfo['_lastversion'] : null;
+                $task->init($raw, $atts, $lastversion);
+                $res = $task->startSession($this, $atts['installed_as']);
+                if (!$res) {
+                    continue; // skip this file
+                }
+                if (PEAR::isError($res)) {
+                    return $res;
+                }
+                $assign = &$task;
+                $this->_scripts[] = &$assign;
+            }
+        }
+        if (count($this->_scripts)) {
+            return true;
+        }
+        return false;
+    }
+
+    function runPostinstallScripts()
+    {
+        if ($this->initPostinstallScripts()) {
+            $ui = &PEAR_Frontend::singleton();
+            if ($ui) {
+                $ui->runPostinstallScripts($this->_scripts, $this);
+            }
+        }
+    }
+
+
+    /**
+     * Convert a recursive set of <dir> and <file> tags into a single <dir> tag with
+     * <file> tags.
+     */
+    function flattenFilelist()
+    {
+        if (isset($this->_packageInfo['bundle'])) {
+            return;
+        }
+        $filelist = array();
+        if (isset($this->_packageInfo['contents']['dir']['dir'])) {
+            $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']);
+            if (!isset($filelist[1])) {
+                $filelist = $filelist[0];
+            }
+            $this->_packageInfo['contents']['dir']['file'] = $filelist;
+            unset($this->_packageInfo['contents']['dir']['dir']);
+        } else {
+            // else already flattened but check for baseinstalldir propagation
+            if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) {
+                if (isset($this->_packageInfo['contents']['dir']['file'][0])) {
+                    foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) {
+                        if (isset($file['attribs']['baseinstalldir'])) {
+                            continue;
+                        }
+                        $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir']
+                            = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
+                    }
+                } else {
+                    if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) {
+                       $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir']
+                            = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'];
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * @param array the final flattened file list
+     * @param array the current directory being processed
+     * @param string|false any recursively inherited baeinstalldir attribute
+     * @param string private recursion variable
+     * @return array
+     * @access protected
+     */
+    function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '')
+    {
+        if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) {
+            $baseinstall = $dir['attribs']['baseinstalldir'];
+        }
+        if (isset($dir['dir'])) {
+            if (!isset($dir['dir'][0])) {
+                $dir['dir'] = array($dir['dir']);
+            }
+            foreach ($dir['dir'] as $subdir) {
+                if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) {
+                    $name = '*unknown*';
+                } else {
+                    $name = $subdir['attribs']['name'];
+                }
+                $newpath = empty($path) ? $name :
+                    $path . '/' . $name;
+                $this->_getFlattenedFilelist($files, $subdir,
+                    $baseinstall, $newpath);
+            }
+        }
+        if (isset($dir['file'])) {
+            if (!isset($dir['file'][0])) {
+                $dir['file'] = array($dir['file']);
+            }
+            foreach ($dir['file'] as $file) {
+                $attrs = $file['attribs'];
+                $name = $attrs['name'];
+                if ($baseinstall && !isset($attrs['baseinstalldir'])) {
+                    $attrs['baseinstalldir'] = $baseinstall;
+                }
+                $attrs['name'] = empty($path) ? $name : $path . '/' . $name;
+                $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
+                    $attrs['name']);
+                $file['attribs'] = $attrs;
+                $files[] = $file;
+            }
+        }
+    }
+
+    function setConfig(&$config)
+    {
+        $this->_config = &$config;
+        $this->_registry = &$config->getRegistry();
+    }
+
+    function setLogger(&$logger)
+    {
+        if (!is_object($logger) || !method_exists($logger, 'log')) {
+            return PEAR::raiseError('Logger must be compatible with PEAR_Common::log');
+        }
+        $this->_logger = &$logger;
+    }
+
+    /**
+     * WARNING - do not use this function directly unless you know what you're doing
+     */
+    function setDeps($deps)
+    {
+        $this->_packageInfo['dependencies'] = $deps;
+    }
+
+    /**
+     * WARNING - do not use this function directly unless you know what you're doing
+     */
+    function setCompatible($compat)
+    {
+        $this->_packageInfo['compatible'] = $compat;
+    }
+
+    function setPackagefile($file, $archive = false)
+    {
+        $this->_packageFile = $file;
+        $this->_archiveFile = $archive ? $archive : $file;
+    }
+
+    /**
+     * Wrapper to {@link PEAR_ErrorStack::getErrors()}
+     * @param boolean determines whether to purge the error stack after retrieving
+     * @return array
+     */
+    function getValidationWarnings($purge = true)
+    {
+        return $this->_stack->getErrors($purge);
+    }
+
+    function getPackageFile()
+    {
+        return $this->_packageFile;
+    }
+
+    function getArchiveFile()
+    {
+        return $this->_archiveFile;
+    }
+
+
+    /**
+     * Directly set the array that defines this packagefile
+     *
+     * WARNING: no validation.  This should only be performed by internal methods
+     * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2
+     * @param array
+     */
+    function fromArray($pinfo)
+    {
+        unset($pinfo['old']);
+        unset($pinfo['xsdversion']);
+        $this->_incomplete = false;
+        $this->_packageInfo = $pinfo;
+    }
+
+    function isIncomplete()
+    {
+        return $this->_incomplete;
+    }
+
+    /**
+     * @return array
+     */
+    function toArray($forreg = false)
+    {
+        if (!$this->validate(PEAR_VALIDATE_NORMAL)) {
+            return false;
+        }
+        return $this->getArray($forreg);
+    }
+
+    function getArray($forReg = false)
+    {
+        if ($forReg) {
+            $arr = $this->_packageInfo;
+            $arr['old'] = array();
+            $arr['old']['version'] = $this->getVersion();
+            $arr['old']['release_date'] = $this->getDate();
+            $arr['old']['release_state'] = $this->getState();
+            $arr['old']['release_license'] = $this->getLicense();
+            $arr['old']['release_notes'] = $this->getNotes();
+            $arr['old']['release_deps'] = $this->getDeps();
+            $arr['old']['maintainers'] = $this->getMaintainers();
+            $arr['xsdversion'] = '2.0';
+            return $arr;
+        } else {
+            $info = $this->_packageInfo;
+            unset($info['dirtree']);
+            if (isset($info['_lastversion'])) {
+                unset($info['_lastversion']);
+            }
+            if (isset($info['#binarypackage'])) {
+                unset($info['#binarypackage']);
+            }
+            return $info;
+        }
+    }
+
+    function packageInfo($field)
+    {
+        $arr = $this->getArray(true);
+        if ($field == 'state') {
+            return $arr['stability']['release'];
+        }
+        if ($field == 'api-version') {
+            return $arr['version']['api'];
+        }
+        if ($field == 'api-state') {
+            return $arr['stability']['api'];
+        }
+        if (isset($arr['old'][$field])) {
+            if (!is_string($arr['old'][$field])) {
+                return null;
+            }
+            return $arr['old'][$field];
+        }
+        if (isset($arr[$field])) {
+            if (!is_string($arr[$field])) {
+                return null;
+            }
+            return $arr[$field];
+        }
+        return null;
+    }
+
+    function getName()
+    {
+        return $this->getPackage();
+    }
+
+    function getPackage()
+    {
+        if (isset($this->_packageInfo['name'])) {
+            return $this->_packageInfo['name'];
+        }
+        return false;
+    }
+
+    function getChannel()
+    {
+        if (isset($this->_packageInfo['uri'])) {
+            return '__uri';
+        }
+        if (isset($this->_packageInfo['channel'])) {
+            return strtolower($this->_packageInfo['channel']);
+        }
+        return false;
+    }
+
+    function getUri()
+    {
+        if (isset($this->_packageInfo['uri'])) {
+            return $this->_packageInfo['uri'];
+        }
+        return false;
+    }
+
+    function getExtends()
+    {
+        if (isset($this->_packageInfo['extends'])) {
+            return $this->_packageInfo['extends'];
+        }
+        return false;
+    }
+
+    function getSummary()
+    {
+        if (isset($this->_packageInfo['summary'])) {
+            return $this->_packageInfo['summary'];
+        }
+        return false;
+    }
+
+    function getDescription()
+    {
+        if (isset($this->_packageInfo['description'])) {
+            return $this->_packageInfo['description'];
+        }
+        return false;
+    }
+
+    function getMaintainers($raw = false)
+    {
+        if (!isset($this->_packageInfo['lead'])) {
+            return false;
+        }
+        if ($raw) {
+            $ret = array('lead' => $this->_packageInfo['lead']);
+            (isset($this->_packageInfo['developer'])) ?
+                $ret['developer'] = $this->_packageInfo['developer'] :null;
+            (isset($this->_packageInfo['contributor'])) ?
+                $ret['contributor'] = $this->_packageInfo['contributor'] :null;
+            (isset($this->_packageInfo['helper'])) ?
+                $ret['helper'] = $this->_packageInfo['helper'] :null;
+            return $ret;
+        } else {
+            $ret = array();
+            $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] :
+                array($this->_packageInfo['lead']);
+            foreach ($leads as $lead) {
+                $s = $lead;
+                $s['handle'] = $s['user'];
+                unset($s['user']);
+                $s['role'] = 'lead';
+                $ret[] = $s;
+            }
+            if (isset($this->_packageInfo['developer'])) {
+                $leads = isset($this->_packageInfo['developer'][0]) ?
+                    $this->_packageInfo['developer'] :
+                    array($this->_packageInfo['developer']);
+                foreach ($leads as $maintainer) {
+                    $s = $maintainer;
+                    $s['handle'] = $s['user'];
+                    unset($s['user']);
+                    $s['role'] = 'developer';
+                    $ret[] = $s;
+                }
+            }
+            if (isset($this->_packageInfo['contributor'])) {
+                $leads = isset($this->_packageInfo['contributor'][0]) ?
+                    $this->_packageInfo['contributor'] :
+                    array($this->_packageInfo['contributor']);
+                foreach ($leads as $maintainer) {
+                    $s = $maintainer;
+                    $s['handle'] = $s['user'];
+                    unset($s['user']);
+                    $s['role'] = 'contributor';
+                    $ret[] = $s;
+                }
+            }
+            if (isset($this->_packageInfo['helper'])) {
+                $leads = isset($this->_packageInfo['helper'][0]) ?
+                    $this->_packageInfo['helper'] :
+                    array($this->_packageInfo['helper']);
+                foreach ($leads as $maintainer) {
+                    $s = $maintainer;
+                    $s['handle'] = $s['user'];
+                    unset($s['user']);
+                    $s['role'] = 'helper';
+                    $ret[] = $s;
+                }
+            }
+            return $ret;
+        }
+        return false;
+    }
+
+    function getLeads()
+    {
+        if (isset($this->_packageInfo['lead'])) {
+            return $this->_packageInfo['lead'];
+        }
+        return false;
+    }
+
+    function getDevelopers()
+    {
+        if (isset($this->_packageInfo['developer'])) {
+            return $this->_packageInfo['developer'];
+        }
+        return false;
+    }
+
+    function getContributors()
+    {
+        if (isset($this->_packageInfo['contributor'])) {
+            return $this->_packageInfo['contributor'];
+        }
+        return false;
+    }
+
+    function getHelpers()
+    {
+        if (isset($this->_packageInfo['helper'])) {
+            return $this->_packageInfo['helper'];
+        }
+        return false;
+    }
+
+    function setDate($date)
+    {
+        if (!isset($this->_packageInfo['date'])) {
+            // ensure that the extends tag is set up in the right location
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('time', 'version',
+                    'stability', 'license', 'notes', 'contents', 'compatible',
+                    'dependencies', 'providesextension', 'srcpackage', 'srcuri',
+                    'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
+                    'zendextbinrelease', 'bundle', 'changelog'), array(), 'date');
+        }
+        $this->_packageInfo['date'] = $date;
+        $this->_isValid = 0;
+    }
+
+    function setTime($time)
+    {
+        $this->_isValid = 0;
+        if (!isset($this->_packageInfo['time'])) {
+            // ensure that the time tag is set up in the right location
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                    array('version',
+                    'stability', 'license', 'notes', 'contents', 'compatible',
+                    'dependencies', 'providesextension', 'srcpackage', 'srcuri',
+                    'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease',
+                    'zendextbinrelease', 'bundle', 'changelog'), $time, 'time');
+        }
+        $this->_packageInfo['time'] = $time;
+    }
+
+    function getDate()
+    {
+        if (isset($this->_packageInfo['date'])) {
+            return $this->_packageInfo['date'];
+        }
+        return false;
+    }
+
+    function getTime()
+    {
+        if (isset($this->_packageInfo['time'])) {
+            return $this->_packageInfo['time'];
+        }
+        return false;
+    }
+
+    /**
+     * @param package|api version category to return
+     */
+    function getVersion($key = 'release')
+    {
+        if (isset($this->_packageInfo['version'][$key])) {
+            return $this->_packageInfo['version'][$key];
+        }
+        return false;
+    }
+
+    function getStability()
+    {
+        if (isset($this->_packageInfo['stability'])) {
+            return $this->_packageInfo['stability'];
+        }
+        return false;
+    }
+
+    function getState($key = 'release')
+    {
+        if (isset($this->_packageInfo['stability'][$key])) {
+            return $this->_packageInfo['stability'][$key];
+        }
+        return false;
+    }
+
+    function getLicense($raw = false)
+    {
+        if (isset($this->_packageInfo['license'])) {
+            if ($raw) {
+                return $this->_packageInfo['license'];
+            }
+            if (is_array($this->_packageInfo['license'])) {
+                return $this->_packageInfo['license']['_content'];
+            } else {
+                return $this->_packageInfo['license'];
+            }
+        }
+        return false;
+    }
+
+    function getLicenseLocation()
+    {
+        if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) {
+            return false;
+        }
+        return $this->_packageInfo['license']['attribs'];
+    }
+
+    function getNotes()
+    {
+        if (isset($this->_packageInfo['notes'])) {
+            return $this->_packageInfo['notes'];
+        }
+        return false;
+    }
+
+    /**
+     * Return the <usesrole> tag contents, if any
+     * @return array|false
+     */
+    function getUsesrole()
+    {
+        if (isset($this->_packageInfo['usesrole'])) {
+            return $this->_packageInfo['usesrole'];
+        }
+        return false;
+    }
+
+    /**
+     * Return the <usestask> tag contents, if any
+     * @return array|false
+     */
+    function getUsestask()
+    {
+        if (isset($this->_packageInfo['usestask'])) {
+            return $this->_packageInfo['usestask'];
+        }
+        return false;
+    }
+
+    /**
+     * This should only be used to retrieve filenames and install attributes
+     */
+    function getFilelist($preserve = false)
+    {
+        if (isset($this->_packageInfo['filelist']) && !$preserve) {
+            return $this->_packageInfo['filelist'];
+        }
+        $this->flattenFilelist();
+        if ($contents = $this->getContents()) {
+            $ret = array();
+            if (!isset($contents['dir'])) {
+                return false;
+            }
+            if (!isset($contents['dir']['file'][0])) {
+                $contents['dir']['file'] = array($contents['dir']['file']);
+            }
+            foreach ($contents['dir']['file'] as $file) {
+                $name = $file['attribs']['name'];
+                if (!$preserve) {
+                    $file = $file['attribs'];
+                }
+                $ret[$name] = $file;
+            }
+            if (!$preserve) {
+                $this->_packageInfo['filelist'] = $ret;
+            }
+            return $ret;
+        }
+        return false;
+    }
+
+    /**
+     * Return configure options array, if any
+     *
+     * @return array|false
+     */
+    function getConfigureOptions()
+    {
+        if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
+            return false;
+        }
+
+        $releases = $this->getReleases();
+        if (isset($releases[0])) {
+            $releases = $releases[0];
+        }
+
+        if (isset($releases['configureoption'])) {
+            if (!isset($releases['configureoption'][0])) {
+                $releases['configureoption'] = array($releases['configureoption']);
+            }
+
+            for ($i = 0; $i < count($releases['configureoption']); $i++) {
+                $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs'];
+            }
+
+            return $releases['configureoption'];
+        }
+
+        return false;
+    }
+
+    /**
+     * This is only used at install-time, after all serialization
+     * is over.
+     */
+    function resetFilelist()
+    {
+        $this->_packageInfo['filelist'] = array();
+    }
+
+    /**
+     * Retrieve a list of files that should be installed on this computer
+     * @return array
+     */
+    function getInstallationFilelist($forfilecheck = false)
+    {
+        $contents = $this->getFilelist(true);
+        if (isset($contents['dir']['attribs']['baseinstalldir'])) {
+            $base = $contents['dir']['attribs']['baseinstalldir'];
+        }
+        if (isset($this->_packageInfo['bundle'])) {
+            return PEAR::raiseError(
+                'Exception: bundles should be handled in download code only');
+        }
+        $release = $this->getReleases();
+        if ($release) {
+            if (!isset($release[0])) {
+                if (!isset($release['installconditions']) && !isset($release['filelist'])) {
+                    if ($forfilecheck) {
+                        return $this->getFilelist();
+                    }
+                    return $contents;
+                }
+                $release = array($release);
+            }
+            $depchecker = &$this->getPEARDependency2($this->_config, array(),
+                array('channel' => $this->getChannel(), 'package' => $this->getPackage()),
+                PEAR_VALIDATE_INSTALLING);
+            foreach ($release as $instance) {
+                if (isset($instance['installconditions'])) {
+                    $installconditions = $instance['installconditions'];
+                    if (is_array($installconditions)) {
+                        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                        foreach ($installconditions as $type => $conditions) {
+                            if (!isset($conditions[0])) {
+                                $conditions = array($conditions);
+                            }
+                            foreach ($conditions as $condition) {
+                                $ret = $depchecker->{"validate{$type}Dependency"}($condition);
+                                if (PEAR::isError($ret)) {
+                                    PEAR::popErrorHandling();
+                                    continue 3; // skip this release
+                                }
+                            }
+                        }
+                        PEAR::popErrorHandling();
+                    }
+                }
+                // this is the release to use
+                if (isset($instance['filelist'])) {
+                    // ignore files
+                    if (isset($instance['filelist']['ignore'])) {
+                        $ignore = isset($instance['filelist']['ignore'][0]) ?
+                            $instance['filelist']['ignore'] :
+                            array($instance['filelist']['ignore']);
+                        foreach ($ignore as $ig) {
+                            unset ($contents[$ig['attribs']['name']]);
+                        }
+                    }
+                    // install files as this name
+                    if (isset($instance['filelist']['install'])) {
+                        $installas = isset($instance['filelist']['install'][0]) ?
+                            $instance['filelist']['install'] :
+                            array($instance['filelist']['install']);
+                        foreach ($installas as $as) {
+                            $contents[$as['attribs']['name']]['attribs']['install-as'] =
+                                $as['attribs']['as'];
+                        }
+                    }
+                }
+                if ($forfilecheck) {
+                    foreach ($contents as $file => $attrs) {
+                        $contents[$file] = $attrs['attribs'];
+                    }
+                }
+                return $contents;
+            }
+        } else { // simple release - no installconditions or install-as
+            if ($forfilecheck) {
+                return $this->getFilelist();
+            }
+            return $contents;
+        }
+        // no releases matched
+        return PEAR::raiseError('No releases in package.xml matched the existing operating ' .
+            'system, extensions installed, or architecture, cannot install');
+    }
+
+    /**
+     * This is only used at install-time, after all serialization
+     * is over.
+     * @param string file name
+     * @param string installed path
+     */
+    function setInstalledAs($file, $path)
+    {
+        if ($path) {
+            return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
+        }
+        unset($this->_packageInfo['filelist'][$file]['installed_as']);
+    }
+
+    function getInstalledLocation($file)
+    {
+        if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) {
+            return $this->_packageInfo['filelist'][$file]['installed_as'];
+        }
+        return false;
+    }
+
+    /**
+     * This is only used at install-time, after all serialization
+     * is over.
+     */
+    function installedFile($file, $atts)
+    {
+        if (isset($this->_packageInfo['filelist'][$file])) {
+            $this->_packageInfo['filelist'][$file] =
+                array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']);
+        } else {
+            $this->_packageInfo['filelist'][$file] = $atts['attribs'];
+        }
+    }
+
+    /**
+     * Retrieve the contents tag
+     */
+    function getContents()
+    {
+        if (isset($this->_packageInfo['contents'])) {
+            return $this->_packageInfo['contents'];
+        }
+        return false;
+    }
+
+    /**
+     * @param string full path to file
+     * @param string attribute name
+     * @param string attribute value
+     * @param int risky but fast - use this to choose a file based on its position in the list
+     *            of files.  Index is zero-based like PHP arrays.
+     * @return bool success of operation
+     */
+    function setFileAttribute($filename, $attr, $value, $index = false)
+    {
+        $this->_isValid = 0;
+        if (in_array($attr, array('role', 'name', 'baseinstalldir'))) {
+            $this->_filesValid = false;
+        }
+        if ($index !== false &&
+              isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) {
+            $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value;
+            return true;
+        }
+        if (!isset($this->_packageInfo['contents']['dir']['file'])) {
+            return false;
+        }
+        $files = $this->_packageInfo['contents']['dir']['file'];
+        if (!isset($files[0])) {
+            $files = array($files);
+            $ind = false;
+        } else {
+            $ind = true;
+        }
+        foreach ($files as $i => $file) {
+            if (isset($file['attribs'])) {
+                if ($file['attribs']['name'] == $filename) {
+                    if ($ind) {
+                        $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value;
+                    } else {
+                        $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value;
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    function setDirtree($path)
+    {
+        if (!isset($this->_packageInfo['dirtree'])) {
+            $this->_packageInfo['dirtree'] = array();
+        }
+        $this->_packageInfo['dirtree'][$path] = true;
+    }
+
+    function getDirtree()
+    {
+        if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) {
+            return $this->_packageInfo['dirtree'];
+        }
+        return false;
+    }
+
+    function resetDirtree()
+    {
+        unset($this->_packageInfo['dirtree']);
+    }
+
+    /**
+     * Determines whether this package claims it is compatible with the version of
+     * the package that has a recommended version dependency
+     * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package
+     * @return boolean
+     */
+    function isCompatible($pf)
+    {
+        if (!isset($this->_packageInfo['compatible'])) {
+            return false;
+        }
+        if (!isset($this->_packageInfo['channel'])) {
+            return false;
+        }
+        $me = $pf->getVersion();
+        $compatible = $this->_packageInfo['compatible'];
+        if (!isset($compatible[0])) {
+            $compatible = array($compatible);
+        }
+        $found = false;
+        foreach ($compatible as $info) {
+            if (strtolower($info['name']) == strtolower($pf->getPackage())) {
+                if (strtolower($info['channel']) == strtolower($pf->getChannel())) {
+                    $found = true;
+                    break;
+                }
+            }
+        }
+        if (!$found) {
+            return false;
+        }
+        if (isset($info['exclude'])) {
+            if (!isset($info['exclude'][0])) {
+                $info['exclude'] = array($info['exclude']);
+            }
+            foreach ($info['exclude'] as $exclude) {
+                if (version_compare($me, $exclude, '==')) {
+                    return false;
+                }
+            }
+        }
+        if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @return array|false
+     */
+    function getCompatible()
+    {
+        if (isset($this->_packageInfo['compatible'])) {
+            return $this->_packageInfo['compatible'];
+        }
+        return false;
+    }
+
+    function getDependencies()
+    {
+        if (isset($this->_packageInfo['dependencies'])) {
+            return $this->_packageInfo['dependencies'];
+        }
+        return false;
+    }
+
+    function isSubpackageOf($p)
+    {
+        return $p->isSubpackage($this);
+    }
+
+    /**
+     * Determines whether the passed in package is a subpackage of this package.
+     *
+     * No version checking is done, only name verification.
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @return bool
+     */
+    function isSubpackage($p)
+    {
+        $sub = array();
+        if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) {
+            $sub = $this->_packageInfo['dependencies']['required']['subpackage'];
+            if (!isset($sub[0])) {
+                $sub = array($sub);
+            }
+        }
+        if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) {
+            $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage'];
+            if (!isset($sub1[0])) {
+                $sub1 = array($sub1);
+            }
+            $sub = array_merge($sub, $sub1);
+        }
+        if (isset($this->_packageInfo['dependencies']['group'])) {
+            $group = $this->_packageInfo['dependencies']['group'];
+            if (!isset($group[0])) {
+                $group = array($group);
+            }
+            foreach ($group as $deps) {
+                if (isset($deps['subpackage'])) {
+                    $sub2 = $deps['subpackage'];
+                    if (!isset($sub2[0])) {
+                        $sub2 = array($sub2);
+                    }
+                    $sub = array_merge($sub, $sub2);
+                }
+            }
+        }
+        foreach ($sub as $dep) {
+            if (strtolower($dep['name']) == strtolower($p->getPackage())) {
+                if (isset($dep['channel'])) {
+                    if (strtolower($dep['channel']) == strtolower($p->getChannel())) {
+                        return true;
+                    }
+                } else {
+                    if ($dep['uri'] == $p->getURI()) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    function dependsOn($package, $channel)
+    {
+        if (!($deps = $this->getDependencies())) {
+            return false;
+        }
+        foreach (array('package', 'subpackage') as $type) {
+            foreach (array('required', 'optional') as $needed) {
+                if (isset($deps[$needed][$type])) {
+                    if (!isset($deps[$needed][$type][0])) {
+                        $deps[$needed][$type] = array($deps[$needed][$type]);
+                    }
+                    foreach ($deps[$needed][$type] as $dep) {
+                        $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
+                        if (strtolower($dep['name']) == strtolower($package) &&
+                              $depchannel == $channel) {
+                            return true;
+                        }
+                    }
+                }
+            }
+            if (isset($deps['group'])) {
+                if (!isset($deps['group'][0])) {
+                    $dep['group'] = array($deps['group']);
+                }
+                foreach ($deps['group'] as $group) {
+                    if (isset($group[$type])) {
+                        if (!is_array($group[$type])) {
+                            $group[$type] = array($group[$type]);
+                        }
+                        foreach ($group[$type] as $dep) {
+                            $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
+                            if (strtolower($dep['name']) == strtolower($package) &&
+                                  $depchannel == $channel) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the contents of a dependency group
+     * @param string
+     * @return array|false
+     */
+    function getDependencyGroup($name)
+    {
+        $name = strtolower($name);
+        if (!isset($this->_packageInfo['dependencies']['group'])) {
+            return false;
+        }
+        $groups = $this->_packageInfo['dependencies']['group'];
+        if (!isset($groups[0])) {
+            $groups = array($groups);
+        }
+        foreach ($groups as $group) {
+            if (strtolower($group['attribs']['name']) == $name) {
+                return $group;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Retrieve a partial package.xml 1.0 representation of dependencies
+     *
+     * a very limited representation of dependencies is returned by this method.
+     * The <exclude> tag for excluding certain versions of a dependency is
+     * completely ignored.  In addition, dependency groups are ignored, with the
+     * assumption that all dependencies in dependency groups are also listed in
+     * the optional group that work with all dependency groups
+     * @param boolean return package.xml 2.0 <dependencies> tag
+     * @return array|false
+     */
+    function getDeps($raw = false, $nopearinstaller = false)
+    {
+        if (isset($this->_packageInfo['dependencies'])) {
+            if ($raw) {
+                return $this->_packageInfo['dependencies'];
+            }
+            $ret = array();
+            $map = array(
+                'php' => 'php',
+                'package' => 'pkg',
+                'subpackage' => 'pkg',
+                'extension' => 'ext',
+                'os' => 'os',
+                'pearinstaller' => 'pkg',
+                );
+            foreach (array('required', 'optional') as $type) {
+                $optional = ($type == 'optional') ? 'yes' : 'no';
+                if (!isset($this->_packageInfo['dependencies'][$type])
+                    || empty($this->_packageInfo['dependencies'][$type])) {
+                    continue;
+                }
+                foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) {
+                    if ($dtype == 'pearinstaller' && $nopearinstaller) {
+                        continue;
+                    }
+                    if (!isset($deps[0])) {
+                        $deps = array($deps);
+                    }
+                    foreach ($deps as $dep) {
+                        if (!isset($map[$dtype])) {
+                            // no support for arch type
+                            continue;
+                        }
+                        if ($dtype == 'pearinstaller') {
+                            $dep['name'] = 'PEAR';
+                            $dep['channel'] = 'pear.php.net';
+                        }
+                        $s = array('type' => $map[$dtype]);
+                        if (isset($dep['channel'])) {
+                            $s['channel'] = $dep['channel'];
+                        }
+                        if (isset($dep['uri'])) {
+                            $s['uri'] = $dep['uri'];
+                        }
+                        if (isset($dep['name'])) {
+                            $s['name'] = $dep['name'];
+                        }
+                        if (isset($dep['conflicts'])) {
+                            $s['rel'] = 'not';
+                        } else {
+                            if (!isset($dep['min']) &&
+                                  !isset($dep['max'])) {
+                                $s['rel'] = 'has';
+                                $s['optional'] = $optional;
+                            } elseif (isset($dep['min']) &&
+                                  isset($dep['max'])) {
+                                $s['rel'] = 'ge';
+                                $s1 = $s;
+                                $s1['rel'] = 'le';
+                                $s['version'] = $dep['min'];
+                                $s1['version'] = $dep['max'];
+                                if (isset($dep['channel'])) {
+                                    $s1['channel'] = $dep['channel'];
+                                }
+                                if ($dtype != 'php') {
+                                    $s['name'] = $dep['name'];
+                                    $s1['name'] = $dep['name'];
+                                }
+                                $s['optional'] = $optional;
+                                $s1['optional'] = $optional;
+                                $ret[] = $s1;
+                            } elseif (isset($dep['min'])) {
+                                if (isset($dep['exclude']) &&
+                                      $dep['exclude'] == $dep['min']) {
+                                    $s['rel'] = 'gt';
+                                } else {
+                                    $s['rel'] = 'ge';
+                                }
+                                $s['version'] = $dep['min'];
+                                $s['optional'] = $optional;
+                                if ($dtype != 'php') {
+                                    $s['name'] = $dep['name'];
+                                }
+                            } elseif (isset($dep['max'])) {
+                                if (isset($dep['exclude']) &&
+                                      $dep['exclude'] == $dep['max']) {
+                                    $s['rel'] = 'lt';
+                                } else {
+                                    $s['rel'] = 'le';
+                                }
+                                $s['version'] = $dep['max'];
+                                $s['optional'] = $optional;
+                                if ($dtype != 'php') {
+                                    $s['name'] = $dep['name'];
+                                }
+                            }
+                        }
+                        $ret[] = $s;
+                    }
+                }
+            }
+            if (count($ret)) {
+                return $ret;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false
+     */
+    function getPackageType()
+    {
+        if (isset($this->_packageInfo['phprelease'])) {
+            return 'php';
+        }
+        if (isset($this->_packageInfo['extsrcrelease'])) {
+            return 'extsrc';
+        }
+        if (isset($this->_packageInfo['extbinrelease'])) {
+            return 'extbin';
+        }
+        if (isset($this->_packageInfo['zendextsrcrelease'])) {
+            return 'zendextsrc';
+        }
+        if (isset($this->_packageInfo['zendextbinrelease'])) {
+            return 'zendextbin';
+        }
+        if (isset($this->_packageInfo['bundle'])) {
+            return 'bundle';
+        }
+        return false;
+    }
+
+    /**
+     * @return array|false
+     */
+    function getReleases()
+    {
+        $type = $this->getPackageType();
+        if ($type != 'bundle') {
+            $type .= 'release';
+        }
+        if ($this->getPackageType() && isset($this->_packageInfo[$type])) {
+            return $this->_packageInfo[$type];
+        }
+        return false;
+    }
+
+    /**
+     * @return array
+     */
+    function getChangelog()
+    {
+        if (isset($this->_packageInfo['changelog'])) {
+            return $this->_packageInfo['changelog'];
+        }
+        return false;
+    }
+
+    function hasDeps()
+    {
+        return isset($this->_packageInfo['dependencies']);
+    }
+
+    function getPackagexmlVersion()
+    {
+        if (isset($this->_packageInfo['zendextsrcrelease'])) {
+            return '2.1';
+        }
+        if (isset($this->_packageInfo['zendextbinrelease'])) {
+            return '2.1';
+        }
+        return '2.0';
+    }
+
+    /**
+     * @return array|false
+     */
+    function getSourcePackage()
+    {
+        if (isset($this->_packageInfo['extbinrelease']) ||
+              isset($this->_packageInfo['zendextbinrelease'])) {
+            return array('channel' => $this->_packageInfo['srcchannel'],
+                         'package' => $this->_packageInfo['srcpackage']);
+        }
+        return false;
+    }
+
+    function getBundledPackages()
+    {
+        if (isset($this->_packageInfo['bundle'])) {
+            return $this->_packageInfo['contents']['bundledpackage'];
+        }
+        return false;
+    }
+
+    function getLastModified()
+    {
+        if (isset($this->_packageInfo['_lastmodified'])) {
+            return $this->_packageInfo['_lastmodified'];
+        }
+        return false;
+    }
+
+    /**
+     * Get the contents of a file listed within the package.xml
+     * @param string
+     * @return string
+     */
+    function getFileContents($file)
+    {
+        if ($this->_archiveFile == $this->_packageFile) { // unpacked
+            $dir = dirname($this->_packageFile);
+            $file = $dir . DIRECTORY_SEPARATOR . $file;
+            $file = str_replace(array('/', '\\'),
+                array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
+            if (file_exists($file) && is_readable($file)) {
+                return implode('', file($file));
+            }
+        } else { // tgz
+            $tar = &new Archive_Tar($this->_archiveFile);
+            $tar->pushErrorHandling(PEAR_ERROR_RETURN);
+            if ($file != 'package.xml' && $file != 'package2.xml') {
+                $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
+            }
+            $file = $tar->extractInString($file);
+            $tar->popErrorHandling();
+            if (PEAR::isError($file)) {
+                return PEAR::raiseError("Cannot locate file '$file' in archive");
+            }
+            return $file;
+        }
+    }
+
+    function &getRW()
+    {
+        if (!class_exists('PEAR_PackageFile_v2_rw')) {
+            require_once 'PEAR/PackageFile/v2/rw.php';
+        }
+        $a = new PEAR_PackageFile_v2_rw;
+        foreach (get_object_vars($this) as $name => $unused) {
+            if (!isset($this->$name)) {
+                continue;
+            }
+            if ($name == '_config' || $name == '_logger'|| $name == '_registry' ||
+                  $name == '_stack') {
+                $a->$name = &$this->$name;
+            } else {
+                $a->$name = $this->$name;
+            }
+        }
+        return $a;
+    }
+
+    function &getDefaultGenerator()
+    {
+        if (!class_exists('PEAR_PackageFile_Generator_v2')) {
+            require_once 'PEAR/PackageFile/Generator/v2.php';
+        }
+        $a = &new PEAR_PackageFile_Generator_v2($this);
+        return $a;
+    }
+
+    function analyzeSourceCode($file, $string = false)
+    {
+        if (!isset($this->_v2Validator) ||
+              !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) {
+            if (!class_exists('PEAR_PackageFile_v2_Validator')) {
+                require_once 'PEAR/PackageFile/v2/Validator.php';
+            }
+            $this->_v2Validator = new PEAR_PackageFile_v2_Validator;
+        }
+        return $this->_v2Validator->analyzeSourceCode($file, $string);
+    }
+
+    function validate($state = PEAR_VALIDATE_NORMAL)
+    {
+        if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) {
+            return false;
+        }
+        if (!isset($this->_v2Validator) ||
+              !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) {
+            if (!class_exists('PEAR_PackageFile_v2_Validator')) {
+                require_once 'PEAR/PackageFile/v2/Validator.php';
+            }
+            $this->_v2Validator = new PEAR_PackageFile_v2_Validator;
+        }
+        if (isset($this->_packageInfo['xsdversion'])) {
+            unset($this->_packageInfo['xsdversion']);
+        }
+        return $this->_v2Validator->validate($this, $state);
+    }
+
+    function getTasksNs()
+    {
+        if (!isset($this->_tasksNs)) {
+            if (isset($this->_packageInfo['attribs'])) {
+                foreach ($this->_packageInfo['attribs'] as $name => $value) {
+                    if ($value == 'http://pear.php.net/dtd/tasks-1.0') {
+                        $this->_tasksNs = str_replace('xmlns:', '', $name);
+                        break;
+                    }
+                }
+            }
+        }
+        return $this->_tasksNs;
+    }
+
+    /**
+     * Determine whether a task name is a valid task.  Custom tasks may be defined
+     * using subdirectories by putting a "-" in the name, as in <tasks:mycustom-task>
+     *
+     * Note that this method will auto-load the task class file and test for the existence
+     * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class
+     * PEAR_Task_mycustom_task
+     * @param string
+     * @return boolean
+     */
+    function getTask($task)
+    {
+        $this->getTasksNs();
+        // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace
+        $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task);
+        $taskfile = str_replace(' ', '/', ucwords($task));
+        $task = str_replace(array(' ', '/'), '_', ucwords($task));
+        if (class_exists("PEAR_Task_$task")) {
+            return "PEAR_Task_$task";
+        }
+        $fp = @fopen("PEAR/Task/$taskfile.php", 'r', true);
+        if ($fp) {
+            fclose($fp);
+            require_once "PEAR/Task/$taskfile.php";
+            return "PEAR_Task_$task";
+        }
+        return false;
+    }
+
+    /**
+     * Key-friendly array_splice
+     * @param tagname to splice a value in before
+     * @param mixed the value to splice in
+     * @param string the new tag name
+     */
+    function _ksplice($array, $key, $value, $newkey)
+    {
+        $offset = array_search($key, array_keys($array));
+        $after = array_slice($array, $offset);
+        $before = array_slice($array, 0, $offset);
+        $before[$newkey] = $value;
+        return array_merge($before, $after);
+    }
+
+    /**
+     * @param array a list of possible keys, in the order they may occur
+     * @param mixed contents of the new package.xml tag
+     * @param string tag name
+     * @access private
+     */
+    function _insertBefore($array, $keys, $contents, $newkey)
+    {
+        foreach ($keys as $key) {
+            if (isset($array[$key])) {
+                return $array = $this->_ksplice($array, $key, $contents, $newkey);
+            }
+        }
+        $array[$newkey] = $contents;
+        return $array;
+    }
+
+    /**
+     * @param subsection of {@link $_packageInfo}
+     * @param array|string tag contents
+     * @param array format:
+     * <pre>
+     * array(
+     *   tagname => array(list of tag names that follow this one),
+     *   childtagname => array(list of child tag names that follow this one),
+     * )
+     * </pre>
+     *
+     * This allows construction of nested tags
+     * @access private
+     */
+    function _mergeTag($manip, $contents, $order)
+    {
+        if (count($order)) {
+            foreach ($order as $tag => $curorder) {
+                if (!isset($manip[$tag])) {
+                    // ensure that the tag is set up
+                    $manip = $this->_insertBefore($manip, $curorder, array(), $tag);
+                }
+                if (count($order) > 1) {
+                    $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1));
+                    return $manip;
+                }
+            }
+        } else {
+            return $manip;
+        }
+        if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) {
+            $manip[$tag][] = $contents;
+        } else {
+            if (!count($manip[$tag])) {
+                $manip[$tag] = $contents;
+            } else {
+                $manip[$tag] = array($manip[$tag]);
+                $manip[$tag][] = $contents;
+            }
+        }
+        return $manip;
+    }
+}
+?>
diff --git a/lib/php/PEAR/PackageFile/v2/Validator.php b/lib/php/PEAR/PackageFile/v2/Validator.php
new file mode 100644
index 00000000..616b7e7e
--- /dev/null
+++ b/lib/php/PEAR/PackageFile/v2/Validator.php
@@ -0,0 +1,2154 @@
+<?php
+/**
+ * PEAR_PackageFile_v2, package.xml version 2.0, read/write version
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Validator.php 277885 2009-03-27 19:29:31Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a8
+ */
+/**
+ * Private validation class used by PEAR_PackageFile_v2 - do not use directly, its
+ * sole purpose is to split up the PEAR/PackageFile/v2.php file to make it smaller
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a8
+ * @access private
+ */
+class PEAR_PackageFile_v2_Validator
+{
+    /**
+     * @var array
+     */
+    var $_packageInfo;
+    /**
+     * @var PEAR_PackageFile_v2
+     */
+    var $_pf;
+    /**
+     * @var PEAR_ErrorStack
+     */
+    var $_stack;
+    /**
+     * @var int
+     */
+    var $_isValid = 0;
+    /**
+     * @var int
+     */
+    var $_filesValid = 0;
+    /**
+     * @var int
+     */
+    var $_curState = 0;
+    /**
+     * @param PEAR_PackageFile_v2
+     * @param int
+     */
+    function validate(&$pf, $state = PEAR_VALIDATE_NORMAL)
+    {
+        $this->_pf = &$pf;
+        $this->_curState = $state;
+        $this->_packageInfo = $this->_pf->getArray();
+        $this->_isValid = $this->_pf->_isValid;
+        $this->_filesValid = $this->_pf->_filesValid;
+        $this->_stack = &$pf->_stack;
+        $this->_stack->getErrors(true);
+        if (($this->_isValid & $state) == $state) {
+            return true;
+        }
+        if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) {
+            return false;
+        }
+        if (!isset($this->_packageInfo['attribs']['version']) ||
+              ($this->_packageInfo['attribs']['version'] != '2.0' &&
+               $this->_packageInfo['attribs']['version'] != '2.1')
+        ) {
+            $this->_noPackageVersion();
+        }
+        $structure =
+        array(
+            'name',
+            'channel|uri',
+            '*extends', // can't be multiple, but this works fine
+            'summary',
+            'description',
+            '+lead', // these all need content checks
+            '*developer',
+            '*contributor',
+            '*helper',
+            'date',
+            '*time',
+            'version',
+            'stability',
+            'license->?uri->?filesource',
+            'notes',
+            'contents', //special validation needed
+            '*compatible',
+            'dependencies', //special validation needed
+            '*usesrole',
+            '*usestask', // reserve these for 1.4.0a1 to implement
+                         // this will allow a package.xml to gracefully say it
+                         // needs a certain package installed in order to implement a role or task
+            '*providesextension',
+            '*srcpackage|*srcuri',
+            '+phprelease|+extsrcrelease|+extbinrelease|' .
+                '+zendextsrcrelease|+zendextbinrelease|bundle', //special validation needed
+            '*changelog',
+        );
+        $test = $this->_packageInfo;
+        if (isset($test['dependencies']) &&
+              isset($test['dependencies']['required']) &&
+              isset($test['dependencies']['required']['pearinstaller']) &&
+              isset($test['dependencies']['required']['pearinstaller']['min']) &&
+              version_compare('1.9.0',
+                $test['dependencies']['required']['pearinstaller']['min'], '<')
+        ) {
+            $this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']);
+            return false;
+        }
+        // ignore post-installation array fields
+        if (array_key_exists('filelist', $test)) {
+            unset($test['filelist']);
+        }
+        if (array_key_exists('_lastmodified', $test)) {
+            unset($test['_lastmodified']);
+        }
+        if (array_key_exists('#binarypackage', $test)) {
+            unset($test['#binarypackage']);
+        }
+        if (array_key_exists('old', $test)) {
+            unset($test['old']);
+        }
+        if (array_key_exists('_lastversion', $test)) {
+            unset($test['_lastversion']);
+        }
+        if (!$this->_stupidSchemaValidate($structure, $test, '<package>')) {
+            return false;
+        }
+        if (empty($this->_packageInfo['name'])) {
+            $this->_tagCannotBeEmpty('name');
+        }
+        $test = isset($this->_packageInfo['uri']) ? 'uri' :'channel';
+        if (empty($this->_packageInfo[$test])) {
+            $this->_tagCannotBeEmpty($test);
+        }
+        if (is_array($this->_packageInfo['license']) &&
+              (!isset($this->_packageInfo['license']['_content']) ||
+              empty($this->_packageInfo['license']['_content']))) {
+            $this->_tagCannotBeEmpty('license');
+        } elseif (empty($this->_packageInfo['license'])) {
+            $this->_tagCannotBeEmpty('license');
+        }
+        if (empty($this->_packageInfo['summary'])) {
+            $this->_tagCannotBeEmpty('summary');
+        }
+        if (empty($this->_packageInfo['description'])) {
+            $this->_tagCannotBeEmpty('description');
+        }
+        if (empty($this->_packageInfo['date'])) {
+            $this->_tagCannotBeEmpty('date');
+        }
+        if (empty($this->_packageInfo['notes'])) {
+            $this->_tagCannotBeEmpty('notes');
+        }
+        if (isset($this->_packageInfo['time']) && empty($this->_packageInfo['time'])) {
+            $this->_tagCannotBeEmpty('time');
+        }
+        if (isset($this->_packageInfo['dependencies'])) {
+            $this->_validateDependencies();
+        }
+        if (isset($this->_packageInfo['compatible'])) {
+            $this->_validateCompatible();
+        }
+        if (!isset($this->_packageInfo['bundle'])) {
+            if (empty($this->_packageInfo['contents'])) {
+                $this->_tagCannotBeEmpty('contents');
+            }
+            if (!isset($this->_packageInfo['contents']['dir'])) {
+                $this->_filelistMustContainDir('contents');
+                return false;
+            }
+            if (isset($this->_packageInfo['contents']['file'])) {
+                $this->_filelistCannotContainFile('contents');
+                return false;
+            }
+        }
+        $this->_validateMaintainers();
+        $this->_validateStabilityVersion();
+        $fail = false;
+        if (array_key_exists('usesrole', $this->_packageInfo)) {
+            $roles = $this->_packageInfo['usesrole'];
+            if (!is_array($roles) || !isset($roles[0])) {
+                $roles = array($roles);
+            }
+            foreach ($roles as $role) {
+                if (!isset($role['role'])) {
+                    $this->_usesroletaskMustHaveRoleTask('usesrole', 'role');
+                    $fail = true;
+                } else {
+                    if (!isset($role['channel'])) {
+                        if (!isset($role['uri'])) {
+                            $this->_usesroletaskMustHaveChannelOrUri($role['role'], 'usesrole');
+                            $fail = true;
+                        }
+                    } elseif (!isset($role['package'])) {
+                        $this->_usesroletaskMustHavePackage($role['role'], 'usesrole');
+                        $fail = true;
+                    }
+                }
+            }
+        }
+        if (array_key_exists('usestask', $this->_packageInfo)) {
+            $roles = $this->_packageInfo['usestask'];
+            if (!is_array($roles) || !isset($roles[0])) {
+                $roles = array($roles);
+            }
+            foreach ($roles as $role) {
+                if (!isset($role['task'])) {
+                    $this->_usesroletaskMustHaveRoleTask('usestask', 'task');
+                    $fail = true;
+                } else {
+                    if (!isset($role['channel'])) {
+                        if (!isset($role['uri'])) {
+                            $this->_usesroletaskMustHaveChannelOrUri($role['task'], 'usestask');
+                            $fail = true;
+                        }
+                    } elseif (!isset($role['package'])) {
+                        $this->_usesroletaskMustHavePackage($role['task'], 'usestask');
+                        $fail = true;
+                    }
+                }
+            }
+        }
+
+        if ($fail) {
+            return false;
+        }
+
+        $list = $this->_packageInfo['contents'];
+        if (isset($list['dir']) && is_array($list['dir']) && isset($list['dir'][0])) {
+            $this->_multipleToplevelDirNotAllowed();
+            return $this->_isValid = 0;
+        }
+
+        $this->_validateFilelist();
+        $this->_validateRelease();
+        if (!$this->_stack->hasErrors()) {
+            $chan = $this->_pf->_registry->getChannel($this->_pf->getChannel(), true);
+            if (PEAR::isError($chan)) {
+                $this->_unknownChannel($this->_pf->getChannel());
+            } else {
+                $valpack = $chan->getValidationPackage();
+                // for channel validator packages, always use the default PEAR validator.
+                // otherwise, they can't be installed or packaged
+                $validator = $chan->getValidationObject($this->_pf->getPackage());
+                if (!$validator) {
+                    $this->_stack->push(__FUNCTION__, 'error',
+                        array_merge(
+                            array('channel' => $chan->getName(),
+                                  'package' => $this->_pf->getPackage()),
+                              $valpack
+                            ),
+                        'package "%channel%/%package%" cannot be properly validated without ' .
+                        'validation package "%channel%/%name%-%version%"');
+                    return $this->_isValid = 0;
+                }
+                $validator->setPackageFile($this->_pf);
+                $validator->validate($state);
+                $failures = $validator->getFailures();
+                foreach ($failures['errors'] as $error) {
+                    $this->_stack->push(__FUNCTION__, 'error', $error,
+                        'Channel validator error: field "%field%" - %reason%');
+                }
+                foreach ($failures['warnings'] as $warning) {
+                    $this->_stack->push(__FUNCTION__, 'warning', $warning,
+                        'Channel validator warning: field "%field%" - %reason%');
+                }
+            }
+        }
+
+        $this->_pf->_isValid = $this->_isValid = !$this->_stack->hasErrors('error');
+        if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$this->_filesValid) {
+            if ($this->_pf->getPackageType() == 'bundle') {
+                if ($this->_analyzeBundledPackages()) {
+                    $this->_filesValid = $this->_pf->_filesValid = true;
+                } else {
+                    $this->_pf->_isValid = $this->_isValid = 0;
+                }
+            } else {
+                if (!$this->_analyzePhpFiles()) {
+                    $this->_pf->_isValid = $this->_isValid = 0;
+                } else {
+                    $this->_filesValid = $this->_pf->_filesValid = true;
+                }
+            }
+        }
+
+        if ($this->_isValid) {
+            return $this->_pf->_isValid = $this->_isValid = $state;
+        }
+
+        return $this->_pf->_isValid = $this->_isValid = 0;
+    }
+
+    function _stupidSchemaValidate($structure, $xml, $root)
+    {
+        if (!is_array($xml)) {
+            $xml = array();
+        }
+        $keys = array_keys($xml);
+        reset($keys);
+        $key = current($keys);
+        while ($key == 'attribs' || $key == '_contents') {
+            $key = next($keys);
+        }
+        $unfoundtags = $optionaltags = array();
+        $ret = true;
+        $mismatch = false;
+        foreach ($structure as $struc) {
+            if ($key) {
+                $tag = $xml[$key];
+            }
+            $test = $this->_processStructure($struc);
+            if (isset($test['choices'])) {
+                $loose = true;
+                foreach ($test['choices'] as $choice) {
+                    if ($key == $choice['tag']) {
+                        $key = next($keys);
+                        while ($key == 'attribs' || $key == '_contents') {
+                            $key = next($keys);
+                        }
+                        $unfoundtags = $optionaltags = array();
+                        $mismatch = false;
+                        if ($key && $key != $choice['tag'] && isset($choice['multiple'])) {
+                            $unfoundtags[] = $choice['tag'];
+                            $optionaltags[] = $choice['tag'];
+                            if ($key) {
+                                $mismatch = true;
+                            }
+                        }
+                        $ret &= $this->_processAttribs($choice, $tag, $root);
+                        continue 2;
+                    } else {
+                        $unfoundtags[] = $choice['tag'];
+                        $mismatch = true;
+                    }
+                    if (!isset($choice['multiple']) || $choice['multiple'] != '*') {
+                        $loose = false;
+                    } else {
+                        $optionaltags[] = $choice['tag'];
+                    }
+                }
+                if (!$loose) {
+                    $this->_invalidTagOrder($unfoundtags, $key, $root);
+                    return false;
+                }
+            } else {
+                if ($key != $test['tag']) {
+                    if (isset($test['multiple']) && $test['multiple'] != '*') {
+                        $unfoundtags[] = $test['tag'];
+                        $this->_invalidTagOrder($unfoundtags, $key, $root);
+                        return false;
+                    } else {
+                        if ($key) {
+                            $mismatch = true;
+                        }
+                        $unfoundtags[] = $test['tag'];
+                        $optionaltags[] = $test['tag'];
+                    }
+                    if (!isset($test['multiple'])) {
+                        $this->_invalidTagOrder($unfoundtags, $key, $root);
+                        return false;
+                    }
+                    continue;
+                } else {
+                    $unfoundtags = $optionaltags = array();
+                    $mismatch = false;
+                }
+                $key = next($keys);
+                while ($key == 'attribs' || $key == '_contents') {
+                    $key = next($keys);
+                }
+                if ($key && $key != $test['tag'] && isset($test['multiple'])) {
+                    $unfoundtags[] = $test['tag'];
+                    $optionaltags[] = $test['tag'];
+                    $mismatch = true;
+                }
+                $ret &= $this->_processAttribs($test, $tag, $root);
+                continue;
+            }
+        }
+        if (!$mismatch && count($optionaltags)) {
+            // don't error out on any optional tags
+            $unfoundtags = array_diff($unfoundtags, $optionaltags);
+        }
+        if (count($unfoundtags)) {
+            $this->_invalidTagOrder($unfoundtags, $key, $root);
+        } elseif ($key) {
+            // unknown tags
+            $this->_invalidTagOrder('*no tags allowed here*', $key, $root);
+            while ($key = next($keys)) {
+                $this->_invalidTagOrder('*no tags allowed here*', $key, $root);
+            }
+        }
+        return $ret;
+    }
+
+    function _processAttribs($choice, $tag, $context)
+    {
+        if (isset($choice['attribs'])) {
+            if (!is_array($tag)) {
+                $tag = array($tag);
+            }
+            $tags = $tag;
+            if (!isset($tags[0])) {
+                $tags = array($tags);
+            }
+            $ret = true;
+            foreach ($tags as $i => $tag) {
+                if (!is_array($tag) || !isset($tag['attribs'])) {
+                    foreach ($choice['attribs'] as $attrib) {
+                        if ($attrib{0} != '?') {
+                            $ret &= $this->_tagHasNoAttribs($choice['tag'],
+                                $context);
+                            continue 2;
+                        }
+                    }
+                }
+                foreach ($choice['attribs'] as $attrib) {
+                    if ($attrib{0} != '?') {
+                        if (!isset($tag['attribs'][$attrib])) {
+                            $ret &= $this->_tagMissingAttribute($choice['tag'],
+                                $attrib, $context);
+                        }
+                    }
+                }
+            }
+            return $ret;
+        }
+        return true;
+    }
+
+    function _processStructure($key)
+    {
+        $ret = array();
+        if (count($pieces = explode('|', $key)) > 1) {
+            $ret['choices'] = array();
+            foreach ($pieces as $piece) {
+                $ret['choices'][] = $this->_processStructure($piece);
+            }
+            return $ret;
+        }
+        $multi = $key{0};
+        if ($multi == '+' || $multi == '*') {
+            $ret['multiple'] = $key{0};
+            $key = substr($key, 1);
+        }
+        if (count($attrs = explode('->', $key)) > 1) {
+            $ret['tag'] = array_shift($attrs);
+            $ret['attribs'] = $attrs;
+        } else {
+            $ret['tag'] = $key;
+        }
+        return $ret;
+    }
+
+    function _validateStabilityVersion()
+    {
+        $structure = array('release', 'api');
+        $a = $this->_stupidSchemaValidate($structure, $this->_packageInfo['version'], '<version>');
+        $a &= $this->_stupidSchemaValidate($structure, $this->_packageInfo['stability'], '<stability>');
+        if ($a) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $this->_packageInfo['version']['release'])) {
+                $this->_invalidVersion('release', $this->_packageInfo['version']['release']);
+            }
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $this->_packageInfo['version']['api'])) {
+                $this->_invalidVersion('api', $this->_packageInfo['version']['api']);
+            }
+            if (!in_array($this->_packageInfo['stability']['release'],
+                  array('snapshot', 'devel', 'alpha', 'beta', 'stable'))) {
+                $this->_invalidState('release', $this->_packageInfo['stability']['release']);
+            }
+            if (!in_array($this->_packageInfo['stability']['api'],
+                  array('devel', 'alpha', 'beta', 'stable'))) {
+                $this->_invalidState('api', $this->_packageInfo['stability']['api']);
+            }
+        }
+    }
+
+    function _validateMaintainers()
+    {
+        $structure =
+            array(
+                'name',
+                'user',
+                'email',
+                'active',
+            );
+        foreach (array('lead', 'developer', 'contributor', 'helper') as $type) {
+            if (!isset($this->_packageInfo[$type])) {
+                continue;
+            }
+            if (isset($this->_packageInfo[$type][0])) {
+                foreach ($this->_packageInfo[$type] as $lead) {
+                    $this->_stupidSchemaValidate($structure, $lead, '<' . $type . '>');
+                }
+            } else {
+                $this->_stupidSchemaValidate($structure, $this->_packageInfo[$type],
+                    '<' . $type . '>');
+            }
+        }
+    }
+
+    function _validatePhpDep($dep, $installcondition = false)
+    {
+        $structure = array(
+            'min',
+            '*max',
+            '*exclude',
+        );
+        $type = $installcondition ? '<installcondition><php>' : '<dependencies><required><php>';
+        $this->_stupidSchemaValidate($structure, $dep, $type);
+        if (isset($dep['min'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/',
+                  $dep['min'])) {
+                $this->_invalidVersion($type . '<min>', $dep['min']);
+            }
+        }
+        if (isset($dep['max'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/',
+                  $dep['max'])) {
+                $this->_invalidVersion($type . '<max>', $dep['max']);
+            }
+        }
+        if (isset($dep['exclude'])) {
+            if (!is_array($dep['exclude'])) {
+                $dep['exclude'] = array($dep['exclude']);
+            }
+            foreach ($dep['exclude'] as $exclude) {
+                if (!preg_match(
+                     '/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/',
+                     $exclude)) {
+                    $this->_invalidVersion($type . '<exclude>', $exclude);
+                }
+            }
+        }
+    }
+
+    function _validatePearinstallerDep($dep)
+    {
+        $structure = array(
+            'min',
+            '*max',
+            '*recommended',
+            '*exclude',
+        );
+        $this->_stupidSchemaValidate($structure, $dep, '<dependencies><required><pearinstaller>');
+        if (isset($dep['min'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $dep['min'])) {
+                $this->_invalidVersion('<dependencies><required><pearinstaller><min>',
+                    $dep['min']);
+            }
+        }
+        if (isset($dep['max'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $dep['max'])) {
+                $this->_invalidVersion('<dependencies><required><pearinstaller><max>',
+                    $dep['max']);
+            }
+        }
+        if (isset($dep['recommended'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $dep['recommended'])) {
+                $this->_invalidVersion('<dependencies><required><pearinstaller><recommended>',
+                    $dep['recommended']);
+            }
+        }
+        if (isset($dep['exclude'])) {
+            if (!is_array($dep['exclude'])) {
+                $dep['exclude'] = array($dep['exclude']);
+            }
+            foreach ($dep['exclude'] as $exclude) {
+                if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                      $exclude)) {
+                    $this->_invalidVersion('<dependencies><required><pearinstaller><exclude>',
+                        $exclude);
+                }
+            }
+        }
+    }
+
+    function _validatePackageDep($dep, $group, $type = '<package>')
+    {
+        if (isset($dep['uri'])) {
+            if (isset($dep['conflicts'])) {
+                $structure = array(
+                    'name',
+                    'uri',
+                    'conflicts',
+                    '*providesextension',
+                );
+            } else {
+                $structure = array(
+                    'name',
+                    'uri',
+                    '*providesextension',
+                );
+            }
+        } else {
+            if (isset($dep['conflicts'])) {
+                $structure = array(
+                    'name',
+                    'channel',
+                    '*min',
+                    '*max',
+                    '*exclude',
+                    'conflicts',
+                    '*providesextension',
+                );
+            } else {
+                $structure = array(
+                    'name',
+                    'channel',
+                    '*min',
+                    '*max',
+                    '*recommended',
+                    '*exclude',
+                    '*nodefault',
+                    '*providesextension',
+                );
+            }
+        }
+        if (isset($dep['name'])) {
+            $type .= '<name>' . $dep['name'] . '</name>';
+        }
+        $this->_stupidSchemaValidate($structure, $dep, '<dependencies>' . $group . $type);
+        if (isset($dep['uri']) && (isset($dep['min']) || isset($dep['max']) ||
+              isset($dep['recommended']) || isset($dep['exclude']))) {
+            $this->_uriDepsCannotHaveVersioning('<dependencies>' . $group . $type);
+        }
+        if (isset($dep['channel']) && strtolower($dep['channel']) == '__uri') {
+            $this->_DepchannelCannotBeUri('<dependencies>' . $group . $type);
+        }
+        if (isset($dep['min'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $dep['min'])) {
+                $this->_invalidVersion('<dependencies>' . $group . $type . '<min>', $dep['min']);
+            }
+        }
+        if (isset($dep['max'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $dep['max'])) {
+                $this->_invalidVersion('<dependencies>' . $group . $type . '<max>', $dep['max']);
+            }
+        }
+        if (isset($dep['recommended'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $dep['recommended'])) {
+                $this->_invalidVersion('<dependencies>' . $group . $type . '<recommended>',
+                    $dep['recommended']);
+            }
+        }
+        if (isset($dep['exclude'])) {
+            if (!is_array($dep['exclude'])) {
+                $dep['exclude'] = array($dep['exclude']);
+            }
+            foreach ($dep['exclude'] as $exclude) {
+                if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                      $exclude)) {
+                    $this->_invalidVersion('<dependencies>' . $group . $type . '<exclude>',
+                        $exclude);
+                }
+            }
+        }
+    }
+
+    function _validateSubpackageDep($dep, $group)
+    {
+        $this->_validatePackageDep($dep, $group, '<subpackage>');
+        if (isset($dep['providesextension'])) {
+            $this->_subpackageCannotProvideExtension(isset($dep['name']) ? $dep['name'] : '');
+        }
+        if (isset($dep['conflicts'])) {
+            $this->_subpackagesCannotConflict(isset($dep['name']) ? $dep['name'] : '');
+        }
+    }
+
+    function _validateExtensionDep($dep, $group = false, $installcondition = false)
+    {
+        if (isset($dep['conflicts'])) {
+            $structure = array(
+                'name',
+                '*min',
+                '*max',
+                '*exclude',
+                'conflicts',
+            );
+        } else {
+            $structure = array(
+                'name',
+                '*min',
+                '*max',
+                '*recommended',
+                '*exclude',
+            );
+        }
+        if ($installcondition) {
+            $type = '<installcondition><extension>';
+        } else {
+            $type = '<dependencies>' . $group . '<extension>';
+        }
+        if (isset($dep['name'])) {
+            $type .= '<name>' . $dep['name'] . '</name>';
+        }
+        $this->_stupidSchemaValidate($structure, $dep, $type);
+        if (isset($dep['min'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $dep['min'])) {
+                $this->_invalidVersion(substr($type, 1) . '<min', $dep['min']);
+            }
+        }
+        if (isset($dep['max'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $dep['max'])) {
+                $this->_invalidVersion(substr($type, 1) . '<max', $dep['max']);
+            }
+        }
+        if (isset($dep['recommended'])) {
+            if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                  $dep['recommended'])) {
+                $this->_invalidVersion(substr($type, 1) . '<recommended', $dep['recommended']);
+            }
+        }
+        if (isset($dep['exclude'])) {
+            if (!is_array($dep['exclude'])) {
+                $dep['exclude'] = array($dep['exclude']);
+            }
+            foreach ($dep['exclude'] as $exclude) {
+                if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                      $exclude)) {
+                    $this->_invalidVersion(substr($type, 1) . '<exclude', $exclude);
+                }
+            }
+        }
+    }
+
+    function _validateOsDep($dep, $installcondition = false)
+    {
+        $structure = array(
+            'name',
+            '*conflicts',
+        );
+        $type = $installcondition ? '<installcondition><os>' : '<dependencies><required><os>';
+        if ($this->_stupidSchemaValidate($structure, $dep, $type)) {
+            if ($dep['name'] == '*') {
+                if (array_key_exists('conflicts', $dep)) {
+                    $this->_cannotConflictWithAllOs($type);
+                }
+            }
+        }
+    }
+
+    function _validateArchDep($dep, $installcondition = false)
+    {
+        $structure = array(
+            'pattern',
+            '*conflicts',
+        );
+        $type = $installcondition ? '<installcondition><arch>' : '<dependencies><required><arch>';
+        $this->_stupidSchemaValidate($structure, $dep, $type);
+    }
+
+    function _validateInstallConditions($cond, $release)
+    {
+        $structure = array(
+            '*php',
+            '*extension',
+            '*os',
+            '*arch',
+        );
+        if (!$this->_stupidSchemaValidate($structure,
+              $cond, $release)) {
+            return false;
+        }
+        foreach (array('php', 'extension', 'os', 'arch') as $type) {
+            if (isset($cond[$type])) {
+                $iter = $cond[$type];
+                if (!is_array($iter) || !isset($iter[0])) {
+                    $iter = array($iter);
+                }
+                foreach ($iter as $package) {
+                    if ($type == 'extension') {
+                        $this->{"_validate{$type}Dep"}($package, false, true);
+                    } else {
+                        $this->{"_validate{$type}Dep"}($package, true);
+                    }
+                }
+            }
+        }
+    }
+
+    function _validateDependencies()
+    {
+        $structure = array(
+            'required',
+            '*optional',
+            '*group->name->hint'
+        );
+        if (!$this->_stupidSchemaValidate($structure,
+              $this->_packageInfo['dependencies'], '<dependencies>')) {
+            return false;
+        }
+        foreach (array('required', 'optional') as $simpledep) {
+            if (isset($this->_packageInfo['dependencies'][$simpledep])) {
+                if ($simpledep == 'optional') {
+                    $structure = array(
+                        '*package',
+                        '*subpackage',
+                        '*extension',
+                    );
+                } else {
+                    $structure = array(
+                        'php',
+                        'pearinstaller',
+                        '*package',
+                        '*subpackage',
+                        '*extension',
+                        '*os',
+                        '*arch',
+                    );
+                }
+                if ($this->_stupidSchemaValidate($structure,
+                      $this->_packageInfo['dependencies'][$simpledep],
+                      "<dependencies><$simpledep>")) {
+                    foreach (array('package', 'subpackage', 'extension') as $type) {
+                        if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) {
+                            $iter = $this->_packageInfo['dependencies'][$simpledep][$type];
+                            if (!isset($iter[0])) {
+                                $iter = array($iter);
+                            }
+                            foreach ($iter as $package) {
+                                if ($type != 'extension') {
+                                    if (isset($package['uri'])) {
+                                        if (isset($package['channel'])) {
+                                            $this->_UrlOrChannel($type,
+                                                $package['name']);
+                                        }
+                                    } else {
+                                        if (!isset($package['channel'])) {
+                                            $this->_NoChannel($type, $package['name']);
+                                        }
+                                    }
+                                }
+                                $this->{"_validate{$type}Dep"}($package, "<$simpledep>");
+                            }
+                        }
+                    }
+                    if ($simpledep == 'optional') {
+                        continue;
+                    }
+                    foreach (array('php', 'pearinstaller', 'os', 'arch') as $type) {
+                        if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) {
+                            $iter = $this->_packageInfo['dependencies'][$simpledep][$type];
+                            if (!isset($iter[0])) {
+                                $iter = array($iter);
+                            }
+                            foreach ($iter as $package) {
+                                $this->{"_validate{$type}Dep"}($package);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (isset($this->_packageInfo['dependencies']['group'])) {
+            $groups = $this->_packageInfo['dependencies']['group'];
+            if (!isset($groups[0])) {
+                $groups = array($groups);
+            }
+            $structure = array(
+                '*package',
+                '*subpackage',
+                '*extension',
+            );
+            foreach ($groups as $group) {
+                if ($this->_stupidSchemaValidate($structure, $group, '<group>')) {
+                    if (!PEAR_Validate::validGroupName($group['attribs']['name'])) {
+                        $this->_invalidDepGroupName($group['attribs']['name']);
+                    }
+                    foreach (array('package', 'subpackage', 'extension') as $type) {
+                        if (isset($group[$type])) {
+                            $iter = $group[$type];
+                            if (!isset($iter[0])) {
+                                $iter = array($iter);
+                            }
+                            foreach ($iter as $package) {
+                                if ($type != 'extension') {
+                                    if (isset($package['uri'])) {
+                                        if (isset($package['channel'])) {
+                                            $this->_UrlOrChannelGroup($type,
+                                                $package['name'],
+                                                $group['name']);
+                                        }
+                                    } else {
+                                        if (!isset($package['channel'])) {
+                                            $this->_NoChannelGroup($type,
+                                                $package['name'],
+                                                $group['name']);
+                                        }
+                                    }
+                                }
+                                $this->{"_validate{$type}Dep"}($package, '<group name="' .
+                                    $group['attribs']['name'] . '">');
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    function _validateCompatible()
+    {
+        $compat = $this->_packageInfo['compatible'];
+        if (!isset($compat[0])) {
+            $compat = array($compat);
+        }
+        $required = array('name', 'channel', 'min', 'max', '*exclude');
+        foreach ($compat as $package) {
+            $type = '<compatible>';
+            if (is_array($package) && array_key_exists('name', $package)) {
+                $type .= '<name>' . $package['name'] . '</name>';
+            }
+            $this->_stupidSchemaValidate($required, $package, $type);
+            if (is_array($package) && array_key_exists('min', $package)) {
+                if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                      $package['min'])) {
+                    $this->_invalidVersion(substr($type, 1) . '<min', $package['min']);
+                }
+            }
+            if (is_array($package) && array_key_exists('max', $package)) {
+                if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                      $package['max'])) {
+                    $this->_invalidVersion(substr($type, 1) . '<max', $package['max']);
+                }
+            }
+            if (is_array($package) && array_key_exists('exclude', $package)) {
+                if (!is_array($package['exclude'])) {
+                    $package['exclude'] = array($package['exclude']);
+                }
+                foreach ($package['exclude'] as $exclude) {
+                    if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
+                          $exclude)) {
+                        $this->_invalidVersion(substr($type, 1) . '<exclude', $exclude);
+                    }
+                }
+            }
+        }
+    }
+
+    function _validateBundle($list)
+    {
+        if (!is_array($list) || !isset($list['bundledpackage'])) {
+            return $this->_NoBundledPackages();
+        }
+        if (!is_array($list['bundledpackage']) || !isset($list['bundledpackage'][0])) {
+            return $this->_AtLeast2BundledPackages();
+        }
+        foreach ($list['bundledpackage'] as $package) {
+            if (!is_string($package)) {
+                $this->_bundledPackagesMustBeFilename();
+            }
+        }
+    }
+
+    function _validateFilelist($list = false, $allowignore = false, $dirs = '')
+    {
+        $iscontents = false;
+        if (!$list) {
+            $iscontents = true;
+            $list = $this->_packageInfo['contents'];
+            if (isset($this->_packageInfo['bundle'])) {
+                return $this->_validateBundle($list);
+            }
+        }
+        if ($allowignore) {
+            $struc = array(
+                '*install->name->as',
+                '*ignore->name'
+            );
+        } else {
+            $struc = array(
+                '*dir->name->?baseinstalldir',
+                '*file->name->role->?baseinstalldir->?md5sum'
+            );
+            if (isset($list['dir']) && isset($list['file'])) {
+                // stave off validation errors without requiring a set order.
+                $_old = $list;
+                if (isset($list['attribs'])) {
+                    $list = array('attribs' => $_old['attribs']);
+                }
+                $list['dir'] = $_old['dir'];
+                $list['file'] = $_old['file'];
+            }
+        }
+        if (!isset($list['attribs']) || !isset($list['attribs']['name'])) {
+            $unknown = $allowignore ? '<filelist>' : '<dir name="*unknown*">';
+            $dirname = $iscontents ? '<contents>' : $unknown;
+        } else {
+            $dirname = '<dir name="' . $list['attribs']['name'] . '">';
+            if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
+                          str_replace('\\', '/', $list['attribs']['name']))) {
+                // file contains .. parent directory or . cur directory
+                $this->_invalidDirName($list['attribs']['name']);
+            }
+        }
+        $res = $this->_stupidSchemaValidate($struc, $list, $dirname);
+        if ($allowignore && $res) {
+            $ignored_or_installed = array();
+            $this->_pf->getFilelist();
+            $fcontents = $this->_pf->getContents();
+            $filelist = array();
+            if (!isset($fcontents['dir']['file'][0])) {
+                $fcontents['dir']['file'] = array($fcontents['dir']['file']);
+            }
+            foreach ($fcontents['dir']['file'] as $file) {
+                $filelist[$file['attribs']['name']] = true;
+            }
+            if (isset($list['install'])) {
+                if (!isset($list['install'][0])) {
+                    $list['install'] = array($list['install']);
+                }
+                foreach ($list['install'] as $file) {
+                    if (!isset($filelist[$file['attribs']['name']])) {
+                        $this->_notInContents($file['attribs']['name'], 'install');
+                        continue;
+                    }
+                    if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) {
+                        $this->_multipleInstallAs($file['attribs']['name']);
+                    }
+                    if (!isset($ignored_or_installed[$file['attribs']['name']])) {
+                        $ignored_or_installed[$file['attribs']['name']] = array();
+                    }
+                    $ignored_or_installed[$file['attribs']['name']][] = 1;
+                    if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
+                                  str_replace('\\', '/', $file['attribs']['as']))) {
+                        // file contains .. parent directory or . cur directory references
+                        $this->_invalidFileInstallAs($file['attribs']['name'],
+                            $file['attribs']['as']);
+                    }
+                }
+            }
+            if (isset($list['ignore'])) {
+                if (!isset($list['ignore'][0])) {
+                    $list['ignore'] = array($list['ignore']);
+                }
+                foreach ($list['ignore'] as $file) {
+                    if (!isset($filelist[$file['attribs']['name']])) {
+                        $this->_notInContents($file['attribs']['name'], 'ignore');
+                        continue;
+                    }
+                    if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) {
+                        $this->_ignoreAndInstallAs($file['attribs']['name']);
+                    }
+                }
+            }
+        }
+        if (!$allowignore && isset($list['file'])) {
+            if (is_string($list['file'])) {
+                $this->_oldStyleFileNotAllowed();
+                return false;
+            }
+            if (!isset($list['file'][0])) {
+                // single file
+                $list['file'] = array($list['file']);
+            }
+            foreach ($list['file'] as $i => $file)
+            {
+                if (isset($file['attribs']) && isset($file['attribs']['name'])) {
+                    if ($file['attribs']['name']{0} == '.' &&
+                          $file['attribs']['name']{1} == '/') {
+                        // name is something like "./doc/whatever.txt"
+                        $this->_invalidFileName($file['attribs']['name'], $dirname);
+                    }
+                    if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
+                                  str_replace('\\', '/', $file['attribs']['name']))) {
+                        // file contains .. parent directory or . cur directory
+                        $this->_invalidFileName($file['attribs']['name'], $dirname);
+                    }
+                }
+                if (isset($file['attribs']) && isset($file['attribs']['role'])) {
+                    if (!$this->_validateRole($file['attribs']['role'])) {
+                        if (isset($this->_packageInfo['usesrole'])) {
+                            $roles = $this->_packageInfo['usesrole'];
+                            if (!isset($roles[0])) {
+                                $roles = array($roles);
+                            }
+                            foreach ($roles as $role) {
+                                if ($role['role'] = $file['attribs']['role']) {
+                                    $msg = 'This package contains role "%role%" and requires ' .
+                                        'package "%package%" to be used';
+                                    if (isset($role['uri'])) {
+                                        $params = array('role' => $role['role'],
+                                            'package' => $role['uri']);
+                                    } else {
+                                        $params = array('role' => $role['role'],
+                                            'package' => $this->_pf->_registry->
+                                            parsedPackageNameToString(array('package' =>
+                                                $role['package'], 'channel' => $role['channel']),
+                                                true));
+                                    }
+                                    $this->_stack->push('_mustInstallRole', 'error', $params, $msg);
+                                }
+                            }
+                        }
+                        $this->_invalidFileRole($file['attribs']['name'],
+                            $dirname, $file['attribs']['role']);
+                    }
+                }
+                if (!isset($file['attribs'])) {
+                    continue;
+                }
+                $save = $file['attribs'];
+                if ($dirs) {
+                    $save['name'] = $dirs . '/' . $save['name'];
+                }
+                unset($file['attribs']);
+                if (count($file) && $this->_curState != PEAR_VALIDATE_DOWNLOADING) { // has tasks
+                    foreach ($file as $task => $value) {
+                        if ($tagClass = $this->_pf->getTask($task)) {
+                            if (!is_array($value) || !isset($value[0])) {
+                                $value = array($value);
+                            }
+                            foreach ($value as $v) {
+                                $ret = call_user_func(array($tagClass, 'validateXml'),
+                                    $this->_pf, $v, $this->_pf->_config, $save);
+                                if (is_array($ret)) {
+                                    $this->_invalidTask($task, $ret, isset($save['name']) ?
+                                        $save['name'] : '');
+                                }
+                            }
+                        } else {
+                            if (isset($this->_packageInfo['usestask'])) {
+                                $roles = $this->_packageInfo['usestask'];
+                                if (!isset($roles[0])) {
+                                    $roles = array($roles);
+                                }
+                                foreach ($roles as $role) {
+                                    if ($role['task'] = $task) {
+                                        $msg = 'This package contains task "%task%" and requires ' .
+                                            'package "%package%" to be used';
+                                        if (isset($role['uri'])) {
+                                            $params = array('task' => $role['task'],
+                                                'package' => $role['uri']);
+                                        } else {
+                                            $params = array('task' => $role['task'],
+                                                'package' => $this->_pf->_registry->
+                                                parsedPackageNameToString(array('package' =>
+                                                    $role['package'], 'channel' => $role['channel']),
+                                                    true));
+                                        }
+                                        $this->_stack->push('_mustInstallTask', 'error',
+                                            $params, $msg);
+                                    }
+                                }
+                            }
+                            $this->_unknownTask($task, $save['name']);
+                        }
+                    }
+                }
+            }
+        }
+        if (isset($list['ignore'])) {
+            if (!$allowignore) {
+                $this->_ignoreNotAllowed('ignore');
+            }
+        }
+        if (isset($list['install'])) {
+            if (!$allowignore) {
+                $this->_ignoreNotAllowed('install');
+            }
+        }
+        if (isset($list['file'])) {
+            if ($allowignore) {
+                $this->_fileNotAllowed('file');
+            }
+        }
+        if (isset($list['dir'])) {
+            if ($allowignore) {
+                $this->_fileNotAllowed('dir');
+            } else {
+                if (!isset($list['dir'][0])) {
+                    $list['dir'] = array($list['dir']);
+                }
+                foreach ($list['dir'] as $dir) {
+                    if (isset($dir['attribs']) && isset($dir['attribs']['name'])) {
+                        if ($dir['attribs']['name'] == '/' ||
+                              !isset($this->_packageInfo['contents']['dir']['dir'])) {
+                            // always use nothing if the filelist has already been flattened
+                            $newdirs = '';
+                        } elseif ($dirs == '') {
+                            $newdirs = $dir['attribs']['name'];
+                        } else {
+                            $newdirs = $dirs . '/' . $dir['attribs']['name'];
+                        }
+                    } else {
+                        $newdirs = $dirs;
+                    }
+                    $this->_validateFilelist($dir, $allowignore, $newdirs);
+                }
+            }
+        }
+    }
+
+    function _validateRelease()
+    {
+        if (isset($this->_packageInfo['phprelease'])) {
+            $release = 'phprelease';
+            if (isset($this->_packageInfo['providesextension'])) {
+                $this->_cannotProvideExtension($release);
+            }
+            if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) {
+                $this->_cannotHaveSrcpackage($release);
+            }
+            $releases = $this->_packageInfo['phprelease'];
+            if (!is_array($releases)) {
+                return true;
+            }
+            if (!isset($releases[0])) {
+                $releases = array($releases);
+            }
+            foreach ($releases as $rel) {
+                $this->_stupidSchemaValidate(array(
+                    '*installconditions',
+                    '*filelist',
+                ), $rel, '<phprelease>');
+            }
+        }
+        foreach (array('', 'zend') as $prefix) {
+            $releasetype = $prefix . 'extsrcrelease';
+            if (isset($this->_packageInfo[$releasetype])) {
+                $release = $releasetype;
+                if (!isset($this->_packageInfo['providesextension'])) {
+                    $this->_mustProvideExtension($release);
+                }
+                if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) {
+                    $this->_cannotHaveSrcpackage($release);
+                }
+                $releases = $this->_packageInfo[$releasetype];
+                if (!is_array($releases)) {
+                    return true;
+                }
+                if (!isset($releases[0])) {
+                    $releases = array($releases);
+                }
+                foreach ($releases as $rel) {
+                    $this->_stupidSchemaValidate(array(
+                        '*installconditions',
+                        '*configureoption->name->prompt->?default',
+                        '*binarypackage',
+                        '*filelist',
+                    ), $rel, '<' . $releasetype . '>');
+                    if (isset($rel['binarypackage'])) {
+                        if (!is_array($rel['binarypackage']) || !isset($rel['binarypackage'][0])) {
+                            $rel['binarypackage'] = array($rel['binarypackage']);
+                        }
+                        foreach ($rel['binarypackage'] as $bin) {
+                            if (!is_string($bin)) {
+                                $this->_binaryPackageMustBePackagename();
+                            }
+                        }
+                    }
+                }
+            }
+            $releasetype = 'extbinrelease';
+            if (isset($this->_packageInfo[$releasetype])) {
+                $release = $releasetype;
+                if (!isset($this->_packageInfo['providesextension'])) {
+                    $this->_mustProvideExtension($release);
+                }
+                if (isset($this->_packageInfo['channel']) &&
+                      !isset($this->_packageInfo['srcpackage'])) {
+                    $this->_mustSrcPackage($release);
+                }
+                if (isset($this->_packageInfo['uri']) && !isset($this->_packageInfo['srcuri'])) {
+                    $this->_mustSrcuri($release);
+                }
+                $releases = $this->_packageInfo[$releasetype];
+                if (!is_array($releases)) {
+                    return true;
+                }
+                if (!isset($releases[0])) {
+                    $releases = array($releases);
+                }
+                foreach ($releases as $rel) {
+                    $this->_stupidSchemaValidate(array(
+                        '*installconditions',
+                        '*filelist',
+                    ), $rel, '<' . $releasetype . '>');
+                }
+            }
+        }
+        if (isset($this->_packageInfo['bundle'])) {
+            $release = 'bundle';
+            if (isset($this->_packageInfo['providesextension'])) {
+                $this->_cannotProvideExtension($release);
+            }
+            if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) {
+                $this->_cannotHaveSrcpackage($release);
+            }
+            $releases = $this->_packageInfo['bundle'];
+            if (!is_array($releases) || !isset($releases[0])) {
+                $releases = array($releases);
+            }
+            foreach ($releases as $rel) {
+                $this->_stupidSchemaValidate(array(
+                    '*installconditions',
+                    '*filelist',
+                ), $rel, '<bundle>');
+            }
+        }
+        foreach ($releases as $rel) {
+            if (is_array($rel) && array_key_exists('installconditions', $rel)) {
+                $this->_validateInstallConditions($rel['installconditions'],
+                    "<$release><installconditions>");
+            }
+            if (is_array($rel) && array_key_exists('filelist', $rel)) {
+                if ($rel['filelist']) {
+
+                    $this->_validateFilelist($rel['filelist'], true);
+                }
+            }
+        }
+    }
+
+    /**
+     * This is here to allow role extension through plugins
+     * @param string
+     */
+    function _validateRole($role)
+    {
+        return in_array($role, PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType()));
+    }
+
+    function _pearVersionTooLow($version)
+    {
+        $this->_stack->push(__FUNCTION__, 'error',
+            array('version' => $version),
+            'This package.xml requires PEAR version %version% to parse properly, we are ' .
+            'version 1.9.0');
+    }
+
+    function _invalidTagOrder($oktags, $actual, $root)
+    {
+        $this->_stack->push(__FUNCTION__, 'error',
+            array('oktags' => $oktags, 'actual' => $actual, 'root' => $root),
+            'Invalid tag order in %root%, found <%actual%> expected one of "%oktags%"');
+    }
+
+    function _ignoreNotAllowed($type)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
+            '<%type%> is not allowed inside global <contents>, only inside ' .
+            '<phprelease>/<extbinrelease>/<zendextbinrelease>, use <dir> and <file> only');
+    }
+
+    function _fileNotAllowed($type)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
+            '<%type%> is not allowed inside release <filelist>, only inside ' .
+            '<contents>, use <ignore> and <install> only');
+    }
+
+    function _oldStyleFileNotAllowed()
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(),
+            'Old-style <file>name</file> is not allowed.  Use' .
+            '<file name="name" role="role"/>');
+    }
+
+    function _tagMissingAttribute($tag, $attr, $context)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag,
+            'attribute' => $attr, 'context' => $context),
+            'tag <%tag%> in context "%context%" has no attribute "%attribute%"');
+    }
+
+    function _tagHasNoAttribs($tag, $context)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag,
+            'context' => $context),
+            'tag <%tag%> has no attributes in context "%context%"');
+    }
+
+    function _invalidInternalStructure()
+    {
+        $this->_stack->push(__FUNCTION__, 'exception', array(),
+            'internal array was not generated by compatible parser, or extreme parser error, cannot continue');
+    }
+
+    function _invalidFileRole($file, $dir, $role)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(
+            'file' => $file, 'dir' => $dir, 'role' => $role,
+            'roles' => PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())),
+            'File "%file%" in directory "%dir%" has invalid role "%role%", should be one of %roles%');
+    }
+
+    function _invalidFileName($file, $dir)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(
+            'file' => $file),
+            'File "%file%" in directory "%dir%" cannot begin with "./" or contain ".."');
+    }
+
+    function _invalidFileInstallAs($file, $as)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(
+            'file' => $file, 'as' => $as),
+            'File "%file%" <install as="%as%"/> cannot contain "./" or contain ".."');
+    }
+
+    function _invalidDirName($dir)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(
+            'dir' => $file),
+            'Directory "%dir%" cannot begin with "./" or contain ".."');
+    }
+
+    function _filelistCannotContainFile($filelist)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist),
+            '<%tag%> can only contain <dir>, contains <file>.  Use ' .
+            '<dir name="/"> as the first dir element');
+    }
+
+    function _filelistMustContainDir($filelist)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist),
+            '<%tag%> must contain <dir>.  Use <dir name="/"> as the ' .
+            'first dir element');
+    }
+
+    function _tagCannotBeEmpty($tag)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag),
+            '<%tag%> cannot be empty (<%tag%/>)');
+    }
+
+    function _UrlOrChannel($type, $name)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type,
+            'name' => $name),
+            'Required dependency <%type%> "%name%" can have either url OR ' .
+            'channel attributes, and not both');
+    }
+
+    function _NoChannel($type, $name)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type,
+            'name' => $name),
+            'Required dependency <%type%> "%name%" must have either url OR ' .
+            'channel attributes');
+    }
+
+    function _UrlOrChannelGroup($type, $name, $group)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type,
+            'name' => $name, 'group' => $group),
+            'Group "%group%" dependency <%type%> "%name%" can have either url OR ' .
+            'channel attributes, and not both');
+    }
+
+    function _NoChannelGroup($type, $name, $group)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type,
+            'name' => $name, 'group' => $group),
+            'Group "%group%" dependency <%type%> "%name%" must have either url OR ' .
+            'channel attributes');
+    }
+
+    function _unknownChannel($channel)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('channel' => $channel),
+            'Unknown channel "%channel%"');
+    }
+
+    function _noPackageVersion()
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(),
+            'package.xml <package> tag has no version attribute, or version is not 2.0');
+    }
+
+    function _NoBundledPackages()
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(),
+            'No <bundledpackage> tag was found in <contents>, required for bundle packages');
+    }
+
+    function _AtLeast2BundledPackages()
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(),
+            'At least 2 packages must be bundled in a bundle package');
+    }
+
+    function _ChannelOrUri($name)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('name' => $name),
+            'Bundled package "%name%" can have either a uri or a channel, not both');
+    }
+
+    function _noChildTag($child, $tag)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('child' => $child, 'tag' => $tag),
+            'Tag <%tag%> is missing child tag <%child%>');
+    }
+
+    function _invalidVersion($type, $value)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value),
+            'Version type <%type%> is not a valid version (%value%)');
+    }
+
+    function _invalidState($type, $value)
+    {
+        $states = array('stable', 'beta', 'alpha', 'devel');
+        if ($type != 'api') {
+            $states[] = 'snapshot';
+        }
+        if (strtolower($value) == 'rc') {
+            $this->_stack->push(__FUNCTION__, 'error',
+                array('version' => $this->_packageInfo['version']['release']),
+                'RC is not a state, it is a version postfix, try %version%RC1, stability beta');
+        }
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value,
+            'types' => $states),
+            'Stability type <%type%> is not a valid stability (%value%), must be one of ' .
+            '%types%');
+    }
+
+    function _invalidTask($task, $ret, $file)
+    {
+        switch ($ret[0]) {
+            case PEAR_TASK_ERROR_MISSING_ATTRIB :
+                $info = array('attrib' => $ret[1], 'task' => $task, 'file' => $file);
+                $msg = 'task <%task%> is missing attribute "%attrib%" in file %file%';
+            break;
+            case PEAR_TASK_ERROR_NOATTRIBS :
+                $info = array('task' => $task, 'file' => $file);
+                $msg = 'task <%task%> has no attributes in file %file%';
+            break;
+            case PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE :
+                $info = array('attrib' => $ret[1], 'values' => $ret[3],
+                    'was' => $ret[2], 'task' => $task, 'file' => $file);
+                $msg = 'task <%task%> attribute "%attrib%" has the wrong value "%was%" '.
+                    'in file %file%, expecting one of "%values%"';
+            break;
+            case PEAR_TASK_ERROR_INVALID :
+                $info = array('reason' => $ret[1], 'task' => $task, 'file' => $file);
+                $msg = 'task <%task%> in file %file% is invalid because of "%reason%"';
+            break;
+        }
+        $this->_stack->push(__FUNCTION__, 'error', $info, $msg);
+    }
+
+    function _unknownTask($task, $file)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('task' => $task, 'file' => $file),
+            'Unknown task "%task%" passed in file <file name="%file%">');
+    }
+
+    function _subpackageCannotProvideExtension($name)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('name' => $name),
+            'Subpackage dependency "%name%" cannot use <providesextension>, ' .
+            'only package dependencies can use this tag');
+    }
+
+    function _subpackagesCannotConflict($name)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('name' => $name),
+            'Subpackage dependency "%name%" cannot use <conflicts/>, ' .
+            'only package dependencies can use this tag');
+    }
+
+    function _cannotProvideExtension($release)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
+            '<%release%> packages cannot use <providesextension>, only extbinrelease, extsrcrelease, zendextsrcrelease, and zendextbinrelease can provide a PHP extension');
+    }
+
+    function _mustProvideExtension($release)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
+            '<%release%> packages must use <providesextension> to indicate which PHP extension is provided');
+    }
+
+    function _cannotHaveSrcpackage($release)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
+            '<%release%> packages cannot specify a source code package, only extension binaries may use the <srcpackage> tag');
+    }
+
+    function _mustSrcPackage($release)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
+            '<extbinrelease>/<zendextbinrelease> packages must specify a source code package with <srcpackage>');
+    }
+
+    function _mustSrcuri($release)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('release' => $release),
+            '<extbinrelease>/<zendextbinrelease> packages must specify a source code package with <srcuri>');
+    }
+
+    function _uriDepsCannotHaveVersioning($type)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
+            '%type%: dependencies with a <uri> tag cannot have any versioning information');
+    }
+
+    function _conflictingDepsCannotHaveVersioning($type)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
+            '%type%: conflicting dependencies cannot have versioning info, use <exclude> to ' .
+            'exclude specific versions of a dependency');
+    }
+
+    function _DepchannelCannotBeUri($type)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('type' => $type),
+            '%type%: channel cannot be __uri, this is a pseudo-channel reserved for uri ' .
+            'dependencies only');
+    }
+
+    function _bundledPackagesMustBeFilename()
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(),
+            '<bundledpackage> tags must contain only the filename of a package release ' .
+            'in the bundle');
+    }
+
+    function _binaryPackageMustBePackagename()
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(),
+            '<binarypackage> tags must contain the name of a package that is ' .
+            'a compiled version of this extsrc/zendextsrc package');
+    }
+
+    function _fileNotFound($file)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
+            'File "%file%" in package.xml does not exist');
+    }
+
+    function _notInContents($file, $tag)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('file' => $file, 'tag' => $tag),
+            '<%tag% name="%file%"> is invalid, file is not in <contents>');
+    }
+
+    function _cannotValidateNoPathSet()
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(),
+            'Cannot validate files, no path to package file is set (use setPackageFile())');
+    }
+
+    function _usesroletaskMustHaveChannelOrUri($role, $tag)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag),
+            '<%tag%> for role "%role%" must contain either <uri>, or <channel> and <package>');
+    }
+
+    function _usesroletaskMustHavePackage($role, $tag)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag),
+            '<%tag%> for role "%role%" must contain <package>');
+    }
+
+    function _usesroletaskMustHaveRoleTask($tag, $type)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, 'type' => $type),
+            '<%tag%> must contain <%type%> defining the %type% to be used');
+    }
+
+    function _cannotConflictWithAllOs($type)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag),
+            '%tag% cannot conflict with all OSes');
+    }
+
+    function _invalidDepGroupName($name)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('name' => $name),
+            'Invalid dependency group name "%name%"');
+    }
+
+    function _multipleToplevelDirNotAllowed()
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array(),
+            'Multiple top-level <dir> tags are not allowed.  Enclose them ' .
+                'in a <dir name="/">');
+    }
+
+    function _multipleInstallAs($file)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
+            'Only one <install> tag is allowed for file "%file%"');
+    }
+
+    function _ignoreAndInstallAs($file)
+    {
+        $this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
+            'Cannot have both <ignore> and <install> tags for file "%file%"');
+    }
+
+    function _analyzeBundledPackages()
+    {
+        if (!$this->_isValid) {
+            return false;
+        }
+        if (!$this->_pf->getPackageType() == 'bundle') {
+            return false;
+        }
+        if (!isset($this->_pf->_packageFile)) {
+            return false;
+        }
+        $dir_prefix = dirname($this->_pf->_packageFile);
+        $common = new PEAR_Common;
+        $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') :
+            array($common, 'log');
+        $info = $this->_pf->getContents();
+        $info = $info['bundledpackage'];
+        if (!is_array($info)) {
+            $info = array($info);
+        }
+        $pkg = &new PEAR_PackageFile($this->_pf->_config);
+        foreach ($info as $package) {
+            if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) {
+                $this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $package);
+                $this->_isValid = 0;
+                continue;
+            }
+            call_user_func_array($log, array(1, "Analyzing bundled package $package"));
+            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+            $ret = $pkg->fromAnyFile($dir_prefix . DIRECTORY_SEPARATOR . $package,
+                PEAR_VALIDATE_NORMAL);
+            PEAR::popErrorHandling();
+            if (PEAR::isError($ret)) {
+                call_user_func_array($log, array(0, "ERROR: package $package is not a valid " .
+                    'package'));
+                $inf = $ret->getUserInfo();
+                if (is_array($inf)) {
+                    foreach ($inf as $err) {
+                        call_user_func_array($log, array(1, $err['message']));
+                    }
+                }
+                return false;
+            }
+        }
+        return true;
+    }
+
+    function _analyzePhpFiles()
+    {
+        if (!$this->_isValid) {
+            return false;
+        }
+        if (!isset($this->_pf->_packageFile)) {
+            $this->_cannotValidateNoPathSet();
+            return false;
+        }
+        $dir_prefix = dirname($this->_pf->_packageFile);
+        $common = new PEAR_Common;
+        $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') :
+            array(&$common, 'log');
+        $info = $this->_pf->getContents();
+        if (!$info || !isset($info['dir']['file'])) {
+            $this->_tagCannotBeEmpty('contents><dir');
+            return false;
+        }
+        $info = $info['dir']['file'];
+        if (isset($info['attribs'])) {
+            $info = array($info);
+        }
+        $provides = array();
+        foreach ($info as $fa) {
+            $fa = $fa['attribs'];
+            $file = $fa['name'];
+            if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) {
+                $this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $file);
+                $this->_isValid = 0;
+                continue;
+            }
+            if (in_array($fa['role'], PEAR_Installer_Role::getPhpRoles()) && $dir_prefix) {
+                call_user_func_array($log, array(1, "Analyzing $file"));
+                $srcinfo = $this->analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file);
+                if ($srcinfo) {
+                    $provides = array_merge($provides, $this->_buildProvidesArray($srcinfo));
+                }
+            }
+        }
+        $this->_packageName = $pn = $this->_pf->getPackage();
+        $pnl = strlen($pn);
+        foreach ($provides as $key => $what) {
+            if (isset($what['explicit']) || !$what) {
+                // skip conformance checks if the provides entry is
+                // specified in the package.xml file
+                continue;
+            }
+            extract($what);
+            if ($type == 'class') {
+                if (!strncasecmp($name, $pn, $pnl)) {
+                    continue;
+                }
+                $this->_stack->push(__FUNCTION__, 'warning',
+                    array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn),
+                    'in %file%: %type% "%name%" not prefixed with package name "%package%"');
+            } elseif ($type == 'function') {
+                if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) {
+                    continue;
+                }
+                $this->_stack->push(__FUNCTION__, 'warning',
+                    array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn),
+                    'in %file%: %type% "%name%" not prefixed with package name "%package%"');
+            }
+        }
+        return $this->_isValid;
+    }
+
+    /**
+     * Analyze the source code of the given PHP file
+     *
+     * @param  string Filename of the PHP file
+     * @param  boolean whether to analyze $file as the file contents
+     * @return mixed
+     */
+    function analyzeSourceCode($file, $string = false)
+    {
+        if (!function_exists("token_get_all")) {
+            $this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
+                'Parser error: token_get_all() function must exist to analyze source code, PHP may have been compiled with --disable-tokenizer');
+            return false;
+        }
+
+        if (!defined('T_DOC_COMMENT')) {
+            define('T_DOC_COMMENT', T_COMMENT);
+        }
+
+        if (!defined('T_INTERFACE')) {
+            define('T_INTERFACE', -1);
+        }
+
+        if (!defined('T_IMPLEMENTS')) {
+            define('T_IMPLEMENTS', -1);
+        }
+
+        if ($string) {
+            $contents = $file;
+        } else {
+            if (!$fp = @fopen($file, "r")) {
+                return false;
+            }
+            fclose($fp);
+            $contents = file_get_contents($file);
+        }
+
+        // Silence this function so we can catch PHP Warnings and show our own custom message
+        $tokens = @token_get_all($contents);
+        if (isset($php_errormsg)) {
+            if (isset($this->_stack)) {
+                $pn = $this->_pf->getPackage();
+                $this->_stack->push(__FUNCTION__, 'warning',
+                        array('file' => $file, 'package' => $pn),
+                        'in %file%: Could not process file for unkown reasons,' .
+                        ' possibly a PHP parse error in %file% from %package%');
+            }
+        }
+/*
+        for ($i = 0; $i < sizeof($tokens); $i++) {
+            @list($token, $data) = $tokens[$i];
+            if (is_string($token)) {
+                var_dump($token);
+            } else {
+                print token_name($token) . ' ';
+                var_dump(rtrim($data));
+            }
+        }
+*/
+        $look_for = 0;
+        $paren_level = 0;
+        $bracket_level = 0;
+        $brace_level = 0;
+        $lastphpdoc = '';
+        $current_class = '';
+        $current_interface = '';
+        $current_class_level = -1;
+        $current_function = '';
+        $current_function_level = -1;
+        $declared_classes = array();
+        $declared_interfaces = array();
+        $declared_functions = array();
+        $declared_methods = array();
+        $used_classes = array();
+        $used_functions = array();
+        $extends = array();
+        $implements = array();
+        $nodeps = array();
+        $inquote = false;
+        $interface = false;
+        for ($i = 0; $i < sizeof($tokens); $i++) {
+            if (is_array($tokens[$i])) {
+                list($token, $data) = $tokens[$i];
+            } else {
+                $token = $tokens[$i];
+                $data = '';
+            }
+
+            if ($inquote) {
+                if ($token != '"' && $token != T_END_HEREDOC) {
+                    continue;
+                } else {
+                    $inquote = false;
+                    continue;
+                }
+            }
+
+            switch ($token) {
+                case T_WHITESPACE :
+                    continue;
+                case ';':
+                    if ($interface) {
+                        $current_function = '';
+                        $current_function_level = -1;
+                    }
+                    break;
+                case '"':
+                case T_START_HEREDOC:
+                    $inquote = true;
+                    break;
+                case T_CURLY_OPEN:
+                case T_DOLLAR_OPEN_CURLY_BRACES:
+                case '{': $brace_level++; continue 2;
+                case '}':
+                    $brace_level--;
+                    if ($current_class_level == $brace_level) {
+                        $current_class = '';
+                        $current_class_level = -1;
+                    }
+                    if ($current_function_level == $brace_level) {
+                        $current_function = '';
+                        $current_function_level = -1;
+                    }
+                    continue 2;
+                case '[': $bracket_level++; continue 2;
+                case ']': $bracket_level--; continue 2;
+                case '(': $paren_level++;   continue 2;
+                case ')': $paren_level--;   continue 2;
+                case T_INTERFACE:
+                    $interface = true;
+                case T_CLASS:
+                    if (($current_class_level != -1) || ($current_function_level != -1)) {
+                        if (isset($this->_stack)) {
+                            $this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
+                            'Parser error: invalid PHP found in file "%file%"');
+                        } else {
+                            PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"",
+                                PEAR_COMMON_ERROR_INVALIDPHP);
+                        }
+
+                        return false;
+                    }
+                case T_FUNCTION:
+                case T_NEW:
+                case T_EXTENDS:
+                case T_IMPLEMENTS:
+                    $look_for = $token;
+                    continue 2;
+                case T_STRING:
+                    if (version_compare(zend_version(), '2.0', '<')) {
+                        if (in_array(strtolower($data),
+                            array('public', 'private', 'protected', 'abstract',
+                                  'interface', 'implements', 'throw')
+                                 )
+                        ) {
+                            if (isset($this->_stack)) {
+                                $this->_stack->push(__FUNCTION__, 'warning', array(
+                                    'file' => $file),
+                                    'Error, PHP5 token encountered in %file%,' .
+                                    ' analysis should be in PHP5');
+                            } else {
+                                PEAR::raiseError('Error: PHP5 token encountered in ' . $file .
+                                    'packaging should be done in PHP 5');
+                                return false;
+                            }
+                        }
+                    }
+
+                    if ($look_for == T_CLASS) {
+                        $current_class = $data;
+                        $current_class_level = $brace_level;
+                        $declared_classes[] = $current_class;
+                    } elseif ($look_for == T_INTERFACE) {
+                        $current_interface = $data;
+                        $current_class_level = $brace_level;
+                        $declared_interfaces[] = $current_interface;
+                    } elseif ($look_for == T_IMPLEMENTS) {
+                        $implements[$current_class] = $data;
+                    } elseif ($look_for == T_EXTENDS) {
+                        $extends[$current_class] = $data;
+                    } elseif ($look_for == T_FUNCTION) {
+                        if ($current_class) {
+                            $current_function = "$current_class::$data";
+                            $declared_methods[$current_class][] = $data;
+                        } elseif ($current_interface) {
+                            $current_function = "$current_interface::$data";
+                            $declared_methods[$current_interface][] = $data;
+                        } else {
+                            $current_function = $data;
+                            $declared_functions[] = $current_function;
+                        }
+
+                        $current_function_level = $brace_level;
+                        $m = array();
+                    } elseif ($look_for == T_NEW) {
+                        $used_classes[$data] = true;
+                    }
+
+                    $look_for = 0;
+                    continue 2;
+                case T_VARIABLE:
+                    $look_for = 0;
+                    continue 2;
+                case T_DOC_COMMENT:
+                case T_COMMENT:
+                    if (preg_match('!^/\*\*\s!', $data)) {
+                        $lastphpdoc = $data;
+                        if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
+                            $nodeps = array_merge($nodeps, $m[1]);
+                        }
+                    }
+                    continue 2;
+                case T_DOUBLE_COLON:
+                    if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
+                        if (isset($this->_stack)) {
+                            $this->_stack->push(__FUNCTION__, 'warning', array('file' => $file),
+                                'Parser error: invalid PHP found in file "%file%"');
+                        } else {
+                            PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"",
+                                PEAR_COMMON_ERROR_INVALIDPHP);
+                        }
+
+                        return false;
+                    }
+
+                    $class = $tokens[$i - 1][1];
+                    if (strtolower($class) != 'parent') {
+                        $used_classes[$class] = true;
+                    }
+
+                    continue 2;
+            }
+        }
+
+        return array(
+            "source_file" => $file,
+            "declared_classes" => $declared_classes,
+            "declared_interfaces" => $declared_interfaces,
+            "declared_methods" => $declared_methods,
+            "declared_functions" => $declared_functions,
+            "used_classes" => array_diff(array_keys($used_classes), $nodeps),
+            "inheritance" => $extends,
+            "implements" => $implements,
+        );
+    }
+
+    /**
+     * Build a "provides" array from data returned by
+     * analyzeSourceCode().  The format of the built array is like
+     * this:
+     *
+     *  array(
+     *    'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'),
+     *    ...
+     *  )
+     *
+     *
+     * @param array $srcinfo array with information about a source file
+     * as returned by the analyzeSourceCode() method.
+     *
+     * @return void
+     *
+     * @access private
+     *
+     */
+    function _buildProvidesArray($srcinfo)
+    {
+        if (!$this->_isValid) {
+            return array();
+        }
+
+        $providesret = array();
+        $file        = basename($srcinfo['source_file']);
+        $pn          = isset($this->_pf) ? $this->_pf->getPackage() : '';
+        $pnl         = strlen($pn);
+        foreach ($srcinfo['declared_classes'] as $class) {
+            $key = "class;$class";
+            if (isset($providesret[$key])) {
+                continue;
+            }
+
+            $providesret[$key] =
+                array('file'=> $file, 'type' => 'class', 'name' => $class);
+            if (isset($srcinfo['inheritance'][$class])) {
+                $providesret[$key]['extends'] =
+                    $srcinfo['inheritance'][$class];
+            }
+        }
+
+        foreach ($srcinfo['declared_methods'] as $class => $methods) {
+            foreach ($methods as $method) {
+                $function = "$class::$method";
+                $key = "function;$function";
+                if ($method{0} == '_' || !strcasecmp($method, $class) ||
+                    isset($providesret[$key])) {
+                    continue;
+                }
+
+                $providesret[$key] =
+                    array('file'=> $file, 'type' => 'function', 'name' => $function);
+            }
+        }
+
+        foreach ($srcinfo['declared_functions'] as $function) {
+            $key = "function;$function";
+            if ($function{0} == '_' || isset($providesret[$key])) {
+                continue;
+            }
+
+            if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
+                $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
+            }
+
+            $providesret[$key] =
+                array('file'=> $file, 'type' => 'function', 'name' => $function);
+        }
+
+        return $providesret;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/PackageFile/v2/rw.php b/lib/php/PEAR/PackageFile/v2/rw.php
new file mode 100644
index 00000000..5c974921
--- /dev/null
+++ b/lib/php/PEAR/PackageFile/v2/rw.php
@@ -0,0 +1,1604 @@
+<?php
+/**
+ * PEAR_PackageFile_v2, package.xml version 2.0, read/write version
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a8
+ */
+/**
+ * For base class
+ */
+require_once 'PEAR/PackageFile/v2.php';
+/**
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a8
+ */
+class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2
+{
+    /**
+     * @param string Extension name
+     * @return bool success of operation
+     */
+    function setProvidesExtension($extension)
+    {
+        if (in_array($this->getPackageType(),
+              array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) {
+            if (!isset($this->_packageInfo['providesextension'])) {
+                // ensure that the channel tag is set up in the right location
+                $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                    array('usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease',
+                    'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                    'bundle', 'changelog'),
+                    $extension, 'providesextension');
+            }
+            $this->_packageInfo['providesextension'] = $extension;
+            return true;
+        }
+        return false;
+    }
+
+    function setPackage($package)
+    {
+        $this->_isValid = 0;
+        if (!isset($this->_packageInfo['attribs'])) {
+            $this->_packageInfo = array_merge(array('attribs' => array(
+                                 'version' => '2.0',
+                                 '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',
+                                 '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',
+                             )), $this->_packageInfo);
+        }
+        if (!isset($this->_packageInfo['name'])) {
+            return $this->_packageInfo = array_merge(array('name' => $package),
+                $this->_packageInfo);
+        }
+        $this->_packageInfo['name'] = $package;
+    }
+
+    /**
+     * set this as a package.xml version 2.1
+     * @access private
+     */
+    function _setPackageVersion2_1()
+    {
+        $info = array(
+                                 'version' => '2.1',
+                                 'xmlns' => 'http://pear.php.net/dtd/package-2.1',
+                                 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
+                                 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
+                                 '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.1
+    http://pear.php.net/dtd/package-2.1.xsd',
+                             );
+        if (!isset($this->_packageInfo['attribs'])) {
+            $this->_packageInfo = array_merge(array('attribs' => $info), $this->_packageInfo);
+        } else {
+            $this->_packageInfo['attribs'] = $info;
+        }
+    }
+
+    function setUri($uri)
+    {
+        unset($this->_packageInfo['channel']);
+        $this->_isValid = 0;
+        if (!isset($this->_packageInfo['uri'])) {
+            // ensure that the uri tag is set up in the right location
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('extends', 'summary', 'description', 'lead',
+                'developer', 'contributor', 'helper', 'date', 'time', 'version',
+                'stability', 'license', 'notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'), $uri, 'uri');
+        }
+        $this->_packageInfo['uri'] = $uri;
+    }
+
+    function setChannel($channel)
+    {
+        unset($this->_packageInfo['uri']);
+        $this->_isValid = 0;
+        if (!isset($this->_packageInfo['channel'])) {
+            // ensure that the channel tag is set up in the right location
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('extends', 'summary', 'description', 'lead',
+                'developer', 'contributor', 'helper', 'date', 'time', 'version',
+                'stability', 'license', 'notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'), $channel, 'channel');
+        }
+        $this->_packageInfo['channel'] = $channel;
+    }
+
+    function setExtends($extends)
+    {
+        $this->_isValid = 0;
+        if (!isset($this->_packageInfo['extends'])) {
+            // ensure that the extends tag is set up in the right location
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('summary', 'description', 'lead',
+                'developer', 'contributor', 'helper', 'date', 'time', 'version',
+                'stability', 'license', 'notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'), $extends, 'extends');
+        }
+        $this->_packageInfo['extends'] = $extends;
+    }
+
+    function setSummary($summary)
+    {
+        $this->_isValid = 0;
+        if (!isset($this->_packageInfo['summary'])) {
+            // ensure that the summary tag is set up in the right location
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('description', 'lead',
+                'developer', 'contributor', 'helper', 'date', 'time', 'version',
+                'stability', 'license', 'notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'), $summary, 'summary');
+        }
+        $this->_packageInfo['summary'] = $summary;
+    }
+
+    function setDescription($desc)
+    {
+        $this->_isValid = 0;
+        if (!isset($this->_packageInfo['description'])) {
+            // ensure that the description tag is set up in the right location
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('lead',
+                'developer', 'contributor', 'helper', 'date', 'time', 'version',
+                'stability', 'license', 'notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'), $desc, 'description');
+        }
+        $this->_packageInfo['description'] = $desc;
+    }
+
+    /**
+     * Adds a new maintainer - no checking of duplicates is performed, use
+     * updatemaintainer for that purpose.
+     */
+    function addMaintainer($role, $handle, $name, $email, $active = 'yes')
+    {
+        if (!in_array($role, array('lead', 'developer', 'contributor', 'helper'))) {
+            return false;
+        }
+        if (isset($this->_packageInfo[$role])) {
+            if (!isset($this->_packageInfo[$role][0])) {
+                $this->_packageInfo[$role] = array($this->_packageInfo[$role]);
+            }
+            $this->_packageInfo[$role][] =
+                array(
+                    'name' => $name,
+                    'user' => $handle,
+                    'email' => $email,
+                    'active' => $active,
+                );
+        } else {
+            $testarr = array('lead',
+                    'developer', 'contributor', 'helper', 'date', 'time', 'version',
+                    'stability', 'license', 'notes', 'contents', 'compatible',
+                    'dependencies', 'providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
+                    'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog');
+            foreach (array('lead', 'developer', 'contributor', 'helper') as $testrole) {
+                array_shift($testarr);
+                if ($role == $testrole) {
+                    break;
+                }
+            }
+            if (!isset($this->_packageInfo[$role])) {
+                // ensure that the extends tag is set up in the right location
+                $this->_packageInfo = $this->_insertBefore($this->_packageInfo, $testarr,
+                    array(), $role);
+            }
+            $this->_packageInfo[$role] =
+                array(
+                    'name' => $name,
+                    'user' => $handle,
+                    'email' => $email,
+                    'active' => $active,
+                );
+        }
+        $this->_isValid = 0;
+    }
+
+    function updateMaintainer($newrole, $handle, $name, $email, $active = 'yes')
+    {
+        $found = false;
+        foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
+            if (!isset($this->_packageInfo[$role])) {
+                continue;
+            }
+            $info = $this->_packageInfo[$role];
+            if (!isset($info[0])) {
+                if ($info['user'] == $handle) {
+                    $found = true;
+                    break;
+                }
+            }
+            foreach ($info as $i => $maintainer) {
+                if ($maintainer['user'] == $handle) {
+                    $found = $i;
+                    break 2;
+                }
+            }
+        }
+        if ($found === false) {
+            return $this->addMaintainer($newrole, $handle, $name, $email, $active);
+        }
+        if ($found !== false) {
+            if ($found === true) {
+                unset($this->_packageInfo[$role]);
+            } else {
+                unset($this->_packageInfo[$role][$found]);
+                $this->_packageInfo[$role] = array_values($this->_packageInfo[$role]);
+            }
+        }
+        $this->addMaintainer($newrole, $handle, $name, $email, $active);
+        $this->_isValid = 0;
+    }
+
+    function deleteMaintainer($handle)
+    {
+        $found = false;
+        foreach (array('lead', 'developer', 'contributor', 'helper') as $role) {
+            if (!isset($this->_packageInfo[$role])) {
+                continue;
+            }
+            if (!isset($this->_packageInfo[$role][0])) {
+                $this->_packageInfo[$role] = array($this->_packageInfo[$role]);
+            }
+            foreach ($this->_packageInfo[$role] as $i => $maintainer) {
+                if ($maintainer['user'] == $handle) {
+                    $found = $i;
+                    break;
+                }
+            }
+            if ($found !== false) {
+                unset($this->_packageInfo[$role][$found]);
+                if (!count($this->_packageInfo[$role]) && $role == 'lead') {
+                    $this->_isValid = 0;
+                }
+                if (!count($this->_packageInfo[$role])) {
+                    unset($this->_packageInfo[$role]);
+                    return true;
+                }
+                $this->_packageInfo[$role] =
+                    array_values($this->_packageInfo[$role]);
+                if (count($this->_packageInfo[$role]) == 1) {
+                    $this->_packageInfo[$role] = $this->_packageInfo[$role][0];
+                }
+                return true;
+            }
+            if (count($this->_packageInfo[$role]) == 1) {
+                $this->_packageInfo[$role] = $this->_packageInfo[$role][0];
+            }
+        }
+        return false;
+    }
+
+    function setReleaseVersion($version)
+    {
+        if (isset($this->_packageInfo['version']) &&
+              isset($this->_packageInfo['version']['release'])) {
+            unset($this->_packageInfo['version']['release']);
+        }
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array(
+            'version' => array('stability', 'license', 'notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'),
+            'release' => array('api')));
+        $this->_isValid = 0;
+    }
+
+    function setAPIVersion($version)
+    {
+        if (isset($this->_packageInfo['version']) &&
+              isset($this->_packageInfo['version']['api'])) {
+            unset($this->_packageInfo['version']['api']);
+        }
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $version, array(
+            'version' => array('stability', 'license', 'notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'),
+            'api' => array()));
+        $this->_isValid = 0;
+    }
+
+    /**
+     * snapshot|devel|alpha|beta|stable
+     */
+    function setReleaseStability($state)
+    {
+        if (isset($this->_packageInfo['stability']) &&
+              isset($this->_packageInfo['stability']['release'])) {
+            unset($this->_packageInfo['stability']['release']);
+        }
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array(
+            'stability' => array('license', 'notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'),
+            'release' => array('api')));
+        $this->_isValid = 0;
+    }
+
+    /**
+     * @param devel|alpha|beta|stable
+     */
+    function setAPIStability($state)
+    {
+        if (isset($this->_packageInfo['stability']) &&
+              isset($this->_packageInfo['stability']['api'])) {
+            unset($this->_packageInfo['stability']['api']);
+        }
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $state, array(
+            'stability' => array('license', 'notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'),
+            'api' => array()));
+        $this->_isValid = 0;
+    }
+
+    function setLicense($license, $uri = false, $filesource = false)
+    {
+        if (!isset($this->_packageInfo['license'])) {
+            // ensure that the license tag is set up in the right location
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('notes', 'contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'), 0, 'license');
+        }
+        if ($uri || $filesource) {
+            $attribs = array();
+            if ($uri) {
+                $attribs['uri'] = $uri;
+            }
+            $uri = true; // for test below
+            if ($filesource) {
+                $attribs['filesource'] = $filesource;
+            }
+        }
+        $license = $uri ? array('attribs' => $attribs, '_content' => $license) : $license;
+        $this->_packageInfo['license'] = $license;
+        $this->_isValid = 0;
+    }
+
+    function setNotes($notes)
+    {
+        $this->_isValid = 0;
+        if (!isset($this->_packageInfo['notes'])) {
+            // ensure that the notes tag is set up in the right location
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('contents', 'compatible',
+                'dependencies', 'providesextension', 'usesrole', 'usestask', 'srcpackage', 'srcuri',
+                'phprelease', 'extsrcrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'extbinrelease', 'bundle', 'changelog'), $notes, 'notes');
+        }
+        $this->_packageInfo['notes'] = $notes;
+    }
+
+    /**
+     * This is only used at install-time, after all serialization
+     * is over.
+     * @param string file name
+     * @param string installed path
+     */
+    function setInstalledAs($file, $path)
+    {
+        if ($path) {
+            return $this->_packageInfo['filelist'][$file]['installed_as'] = $path;
+        }
+        unset($this->_packageInfo['filelist'][$file]['installed_as']);
+    }
+
+    /**
+     * This is only used at install-time, after all serialization
+     * is over.
+     */
+    function installedFile($file, $atts)
+    {
+        if (isset($this->_packageInfo['filelist'][$file])) {
+            $this->_packageInfo['filelist'][$file] =
+                array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']);
+        } else {
+            $this->_packageInfo['filelist'][$file] = $atts['attribs'];
+        }
+    }
+
+    /**
+     * Reset the listing of package contents
+     * @param string base installation dir for the whole package, if any
+     */
+    function clearContents($baseinstall = false)
+    {
+        $this->_filesValid = false;
+        $this->_isValid = 0;
+        if (!isset($this->_packageInfo['contents'])) {
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('compatible',
+                    'dependencies', 'providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
+                    'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                    'bundle', 'changelog'), array(), 'contents');
+        }
+        if ($this->getPackageType() != 'bundle') {
+            $this->_packageInfo['contents'] =
+                array('dir' => array('attribs' => array('name' => '/')));
+            if ($baseinstall) {
+                $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'] = $baseinstall;
+            }
+        } else {
+            $this->_packageInfo['contents'] = array('bundledpackage' => array());
+        }
+    }
+
+    /**
+     * @param string relative path of the bundled package.
+     */
+    function addBundledPackage($path)
+    {
+        if ($this->getPackageType() != 'bundle') {
+            return false;
+        }
+        $this->_filesValid = false;
+        $this->_isValid = 0;
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $path, array(
+                'contents' => array('compatible', 'dependencies', 'providesextension',
+                'usesrole', 'usestask', 'srcpackage', 'srcuri', 'phprelease',
+                'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'bundle', 'changelog'),
+                'bundledpackage' => array()));
+    }
+
+    /**
+     * @param string file name
+     * @param PEAR_Task_Common a read/write task
+     */
+    function addTaskToFile($filename, $task)
+    {
+        if (!method_exists($task, 'getXml')) {
+            return false;
+        }
+        if (!method_exists($task, 'getName')) {
+            return false;
+        }
+        if (!method_exists($task, 'validate')) {
+            return false;
+        }
+        if (!$task->validate()) {
+            return false;
+        }
+        if (!isset($this->_packageInfo['contents']['dir']['file'])) {
+            return false;
+        }
+        $this->getTasksNs(); // discover the tasks namespace if not done already
+        $files = $this->_packageInfo['contents']['dir']['file'];
+        if (!isset($files[0])) {
+            $files = array($files);
+            $ind = false;
+        } else {
+            $ind = true;
+        }
+        foreach ($files as $i => $file) {
+            if (isset($file['attribs'])) {
+                if ($file['attribs']['name'] == $filename) {
+                    if ($ind) {
+                        $t = isset($this->_packageInfo['contents']['dir']['file'][$i]
+                              ['attribs'][$this->_tasksNs .
+                              ':' . $task->getName()]) ?
+                              $this->_packageInfo['contents']['dir']['file'][$i]
+                              ['attribs'][$this->_tasksNs .
+                              ':' . $task->getName()] : false;
+                        if ($t && !isset($t[0])) {
+                            $this->_packageInfo['contents']['dir']['file'][$i]
+                                [$this->_tasksNs . ':' . $task->getName()] = array($t);
+                        }
+                        $this->_packageInfo['contents']['dir']['file'][$i][$this->_tasksNs .
+                            ':' . $task->getName()][] = $task->getXml();
+                    } else {
+                        $t = isset($this->_packageInfo['contents']['dir']['file']
+                              ['attribs'][$this->_tasksNs .
+                              ':' . $task->getName()]) ? $this->_packageInfo['contents']['dir']['file']
+                              ['attribs'][$this->_tasksNs .
+                              ':' . $task->getName()] : false;
+                        if ($t && !isset($t[0])) {
+                            $this->_packageInfo['contents']['dir']['file']
+                                [$this->_tasksNs . ':' . $task->getName()] = array($t);
+                        }
+                        $this->_packageInfo['contents']['dir']['file'][$this->_tasksNs .
+                            ':' . $task->getName()][] = $task->getXml();
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @param string path to the file
+     * @param string filename
+     * @param array extra attributes
+     */
+    function addFile($dir, $file, $attrs)
+    {
+        if ($this->getPackageType() == 'bundle') {
+            return false;
+        }
+        $this->_filesValid = false;
+        $this->_isValid = 0;
+        $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir);
+        if ($dir == '/' || $dir == '') {
+            $dir = '';
+        } else {
+            $dir .= '/';
+        }
+        $attrs['name'] = $dir . $file;
+        if (!isset($this->_packageInfo['contents'])) {
+            // ensure that the contents tag is set up
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo,
+                array('compatible', 'dependencies', 'providesextension', 'usesrole', 'usestask',
+                'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease',
+                'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'bundle', 'changelog'), array(), 'contents');
+        }
+        if (isset($this->_packageInfo['contents']['dir']['file'])) {
+            if (!isset($this->_packageInfo['contents']['dir']['file'][0])) {
+                $this->_packageInfo['contents']['dir']['file'] =
+                    array($this->_packageInfo['contents']['dir']['file']);
+            }
+            $this->_packageInfo['contents']['dir']['file'][]['attribs'] = $attrs;
+        } else {
+            $this->_packageInfo['contents']['dir']['file']['attribs'] = $attrs;
+        }
+    }
+
+    /**
+     * @param string Dependent package name
+     * @param string Dependent package's channel name
+     * @param string minimum version of specified package that this release is guaranteed to be
+     *               compatible with
+     * @param string maximum version of specified package that this release is guaranteed to be
+     *               compatible with
+     * @param string versions of specified package that this release is not compatible with
+     */
+    function addCompatiblePackage($name, $channel, $min, $max, $exclude = false)
+    {
+        $this->_isValid = 0;
+        $set = array(
+            'name' => $name,
+            'channel' => $channel,
+            'min' => $min,
+            'max' => $max,
+        );
+        if ($exclude) {
+            $set['exclude'] = $exclude;
+        }
+        $this->_isValid = 0;
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
+                'compatible' => array('dependencies', 'providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
+            ));
+    }
+
+    /**
+     * Removes the <usesrole> tag entirely
+     */
+    function resetUsesrole()
+    {
+        if (isset($this->_packageInfo['usesrole'])) {
+            unset($this->_packageInfo['usesrole']);
+        }
+    }
+
+    /**
+     * @param string
+     * @param string package name or uri
+     * @param string channel name if non-uri
+     */
+    function addUsesrole($role, $packageOrUri, $channel = false) {
+        $set = array('role' => $role);
+        if ($channel) {
+            $set['package'] = $packageOrUri;
+            $set['channel'] = $channel;
+        } else {
+            $set['uri'] = $packageOrUri;
+        }
+        $this->_isValid = 0;
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
+                'usesrole' => array('usestask', 'srcpackage', 'srcuri',
+                    'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
+            ));
+    }
+
+    /**
+     * Removes the <usestask> tag entirely
+     */
+    function resetUsestask()
+    {
+        if (isset($this->_packageInfo['usestask'])) {
+            unset($this->_packageInfo['usestask']);
+        }
+    }
+
+
+    /**
+     * @param string
+     * @param string package name or uri
+     * @param string channel name if non-uri
+     */
+    function addUsestask($task, $packageOrUri, $channel = false) {
+        $set = array('task' => $task);
+        if ($channel) {
+            $set['package'] = $packageOrUri;
+            $set['channel'] = $channel;
+        } else {
+            $set['uri'] = $packageOrUri;
+        }
+        $this->_isValid = 0;
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $set, array(
+                'usestask' => array('srcpackage', 'srcuri',
+                    'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')
+            ));
+    }
+
+    /**
+     * Remove all compatible tags
+     */
+    function clearCompatible()
+    {
+        unset($this->_packageInfo['compatible']);
+    }
+
+    /**
+     * Reset dependencies prior to adding new ones
+     */
+    function clearDeps()
+    {
+        if (!isset($this->_packageInfo['dependencies'])) {
+            $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
+                array(
+                    'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                        'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                        'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog')));
+        }
+        $this->_packageInfo['dependencies'] = array();
+    }
+
+    /**
+     * @param string minimum PHP version allowed
+     * @param string maximum PHP version allowed
+     * @param array $exclude incompatible PHP versions
+     */
+    function setPhpDep($min, $max = false, $exclude = false)
+    {
+        $this->_isValid = 0;
+        $dep =
+            array(
+                'min' => $min,
+            );
+        if ($max) {
+            $dep['max'] = $max;
+        }
+        if ($exclude) {
+            if (count($exclude) == 1) {
+                $exclude = $exclude[0];
+            }
+            $dep['exclude'] = $exclude;
+        }
+        if (isset($this->_packageInfo['dependencies']['required']['php'])) {
+            $this->_stack->push(__FUNCTION__, 'warning', array('dep' =>
+            $this->_packageInfo['dependencies']['required']['php']),
+                'warning: PHP dependency already exists, overwriting');
+            unset($this->_packageInfo['dependencies']['required']['php']);
+        }
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                'required' => array('optional', 'group'),
+                'php' => array('pearinstaller', 'package', 'subpackage', 'extension', 'os', 'arch')
+            ));
+        return true;
+    }
+
+    /**
+     * @param string minimum allowed PEAR installer version
+     * @param string maximum allowed PEAR installer version
+     * @param string recommended PEAR installer version
+     * @param array incompatible version of the PEAR installer
+     */
+    function setPearinstallerDep($min, $max = false, $recommended = false, $exclude = false)
+    {
+        $this->_isValid = 0;
+        $dep =
+            array(
+                'min' => $min,
+            );
+        if ($max) {
+            $dep['max'] = $max;
+        }
+        if ($recommended) {
+            $dep['recommended'] = $recommended;
+        }
+        if ($exclude) {
+            if (count($exclude) == 1) {
+                $exclude = $exclude[0];
+            }
+            $dep['exclude'] = $exclude;
+        }
+        if (isset($this->_packageInfo['dependencies']['required']['pearinstaller'])) {
+            $this->_stack->push(__FUNCTION__, 'warning', array('dep' =>
+            $this->_packageInfo['dependencies']['required']['pearinstaller']),
+                'warning: PEAR Installer dependency already exists, overwriting');
+            unset($this->_packageInfo['dependencies']['required']['pearinstaller']);
+        }
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                'required' => array('optional', 'group'),
+                'pearinstaller' => array('package', 'subpackage', 'extension', 'os', 'arch')
+            ));
+    }
+
+    /**
+     * Mark a package as conflicting with this package
+     * @param string package name
+     * @param string package channel
+     * @param string extension this package provides, if any
+     * @param string|false minimum version required
+     * @param string|false maximum version allowed
+     * @param array|false versions to exclude from installation
+     */
+    function addConflictingPackageDepWithChannel($name, $channel,
+                $providesextension = false, $min = false, $max = false, $exclude = false)
+    {
+        $this->_isValid = 0;
+        $dep = $this->_constructDep($name, $channel, false, $min, $max, false,
+            $exclude, $providesextension, false, true);
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                'required' => array('optional', 'group'),
+                'package' => array('subpackage', 'extension', 'os', 'arch')
+            ));
+    }
+
+    /**
+     * Mark a package as conflicting with this package
+     * @param string package name
+     * @param string package channel
+     * @param string extension this package provides, if any
+     */
+    function addConflictingPackageDepWithUri($name, $uri, $providesextension = false)
+    {
+        $this->_isValid = 0;
+        $dep =
+            array(
+                'name' => $name,
+                'uri' => $uri,
+                'conflicts' => '',
+            );
+        if ($providesextension) {
+            $dep['providesextension'] = $providesextension;
+        }
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                'required' => array('optional', 'group'),
+                'package' => array('subpackage', 'extension', 'os', 'arch')
+            ));
+    }
+
+    function addDependencyGroup($name, $hint)
+    {
+        $this->_isValid = 0;
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo,
+            array('attribs' => array('name' => $name, 'hint' => $hint)),
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                'group' => array(),
+            ));
+    }
+
+    /**
+     * @param string package name
+     * @param string|false channel name, false if this is a uri
+     * @param string|false uri name, false if this is a channel
+     * @param string|false minimum version required
+     * @param string|false maximum version allowed
+     * @param string|false recommended installation version
+     * @param array|false versions to exclude from installation
+     * @param string extension this package provides, if any
+     * @param bool if true, tells the installer to ignore the default optional dependency group
+     *             when installing this package
+     * @param bool if true, tells the installer to negate this dependency (conflicts)
+     * @return array
+     * @access private
+     */
+    function _constructDep($name, $channel, $uri, $min, $max, $recommended, $exclude,
+                           $providesextension = false, $nodefault = false,
+                           $conflicts = false)
+    {
+        $dep =
+            array(
+                'name' => $name,
+            );
+        if ($channel) {
+            $dep['channel'] = $channel;
+        } elseif ($uri) {
+            $dep['uri'] = $uri;
+        }
+        if ($min) {
+            $dep['min'] = $min;
+        }
+        if ($max) {
+            $dep['max'] = $max;
+        }
+        if ($recommended) {
+            $dep['recommended'] = $recommended;
+        }
+        if ($exclude) {
+            if (is_array($exclude) && count($exclude) == 1) {
+                $exclude = $exclude[0];
+            }
+            $dep['exclude'] = $exclude;
+        }
+        if ($conflicts) {
+            $dep['conflicts'] = '';
+        }
+        if ($nodefault) {
+            $dep['nodefault'] = '';
+        }
+        if ($providesextension) {
+            $dep['providesextension'] = $providesextension;
+        }
+        return $dep;
+    }
+
+    /**
+     * @param package|subpackage
+     * @param string group name
+     * @param string package name
+     * @param string package channel
+     * @param string minimum version
+     * @param string maximum version
+     * @param string recommended version
+     * @param array|false optional excluded versions
+     * @param string extension this package provides, if any
+     * @param bool if true, tells the installer to ignore the default optional dependency group
+     *             when installing this package
+     * @return bool false if the dependency group has not been initialized with
+     *              {@link addDependencyGroup()}, or a subpackage is added with
+     *              a providesextension
+     */
+    function addGroupPackageDepWithChannel($type, $groupname, $name, $channel, $min = false,
+                                      $max = false, $recommended = false, $exclude = false,
+                                      $providesextension = false, $nodefault = false)
+    {
+        if ($type == 'subpackage' && $providesextension) {
+            return false; // subpackages must be php packages
+        }
+        $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
+            $providesextension, $nodefault);
+        return $this->_addGroupDependency($type, $dep, $groupname);
+    }
+
+    /**
+     * @param package|subpackage
+     * @param string group name
+     * @param string package name
+     * @param string package uri
+     * @param string extension this package provides, if any
+     * @param bool if true, tells the installer to ignore the default optional dependency group
+     *             when installing this package
+     * @return bool false if the dependency group has not been initialized with
+     *              {@link addDependencyGroup()}
+     */
+    function addGroupPackageDepWithURI($type, $groupname, $name, $uri, $providesextension = false,
+                                       $nodefault = false)
+    {
+        if ($type == 'subpackage' && $providesextension) {
+            return false; // subpackages must be php packages
+        }
+        $dep = $this->_constructDep($name, false, $uri, false, false, false, false,
+            $providesextension, $nodefault);
+        return $this->_addGroupDependency($type, $dep, $groupname);
+    }
+
+    /**
+     * @param string group name (must be pre-existing)
+     * @param string extension name
+     * @param string minimum version allowed
+     * @param string maximum version allowed
+     * @param string recommended version
+     * @param array incompatible versions
+     */
+    function addGroupExtensionDep($groupname, $name, $min = false, $max = false,
+                                         $recommended = false, $exclude = false)
+    {
+        $this->_isValid = 0;
+        $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
+        return $this->_addGroupDependency('extension', $dep, $groupname);
+    }
+
+    /**
+     * @param package|subpackage|extension
+     * @param array dependency contents
+     * @param string name of the dependency group to add this to
+     * @return boolean
+     * @access private
+     */
+    function _addGroupDependency($type, $dep, $groupname)
+    {
+        $arr = array('subpackage', 'extension');
+        if ($type != 'package') {
+            array_shift($arr);
+        }
+        if ($type == 'extension') {
+            array_shift($arr);
+        }
+        if (!isset($this->_packageInfo['dependencies']['group'])) {
+            return false;
+        } else {
+            if (!isset($this->_packageInfo['dependencies']['group'][0])) {
+                if ($this->_packageInfo['dependencies']['group']['attribs']['name'] == $groupname) {
+                    $this->_packageInfo['dependencies']['group'] = $this->_mergeTag(
+                        $this->_packageInfo['dependencies']['group'], $dep,
+                        array(
+                            $type => $arr
+                        ));
+                    $this->_isValid = 0;
+                    return true;
+                } else {
+                    return false;
+                }
+            } else {
+                foreach ($this->_packageInfo['dependencies']['group'] as $i => $group) {
+                    if ($group['attribs']['name'] == $groupname) {
+                    $this->_packageInfo['dependencies']['group'][$i] = $this->_mergeTag(
+                        $this->_packageInfo['dependencies']['group'][$i], $dep,
+                        array(
+                            $type => $arr
+                        ));
+                        $this->_isValid = 0;
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+    }
+
+    /**
+     * @param optional|required
+     * @param string package name
+     * @param string package channel
+     * @param string minimum version
+     * @param string maximum version
+     * @param string recommended version
+     * @param string extension this package provides, if any
+     * @param bool if true, tells the installer to ignore the default optional dependency group
+     *             when installing this package
+     * @param array|false optional excluded versions
+     */
+    function addPackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
+                                      $recommended = false, $exclude = false,
+                                      $providesextension = false, $nodefault = false)
+    {
+        if (!in_array($type, array('optional', 'required'), true)) {
+            $type = 'required';
+        }
+        $this->_isValid = 0;
+        $arr = array('optional', 'group');
+        if ($type != 'required') {
+            array_shift($arr);
+        }
+        $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
+            $providesextension, $nodefault);
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                $type => $arr,
+                'package' => array('subpackage', 'extension', 'os', 'arch')
+            ));
+    }
+
+    /**
+     * @param optional|required
+     * @param string name of the package
+     * @param string uri of the package
+     * @param string extension this package provides, if any
+     * @param bool if true, tells the installer to ignore the default optional dependency group
+     *             when installing this package
+     */
+    function addPackageDepWithUri($type, $name, $uri, $providesextension = false,
+                                  $nodefault = false)
+    {
+        $this->_isValid = 0;
+        $arr = array('optional', 'group');
+        if ($type != 'required') {
+            array_shift($arr);
+        }
+        $dep = $this->_constructDep($name, false, $uri, false, false, false, false,
+            $providesextension, $nodefault);
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                $type => $arr,
+                'package' => array('subpackage', 'extension', 'os', 'arch')
+            ));
+    }
+
+    /**
+     * @param optional|required optional, required
+     * @param string package name
+     * @param string package channel
+     * @param string minimum version
+     * @param string maximum version
+     * @param string recommended version
+     * @param array incompatible versions
+     * @param bool if true, tells the installer to ignore the default optional dependency group
+     *             when installing this package
+     */
+    function addSubpackageDepWithChannel($type, $name, $channel, $min = false, $max = false,
+                                         $recommended = false, $exclude = false,
+                                         $nodefault = false)
+    {
+        $this->_isValid = 0;
+        $arr = array('optional', 'group');
+        if ($type != 'required') {
+            array_shift($arr);
+        }
+        $dep = $this->_constructDep($name, $channel, false, $min, $max, $recommended, $exclude,
+            $nodefault);
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                $type => $arr,
+                'subpackage' => array('extension', 'os', 'arch')
+            ));
+    }
+
+    /**
+     * @param optional|required optional, required
+     * @param string package name
+     * @param string package uri for download
+     * @param bool if true, tells the installer to ignore the default optional dependency group
+     *             when installing this package
+     */
+    function addSubpackageDepWithUri($type, $name, $uri, $nodefault = false)
+    {
+        $this->_isValid = 0;
+        $arr = array('optional', 'group');
+        if ($type != 'required') {
+            array_shift($arr);
+        }
+        $dep = $this->_constructDep($name, false, $uri, false, false, false, false, $nodefault);
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                $type => $arr,
+                'subpackage' => array('extension', 'os', 'arch')
+            ));
+    }
+
+    /**
+     * @param optional|required optional, required
+     * @param string extension name
+     * @param string minimum version
+     * @param string maximum version
+     * @param string recommended version
+     * @param array incompatible versions
+     */
+    function addExtensionDep($type, $name, $min = false, $max = false, $recommended = false,
+                             $exclude = false)
+    {
+        $this->_isValid = 0;
+        $arr = array('optional', 'group');
+        if ($type != 'required') {
+            array_shift($arr);
+        }
+        $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                $type => $arr,
+                'extension' => array('os', 'arch')
+            ));
+    }
+
+    /**
+     * @param string Operating system name
+     * @param boolean true if this package cannot be installed on this OS
+     */
+    function addOsDep($name, $conflicts = false)
+    {
+        $this->_isValid = 0;
+        $dep = array('name' => $name);
+        if ($conflicts) {
+            $dep['conflicts'] = '';
+        }
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                'required' => array('optional', 'group'),
+                'os' => array('arch')
+            ));
+    }
+
+    /**
+     * @param string Architecture matching pattern
+     * @param boolean true if this package cannot be installed on this architecture
+     */
+    function addArchDep($pattern, $conflicts = false)
+    {
+        $this->_isValid = 0;
+        $dep = array('pattern' => $pattern);
+        if ($conflicts) {
+            $dep['conflicts'] = '';
+        }
+        $this->_packageInfo = $this->_mergeTag($this->_packageInfo, $dep,
+            array(
+                'dependencies' => array('providesextension', 'usesrole', 'usestask',
+                    'srcpackage', 'srcuri', 'phprelease', 'extsrcrelease', 'extbinrelease',
+                    'zendextsrcrelease', 'zendextbinrelease', 'bundle', 'changelog'),
+                'required' => array('optional', 'group'),
+                'arch' => array()
+            ));
+    }
+
+    /**
+     * Set the kind of package, and erase all release tags
+     *
+     * - a php package is a PEAR-style package
+     * - an extbin package is a PECL-style extension binary
+     * - an extsrc package is a PECL-style source for a binary
+     * - an zendextbin package is a PECL-style zend extension binary
+     * - an zendextsrc package is a PECL-style source for a zend extension binary
+     * - a bundle package is a collection of other pre-packaged packages
+     * @param php|extbin|extsrc|zendextsrc|zendextbin|bundle
+     * @return bool success
+     */
+    function setPackageType($type)
+    {
+        $this->_isValid = 0;
+        if (!in_array($type, array('php', 'extbin', 'extsrc', 'zendextsrc',
+                                   'zendextbin', 'bundle'))) {
+            return false;
+        }
+
+        if (in_array($type, array('zendextsrc', 'zendextbin'))) {
+            $this->_setPackageVersion2_1();
+        }
+
+        if ($type != 'bundle') {
+            $type .= 'release';
+        }
+
+        foreach (array('phprelease', 'extbinrelease', 'extsrcrelease',
+                       'zendextsrcrelease', 'zendextbinrelease', 'bundle') as $test) {
+            unset($this->_packageInfo[$test]);
+        }
+
+        if (!isset($this->_packageInfo[$type])) {
+            // ensure that the release tag is set up
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('changelog'),
+                array(), $type);
+        }
+
+        $this->_packageInfo[$type] = array();
+        return true;
+    }
+
+    /**
+     * @return bool true if package type is set up
+     */
+    function addRelease()
+    {
+        if ($type = $this->getPackageType()) {
+            if ($type != 'bundle') {
+                $type .= 'release';
+            }
+            $this->_packageInfo = $this->_mergeTag($this->_packageInfo, array(),
+                array($type => array('changelog')));
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get the current release tag in order to add to it
+     * @param bool returns only releases that have installcondition if true
+     * @return array|null
+     */
+    function &_getCurrentRelease($strict = true)
+    {
+        if ($p = $this->getPackageType()) {
+            if ($strict) {
+                if ($p == 'extsrc' || $p == 'zendextsrc') {
+                    $a = null;
+                    return $a;
+                }
+            }
+            if ($p != 'bundle') {
+                $p .= 'release';
+            }
+            if (isset($this->_packageInfo[$p][0])) {
+                return $this->_packageInfo[$p][count($this->_packageInfo[$p]) - 1];
+            } else {
+                return $this->_packageInfo[$p];
+            }
+        } else {
+            $a = null;
+            return $a;
+        }
+    }
+
+    /**
+     * Add a file to the current release that should be installed under a different name
+     * @param string <contents> path to file
+     * @param string name the file should be installed as
+     */
+    function addInstallAs($path, $as)
+    {
+        $r = &$this->_getCurrentRelease();
+        if ($r === null) {
+            return false;
+        }
+        $this->_isValid = 0;
+        $r = $this->_mergeTag($r, array('attribs' => array('name' => $path, 'as' => $as)),
+            array(
+                'filelist' => array(),
+                'install' => array('ignore')
+            ));
+    }
+
+    /**
+     * Add a file to the current release that should be ignored
+     * @param string <contents> path to file
+     * @return bool success of operation
+     */
+    function addIgnore($path)
+    {
+        $r = &$this->_getCurrentRelease();
+        if ($r === null) {
+            return false;
+        }
+        $this->_isValid = 0;
+        $r = $this->_mergeTag($r, array('attribs' => array('name' => $path)),
+            array(
+                'filelist' => array(),
+                'ignore' => array()
+            ));
+    }
+
+    /**
+     * Add an extension binary package for this extension source code release
+     *
+     * Note that the package must be from the same channel as the extension source package
+     * @param string
+     */
+    function addBinarypackage($package)
+    {
+        if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
+            return false;
+        }
+        $r = &$this->_getCurrentRelease(false);
+        if ($r === null) {
+            return false;
+        }
+        $this->_isValid = 0;
+        $r = $this->_mergeTag($r, $package,
+            array(
+                'binarypackage' => array('filelist'),
+            ));
+    }
+
+    /**
+     * Add a configureoption to an extension source package
+     * @param string
+     * @param string
+     * @param string
+     */
+    function addConfigureOption($name, $prompt, $default = null)
+    {
+        if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
+            return false;
+        }
+
+        $r = &$this->_getCurrentRelease(false);
+        if ($r === null) {
+            return false;
+        }
+
+        $opt = array('attribs' => array('name' => $name, 'prompt' => $prompt));
+        if ($default !== null) {
+            $opt['attribs']['default'] = $default;
+        }
+
+        $this->_isValid = 0;
+        $r = $this->_mergeTag($r, $opt,
+            array(
+                'configureoption' => array('binarypackage', 'filelist'),
+            ));
+    }
+
+    /**
+     * Set an installation condition based on php version for the current release set
+     * @param string minimum version
+     * @param string maximum version
+     * @param false|array incompatible versions of PHP
+     */
+    function setPhpInstallCondition($min, $max, $exclude = false)
+    {
+        $r = &$this->_getCurrentRelease();
+        if ($r === null) {
+            return false;
+        }
+        $this->_isValid = 0;
+        if (isset($r['installconditions']['php'])) {
+            unset($r['installconditions']['php']);
+        }
+        $dep = array('min' => $min, 'max' => $max);
+        if ($exclude) {
+            if (is_array($exclude) && count($exclude) == 1) {
+                $exclude = $exclude[0];
+            }
+            $dep['exclude'] = $exclude;
+        }
+        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
+            $r = $this->_mergeTag($r, $dep,
+                array(
+                    'installconditions' => array('configureoption', 'binarypackage',
+                        'filelist'),
+                    'php' => array('extension', 'os', 'arch')
+                ));
+        } else {
+            $r = $this->_mergeTag($r, $dep,
+                array(
+                    'installconditions' => array('filelist'),
+                    'php' => array('extension', 'os', 'arch')
+                ));
+        }
+    }
+
+    /**
+     * @param optional|required optional, required
+     * @param string extension name
+     * @param string minimum version
+     * @param string maximum version
+     * @param string recommended version
+     * @param array incompatible versions
+     */
+    function addExtensionInstallCondition($name, $min = false, $max = false, $recommended = false,
+                                          $exclude = false)
+    {
+        $r = &$this->_getCurrentRelease();
+        if ($r === null) {
+            return false;
+        }
+        $this->_isValid = 0;
+        $dep = $this->_constructDep($name, false, false, $min, $max, $recommended, $exclude);
+        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
+            $r = $this->_mergeTag($r, $dep,
+                array(
+                    'installconditions' => array('configureoption', 'binarypackage',
+                        'filelist'),
+                    'extension' => array('os', 'arch')
+                ));
+        } else {
+            $r = $this->_mergeTag($r, $dep,
+                array(
+                    'installconditions' => array('filelist'),
+                    'extension' => array('os', 'arch')
+                ));
+        }
+    }
+
+    /**
+     * Set an installation condition based on operating system for the current release set
+     * @param string OS name
+     * @param bool whether this OS is incompatible with the current release
+     */
+    function setOsInstallCondition($name, $conflicts = false)
+    {
+        $r = &$this->_getCurrentRelease();
+        if ($r === null) {
+            return false;
+        }
+        $this->_isValid = 0;
+        if (isset($r['installconditions']['os'])) {
+            unset($r['installconditions']['os']);
+        }
+        $dep = array('name' => $name);
+        if ($conflicts) {
+            $dep['conflicts'] = '';
+        }
+        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
+            $r = $this->_mergeTag($r, $dep,
+                array(
+                    'installconditions' => array('configureoption', 'binarypackage',
+                        'filelist'),
+                    'os' => array('arch')
+                ));
+        } else {
+            $r = $this->_mergeTag($r, $dep,
+                array(
+                    'installconditions' => array('filelist'),
+                    'os' => array('arch')
+                ));
+        }
+    }
+
+    /**
+     * Set an installation condition based on architecture for the current release set
+     * @param string architecture pattern
+     * @param bool whether this arch is incompatible with the current release
+     */
+    function setArchInstallCondition($pattern, $conflicts = false)
+    {
+        $r = &$this->_getCurrentRelease();
+        if ($r === null) {
+            return false;
+        }
+        $this->_isValid = 0;
+        if (isset($r['installconditions']['arch'])) {
+            unset($r['installconditions']['arch']);
+        }
+        $dep = array('pattern' => $pattern);
+        if ($conflicts) {
+            $dep['conflicts'] = '';
+        }
+        if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') {
+            $r = $this->_mergeTag($r, $dep,
+                array(
+                    'installconditions' => array('configureoption', 'binarypackage',
+                        'filelist'),
+                    'arch' => array()
+                ));
+        } else {
+            $r = $this->_mergeTag($r, $dep,
+                array(
+                    'installconditions' => array('filelist'),
+                    'arch' => array()
+                ));
+        }
+    }
+
+    /**
+     * For extension binary releases, this is used to specify either the
+     * static URI to a source package, or the package name and channel of the extsrc/zendextsrc
+     * package it is based on.
+     * @param string Package name, or full URI to source package (extsrc/zendextsrc type)
+     */
+    function setSourcePackage($packageOrUri)
+    {
+        $this->_isValid = 0;
+        if (isset($this->_packageInfo['channel'])) {
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease',
+                'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'bundle', 'changelog'),
+                $packageOrUri, 'srcpackage');
+        } else {
+            $this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('phprelease',
+                'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', 'zendextbinrelease',
+                'bundle', 'changelog'), $packageOrUri, 'srcuri');
+        }
+    }
+
+    /**
+     * Generate a valid change log entry from the current package.xml
+     * @param string|false
+     */
+    function generateChangeLogEntry($notes = false)
+    {
+        return array(
+            'version' =>
+                array(
+                    'release' => $this->getVersion('release'),
+                    'api' => $this->getVersion('api'),
+                    ),
+            'stability' =>
+                $this->getStability(),
+            'date' => $this->getDate(),
+            'license' => $this->getLicense(true),
+            'notes' => $notes ? $notes : $this->getNotes()
+            );
+    }
+
+    /**
+     * @param string release version to set change log notes for
+     * @param array output of {@link generateChangeLogEntry()}
+     */
+    function setChangelogEntry($releaseversion, $contents)
+    {
+        if (!isset($this->_packageInfo['changelog'])) {
+            $this->_packageInfo['changelog']['release'] = $contents;
+            return;
+        }
+        if (!isset($this->_packageInfo['changelog']['release'][0])) {
+            if ($this->_packageInfo['changelog']['release']['version']['release'] == $releaseversion) {
+                $this->_packageInfo['changelog']['release'] = array(
+                    $this->_packageInfo['changelog']['release']);
+            } else {
+                $this->_packageInfo['changelog']['release'] = array(
+                    $this->_packageInfo['changelog']['release']);
+                return $this->_packageInfo['changelog']['release'][] = $contents;
+            }
+        }
+        foreach($this->_packageInfo['changelog']['release'] as $index => $changelog) {
+            if (isset($changelog['version']) &&
+                  strnatcasecmp($changelog['version']['release'], $releaseversion) == 0) {
+                $curlog = $index;
+            }
+        }
+        if (isset($curlog)) {
+            $this->_packageInfo['changelog']['release'][$curlog] = $contents;
+        } else {
+            $this->_packageInfo['changelog']['release'][] = $contents;
+        }
+    }
+
+    /**
+     * Remove the changelog entirely
+     */
+    function clearChangeLog()
+    {
+        unset($this->_packageInfo['changelog']);
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Packager.php b/lib/php/PEAR/Packager.php
new file mode 100644
index 00000000..d71f6d12
--- /dev/null
+++ b/lib/php/PEAR/Packager.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * PEAR_Packager for generating releases
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Packager.php 286809 2009-08-04 15:10:26Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR/Common.php';
+require_once 'PEAR/PackageFile.php';
+require_once 'System.php';
+
+/**
+ * Administration class used to make a PEAR release tarball.
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 0.1
+ */
+class PEAR_Packager extends PEAR_Common
+{
+    /**
+     * @var PEAR_Registry
+     */
+    var $_registry;
+
+    function package($pkgfile = null, $compress = true, $pkg2 = null)
+    {
+        // {{{ validate supplied package.xml file
+        if (empty($pkgfile)) {
+            $pkgfile = 'package.xml';
+        }
+
+        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+        $pkg  = &new PEAR_PackageFile($this->config, $this->debug);
+        $pf   = &$pkg->fromPackageFile($pkgfile, PEAR_VALIDATE_NORMAL);
+        $main = &$pf;
+        PEAR::staticPopErrorHandling();
+        if (PEAR::isError($pf)) {
+            if (is_array($pf->getUserInfo())) {
+                foreach ($pf->getUserInfo() as $error) {
+                    $this->log(0, 'Error: ' . $error['message']);
+                }
+            }
+
+            $this->log(0, $pf->getMessage());
+            return $this->raiseError("Cannot package, errors in package file");
+        }
+
+        foreach ($pf->getValidationWarnings() as $warning) {
+            $this->log(1, 'Warning: ' . $warning['message']);
+        }
+
+        // }}}
+        if ($pkg2) {
+            $this->log(0, 'Attempting to process the second package file');
+            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
+            $pf2 = &$pkg->fromPackageFile($pkg2, PEAR_VALIDATE_NORMAL);
+            PEAR::staticPopErrorHandling();
+            if (PEAR::isError($pf2)) {
+                if (is_array($pf2->getUserInfo())) {
+                    foreach ($pf2->getUserInfo() as $error) {
+                        $this->log(0, 'Error: ' . $error['message']);
+                    }
+                }
+                $this->log(0, $pf2->getMessage());
+                return $this->raiseError("Cannot package, errors in second package file");
+            }
+
+            foreach ($pf2->getValidationWarnings() as $warning) {
+                $this->log(1, 'Warning: ' . $warning['message']);
+            }
+
+            if ($pf2->getPackagexmlVersion() == '2.0' ||
+                  $pf2->getPackagexmlVersion() == '2.1'
+            ) {
+                $main  = &$pf2;
+                $other = &$pf;
+            } else {
+                $main  = &$pf;
+                $other = &$pf2;
+            }
+
+            if ($main->getPackagexmlVersion() != '2.0' &&
+                  $main->getPackagexmlVersion() != '2.1') {
+                return PEAR::raiseError('Error: cannot package two package.xml version 1.0, can ' .
+                    'only package together a package.xml 1.0 and package.xml 2.0');
+            }
+
+            if ($other->getPackagexmlVersion() != '1.0') {
+                return PEAR::raiseError('Error: cannot package two package.xml version 2.0, can ' .
+                    'only package together a package.xml 1.0 and package.xml 2.0');
+            }
+        }
+
+        $main->setLogger($this);
+        if (!$main->validate(PEAR_VALIDATE_PACKAGING)) {
+            foreach ($main->getValidationWarnings() as $warning) {
+                $this->log(0, 'Error: ' . $warning['message']);
+            }
+            return $this->raiseError("Cannot package, errors in package");
+        }
+
+        foreach ($main->getValidationWarnings() as $warning) {
+            $this->log(1, 'Warning: ' . $warning['message']);
+        }
+
+        if ($pkg2) {
+            $other->setLogger($this);
+            $a = false;
+            if (!$other->validate(PEAR_VALIDATE_NORMAL) || $a = !$main->isEquivalent($other)) {
+                foreach ($other->getValidationWarnings() as $warning) {
+                    $this->log(0, 'Error: ' . $warning['message']);
+                }
+
+                foreach ($main->getValidationWarnings() as $warning) {
+                    $this->log(0, 'Error: ' . $warning['message']);
+                }
+
+                if ($a) {
+                    return $this->raiseError('The two package.xml files are not equivalent!');
+                }
+
+                return $this->raiseError("Cannot package, errors in package");
+            }
+
+            foreach ($other->getValidationWarnings() as $warning) {
+                $this->log(1, 'Warning: ' . $warning['message']);
+            }
+
+            $gen = &$main->getDefaultGenerator();
+            $tgzfile = $gen->toTgz2($this, $other, $compress);
+            if (PEAR::isError($tgzfile)) {
+                return $tgzfile;
+            }
+
+            $dest_package = basename($tgzfile);
+            $pkgdir       = dirname($pkgfile);
+
+            // TAR the Package -------------------------------------------
+            $this->log(1, "Package $dest_package done");
+            if (file_exists("$pkgdir/CVS/Root")) {
+                $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion());
+                $cvstag = "RELEASE_$cvsversion";
+                $this->log(1, 'Tag the released code with "pear cvstag ' .
+                    $main->getPackageFile() . '"');
+                $this->log(1, "(or set the CVS tag $cvstag by hand)");
+            } elseif (file_exists("$pkgdir/.svn")) {
+                $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion());
+                $svntag = $pf->getName() . "-$svnversion";
+                $this->log(1, 'Tag the released code with "pear svntag ' .
+                    $main->getPackageFile() . '"');
+                $this->log(1, "(or set the SVN tag $svntag by hand)");
+            }
+        } else { // this branch is executed for single packagefile packaging
+            $gen = &$pf->getDefaultGenerator();
+            $tgzfile = $gen->toTgz($this, $compress);
+            if (PEAR::isError($tgzfile)) {
+                $this->log(0, $tgzfile->getMessage());
+                return $this->raiseError("Cannot package, errors in package");
+            }
+
+            $dest_package = basename($tgzfile);
+            $pkgdir       = dirname($pkgfile);
+
+            // TAR the Package -------------------------------------------
+            $this->log(1, "Package $dest_package done");
+            if (file_exists("$pkgdir/CVS/Root")) {
+                $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion());
+                $cvstag = "RELEASE_$cvsversion";
+                $this->log(1, "Tag the released code with `pear cvstag $pkgfile'");
+                $this->log(1, "(or set the CVS tag $cvstag by hand)");
+            } elseif (file_exists("$pkgdir/.svn")) {
+                $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion());
+                $svntag = $pf->getName() . "-$svnversion";
+                $this->log(1, "Tag the released code with `pear svntag $pkgfile'");
+                $this->log(1, "(or set the SVN tag $svntag by hand)");
+            }
+        }
+
+        return $dest_package;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/REST.php b/lib/php/PEAR/REST.php
new file mode 100644
index 00000000..d2ff32b6
--- /dev/null
+++ b/lib/php/PEAR/REST.php
@@ -0,0 +1,448 @@
+<?php
+/**
+ * PEAR_REST
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: REST.php 286489 2009-07-29 05:59:08Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * For downloading xml files
+ */
+require_once 'PEAR.php';
+require_once 'PEAR/XMLParser.php';
+
+/**
+ * Intelligently retrieve data, following hyperlinks if necessary, and re-directing
+ * as well
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_REST
+{
+    var $config;
+    var $_options;
+
+    function PEAR_REST(&$config, $options = array())
+    {
+        $this->config   = &$config;
+        $this->_options = $options;
+    }
+
+    /**
+     * Retrieve REST data, but always retrieve the local cache if it is available.
+     *
+     * This is useful for elements that should never change, such as information on a particular
+     * release
+     * @param string full URL to this resource
+     * @param array|false contents of the accept-encoding header
+     * @param boolean     if true, xml will be returned as a string, otherwise, xml will be
+     *                    parsed using PEAR_XMLParser
+     * @return string|array
+     */
+    function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false)
+    {
+        $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
+            md5($url) . 'rest.cachefile';
+
+        if (file_exists($cachefile)) {
+            return unserialize(implode('', file($cachefile)));
+        }
+
+        return $this->retrieveData($url, $accept, $forcestring, $channel);
+    }
+
+    /**
+     * Retrieve a remote REST resource
+     * @param string full URL to this resource
+     * @param array|false contents of the accept-encoding header
+     * @param boolean     if true, xml will be returned as a string, otherwise, xml will be
+     *                    parsed using PEAR_XMLParser
+     * @return string|array
+     */
+    function retrieveData($url, $accept = false, $forcestring = false, $channel = false)
+    {
+        $cacheId = $this->getCacheId($url);
+        if ($ret = $this->useLocalCache($url, $cacheId)) {
+            return $ret;
+        }
+
+        $file = $trieddownload = false;
+        if (!isset($this->_options['offline'])) {
+            $trieddownload = true;
+            $file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel);
+        }
+
+        if (PEAR::isError($file)) {
+            if ($file->getCode() !== -9276) {
+                return $file;
+            }
+
+            $trieddownload = false;
+            $file = false; // use local copy if available on socket connect error
+        }
+
+        if (!$file) {
+            $ret = $this->getCache($url);
+            if (!PEAR::isError($ret) && $trieddownload) {
+                // reset the age of the cache if the server says it was unmodified
+                $this->saveCache($url, $ret, null, true, $cacheId);
+            }
+
+            return $ret;
+        }
+
+        if (is_array($file)) {
+            $headers      = $file[2];
+            $lastmodified = $file[1];
+            $content      = $file[0];
+        } else {
+            $headers      = array();
+            $lastmodified = false;
+            $content      = $file;
+        }
+
+        if ($forcestring) {
+            $this->saveCache($url, $content, $lastmodified, false, $cacheId);
+            return $content;
+        }
+
+        if (isset($headers['content-type'])) {
+            switch ($headers['content-type']) {
+                case 'text/xml' :
+                case 'application/xml' :
+                case 'text/plain' :
+                    if ($headers['content-type'] === 'text/plain') {
+                        $check = substr($content, 0, 5);
+                        if ($check !== '<?xml') {
+                            break;
+                        }
+                    }
+
+                    $parser = new PEAR_XMLParser;
+                    PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+                    $err = $parser->parse($content);
+                    PEAR::popErrorHandling();
+                    if (PEAR::isError($err)) {
+                        return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' .
+                            $err->getMessage());
+                    }
+                    $content = $parser->getData();
+                case 'text/html' :
+                default :
+                    // use it as a string
+            }
+        } else {
+            // assume XML
+            $parser = new PEAR_XMLParser;
+            $parser->parse($content);
+            $content = $parser->getData();
+        }
+
+        $this->saveCache($url, $content, $lastmodified, false, $cacheId);
+        return $content;
+    }
+
+    function useLocalCache($url, $cacheid = null)
+    {
+        if ($cacheid === null) {
+            $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
+                md5($url) . 'rest.cacheid';
+            if (!file_exists($cacheidfile)) {
+                return false;
+            }
+
+            $cacheid = unserialize(implode('', file($cacheidfile)));
+        }
+
+        $cachettl = $this->config->get('cache_ttl');
+        // If cache is newer than $cachettl seconds, we use the cache!
+        if (time() - $cacheid['age'] < $cachettl) {
+            return $this->getCache($url);
+        }
+
+        return false;
+    }
+
+    function getCacheId($url)
+    {
+        $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
+            md5($url) . 'rest.cacheid';
+
+        if (!file_exists($cacheidfile)) {
+            return false;
+        }
+
+        $ret = unserialize(implode('', file($cacheidfile)));
+        return $ret;
+    }
+
+    function getCache($url)
+    {
+        $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
+            md5($url) . 'rest.cachefile';
+
+        if (!file_exists($cachefile)) {
+            return PEAR::raiseError('No cached content available for "' . $url . '"');
+        }
+
+        return unserialize(implode('', file($cachefile)));
+    }
+
+    /**
+     * @param string full URL to REST resource
+     * @param string original contents of the REST resource
+     * @param array  HTTP Last-Modified and ETag headers
+     * @param bool   if true, then the cache id file should be regenerated to
+     *               trigger a new time-to-live value
+     */
+    function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null)
+    {
+        $cachedir    = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url);
+        $cacheidfile = $cachedir . 'rest.cacheid';
+        $cachefile   = $cachedir . 'rest.cachefile';
+
+        if ($cacheid === null && $nochange) {
+            $cacheid = unserialize(implode('', file($cacheidfile)));
+        }
+
+        $fp = @fopen($cacheidfile, 'wb');
+        if (!$fp) {
+            $cache_dir = $this->config->get('cache_dir');
+            if (is_dir($cache_dir)) {
+                return false;
+            }
+
+            System::mkdir(array('-p', $cache_dir));
+            $fp = @fopen($cacheidfile, 'wb');
+            if (!$fp) {
+                return false;
+            }
+        }
+
+        if ($nochange) {
+            fwrite($fp, serialize(array(
+                'age'        => time(),
+                'lastChange' => $cacheid['lastChange'],
+                ))
+            );
+
+            fclose($fp);
+            return true;
+        }
+
+        fwrite($fp, serialize(array(
+            'age'        => time(),
+            'lastChange' => $lastmodified,
+            ))
+        );
+
+        fclose($fp);
+        $fp = @fopen($cachefile, 'wb');
+        if (!$fp) {
+            if (file_exists($cacheidfile)) {
+                @unlink($cacheidfile);
+            }
+
+            return false;
+        }
+
+        fwrite($fp, serialize($contents));
+        fclose($fp);
+        return true;
+    }
+
+    /**
+     * Efficiently Download a file through HTTP.  Returns downloaded file as a string in-memory
+     * This is best used for small files
+     *
+     * If an HTTP proxy has been configured (http_proxy PEAR_Config
+     * setting), the proxy will be used.
+     *
+     * @param string  $url       the URL to download
+     * @param string  $save_dir  directory to save file in
+     * @param false|string|array $lastmodified header values to check against for caching
+     *                           use false to return the header values from this download
+     * @param false|array $accept Accept headers to send
+     * @return string|array  Returns the contents of the downloaded file or a PEAR
+     *                       error on failure.  If the error is caused by
+     *                       socket-related errors, the error object will
+     *                       have the fsockopen error code available through
+     *                       getCode().  If caching is requested, then return the header
+     *                       values.
+     *
+     * @access public
+     */
+    function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false)
+    {
+        static $redirect = 0;
+        // always reset , so we are clean case of error
+        $wasredirect = $redirect;
+        $redirect = 0;
+
+        $info = parse_url($url);
+        if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) {
+            return PEAR::raiseError('Cannot download non-http URL "' . $url . '"');
+        }
+
+        if (!isset($info['host'])) {
+            return PEAR::raiseError('Cannot download from non-URL "' . $url . '"');
+        }
+
+        $host   = isset($info['host']) ? $info['host'] : null;
+        $port   = isset($info['port']) ? $info['port'] : null;
+        $path   = isset($info['path']) ? $info['path'] : null;
+        $schema = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http';
+
+        $proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
+        if ($this->config->get('http_proxy')&&
+              $proxy = parse_url($this->config->get('http_proxy'))
+        ) {
+            $proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
+            if ($schema === 'https') {
+                $proxy_host = 'ssl://' . $proxy_host;
+            }
+
+            $proxy_port   = isset($proxy['port']) ? $proxy['port'] : 8080;
+            $proxy_user   = isset($proxy['user']) ? urldecode($proxy['user']) : null;
+            $proxy_pass   = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
+            $proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http';
+        }
+
+        if (empty($port)) {
+            $port = (isset($info['scheme']) && $info['scheme'] == 'https')  ? 443 : 80;
+        }
+
+        if (isset($proxy['host'])) {
+            $request = "GET $url HTTP/1.1\r\n";
+        } else {
+            $request = "GET $path HTTP/1.1\r\n";
+        }
+
+        $request .= "Host: $host:$port\r\n";
+        $ifmodifiedsince = '';
+        if (is_array($lastmodified)) {
+            if (isset($lastmodified['Last-Modified'])) {
+                $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n";
+            }
+
+            if (isset($lastmodified['ETag'])) {
+                $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n";
+            }
+        } else {
+            $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : '');
+        }
+
+        $request .= $ifmodifiedsince .
+            "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n";
+
+        $username = $this->config->get('username', null, $channel);
+        $password = $this->config->get('password', null, $channel);
+
+        if ($username && $password) {
+            $tmp = base64_encode("$username:$password");
+            $request .= "Authorization: Basic $tmp\r\n";
+        }
+
+        if ($proxy_host != '' && $proxy_user != '') {
+            $request .= 'Proxy-Authorization: Basic ' .
+                base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n";
+        }
+
+        if ($accept) {
+            $request .= 'Accept: ' . implode(', ', $accept) . "\r\n";
+        }
+
+        $request .= "Accept-Encoding:\r\n";
+        $request .= "Connection: close\r\n";
+        $request .= "\r\n";
+
+        if ($proxy_host != '') {
+            $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15);
+            if (!$fp) {
+                return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", -9276);
+            }
+        } else {
+            if ($schema === 'https') {
+                $host = 'ssl://' . $host;
+            }
+
+            $fp = @fsockopen($host, $port, $errno, $errstr);
+            if (!$fp) {
+                return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
+            }
+        }
+
+        fwrite($fp, $request);
+
+        $headers = array();
+        $reply   = 0;
+        while ($line = trim(fgets($fp, 1024))) {
+            if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) {
+                $headers[strtolower($matches[1])] = trim($matches[2]);
+            } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
+                $reply = (int)$matches[1];
+                if ($reply == 304 && ($lastmodified || ($lastmodified === false))) {
+                    return false;
+                }
+
+                if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) {
+                    return PEAR::raiseError("File $schema://$host:$port$path not valid (received: $line)");
+                }
+            }
+        }
+
+        if ($reply != 200) {
+            if (!isset($headers['location'])) {
+                return PEAR::raiseError("File $schema://$host:$port$path not valid (redirected but no location)");
+            }
+
+            if ($wasredirect > 4) {
+                return PEAR::raiseError("File $schema://$host:$port$path not valid (redirection looped more than 5 times)");
+            }
+
+            $redirect = $wasredirect + 1;
+            return $this->downloadHttp($headers['location'], $lastmodified, $accept, $channel);
+        }
+
+        $length = isset($headers['content-length']) ? $headers['content-length'] : -1;
+
+        $data = '';
+        while ($chunk = @fread($fp, 8192)) {
+            $data .= $chunk;
+        }
+        fclose($fp);
+
+        if ($lastmodified === false || $lastmodified) {
+            if (isset($headers['etag'])) {
+                $lastmodified = array('ETag' => $headers['etag']);
+            }
+
+            if (isset($headers['last-modified'])) {
+                if (is_array($lastmodified)) {
+                    $lastmodified['Last-Modified'] = $headers['last-modified'];
+                } else {
+                    $lastmodified = $headers['last-modified'];
+                }
+            }
+
+            return array($data, $lastmodified, $headers);
+        }
+
+        return $data;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/REST/10.php b/lib/php/PEAR/REST/10.php
new file mode 100644
index 00000000..77761011
--- /dev/null
+++ b/lib/php/PEAR/REST/10.php
@@ -0,0 +1,867 @@
+<?php
+/**
+ * PEAR_REST_10
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: 10.php 287558 2009-08-21 22:21:28Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a12
+ */
+
+/**
+ * For downloading REST xml/txt files
+ */
+require_once 'PEAR/REST.php';
+
+/**
+ * Implement REST 1.0
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a12
+ */
+class PEAR_REST_10
+{
+    /**
+     * @var PEAR_REST
+     */
+    var $_rest;
+    function PEAR_REST_10($config, $options = array())
+    {
+        $this->_rest = &new PEAR_REST($config, $options);
+    }
+
+    /**
+     * Retrieve information about a remote package to be downloaded from a REST server
+     *
+     * @param string $base The uri to prepend to all REST calls
+     * @param array $packageinfo an array of format:
+     * <pre>
+     *  array(
+     *   'package' => 'packagename',
+     *   'channel' => 'channelname',
+     *  ['state' => 'alpha' (or valid state),]
+     *  -or-
+     *  ['version' => '1.whatever']
+     * </pre>
+     * @param string $prefstate Current preferred_state config variable value
+     * @param bool $installed the installed version of this package to compare against
+     * @return array|false|PEAR_Error see {@link _returnDownloadURL()}
+     */
+    function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false)
+    {
+        $states = $this->betterStates($prefstate, true);
+        if (!$states) {
+            return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
+        }
+
+        $channel  = $packageinfo['channel'];
+        $package  = $packageinfo['package'];
+        $state    = isset($packageinfo['state'])   ? $packageinfo['state']   : null;
+        $version  = isset($packageinfo['version']) ? $packageinfo['version'] : null;
+        $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml';
+
+        $info = $this->_rest->retrieveData($restFile, false, false, $channel);
+        if (PEAR::isError($info)) {
+            return PEAR::raiseError('No releases available for package "' .
+                $channel . '/' . $package . '"');
+        }
+
+        if (!isset($info['r'])) {
+            return false;
+        }
+
+        $release = $found = false;
+        if (!is_array($info['r']) || !isset($info['r'][0])) {
+            $info['r'] = array($info['r']);
+        }
+
+        foreach ($info['r'] as $release) {
+            if (!isset($this->_rest->_options['force']) && ($installed &&
+                  version_compare($release['v'], $installed, '<'))) {
+                continue;
+            }
+
+            if (isset($state)) {
+                // try our preferred state first
+                if ($release['s'] == $state) {
+                    $found = true;
+                    break;
+                }
+                // see if there is something newer and more stable
+                // bug #7221
+                if (in_array($release['s'], $this->betterStates($state), true)) {
+                    $found = true;
+                    break;
+                }
+            } elseif (isset($version)) {
+                if ($release['v'] == $version) {
+                    $found = true;
+                    break;
+                }
+            } else {
+                if (in_array($release['s'], $states)) {
+                    $found = true;
+                    break;
+                }
+            }
+        }
+
+        return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel);
+    }
+
+    function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage,
+                               $prefstate = 'stable', $installed = false, $channel = false)
+    {
+        $states = $this->betterStates($prefstate, true);
+        if (!$states) {
+            return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
+        }
+
+        $channel  = $dependency['channel'];
+        $package  = $dependency['name'];
+        $state    = isset($dependency['state'])   ? $dependency['state']   : null;
+        $version  = isset($dependency['version']) ? $dependency['version'] : null;
+        $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml';
+
+        $info = $this->_rest->retrieveData($restFile, false, false, $channel);
+        if (PEAR::isError($info)) {
+            return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package']
+                . '" dependency "' . $channel . '/' . $package . '" has no releases');
+        }
+
+        if (!is_array($info) || !isset($info['r'])) {
+            return false;
+        }
+
+        $exclude = array();
+        $min = $max = $recommended = false;
+        if ($xsdversion == '1.0') {
+            switch ($dependency['rel']) {
+                case 'ge' :
+                    $min = $dependency['version'];
+                break;
+                case 'gt' :
+                    $min = $dependency['version'];
+                    $exclude = array($dependency['version']);
+                break;
+                case 'eq' :
+                    $recommended = $dependency['version'];
+                break;
+                case 'lt' :
+                    $max = $dependency['version'];
+                    $exclude = array($dependency['version']);
+                break;
+                case 'le' :
+                    $max = $dependency['version'];
+                break;
+                case 'ne' :
+                    $exclude = array($dependency['version']);
+                break;
+            }
+        } else {
+            $min = isset($dependency['min']) ? $dependency['min'] : false;
+            $max = isset($dependency['max']) ? $dependency['max'] : false;
+            $recommended = isset($dependency['recommended']) ?
+                $dependency['recommended'] : false;
+            if (isset($dependency['exclude'])) {
+                if (!isset($dependency['exclude'][0])) {
+                    $exclude = array($dependency['exclude']);
+                }
+            }
+        }
+        $release = $found = false;
+        if (!is_array($info['r']) || !isset($info['r'][0])) {
+            $info['r'] = array($info['r']);
+        }
+        foreach ($info['r'] as $release) {
+            if (!isset($this->_rest->_options['force']) && ($installed &&
+                  version_compare($release['v'], $installed, '<'))) {
+                continue;
+            }
+            if (in_array($release['v'], $exclude)) { // skip excluded versions
+                continue;
+            }
+            // allow newer releases to say "I'm OK with the dependent package"
+            if ($xsdversion == '2.0' && isset($release['co'])) {
+                if (!is_array($release['co']) || !isset($release['co'][0])) {
+                    $release['co'] = array($release['co']);
+                }
+                foreach ($release['co'] as $entry) {
+                    if (isset($entry['x']) && !is_array($entry['x'])) {
+                        $entry['x'] = array($entry['x']);
+                    } elseif (!isset($entry['x'])) {
+                        $entry['x'] = array();
+                    }
+                    if ($entry['c'] == $deppackage['channel'] &&
+                          strtolower($entry['p']) == strtolower($deppackage['package']) &&
+                          version_compare($deppackage['version'], $entry['min'], '>=') &&
+                          version_compare($deppackage['version'], $entry['max'], '<=') &&
+                          !in_array($release['v'], $entry['x'])) {
+                        $recommended = $release['v'];
+                        break;
+                    }
+                }
+            }
+            if ($recommended) {
+                if ($release['v'] != $recommended) { // if we want a specific
+                    // version, then skip all others
+                    continue;
+                } else {
+                    if (!in_array($release['s'], $states)) {
+                        // the stability is too low, but we must return the
+                        // recommended version if possible
+                        return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel);
+                    }
+                }
+            }
+            if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions
+                continue;
+            }
+            if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions
+                continue;
+            }
+            if ($installed && version_compare($release['v'], $installed, '<')) {
+                continue;
+            }
+            if (in_array($release['s'], $states)) { // if in the preferred state...
+                $found = true; // ... then use it
+                break;
+            }
+        }
+        return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel);
+    }
+
+    /**
+     * Take raw data and return the array needed for processing a download URL
+     *
+     * @param string $base REST base uri
+     * @param string $package Package name
+     * @param array $release an array of format array('v' => version, 's' => state)
+     *                       describing the release to download
+     * @param array $info list of all releases as defined by allreleases.xml
+     * @param bool|null $found determines whether the release was found or this is the next
+     *                    best alternative.  If null, then versions were skipped because
+     *                    of PHP dependency
+     * @return array|PEAR_Error
+     * @access private
+     */
+    function _returnDownloadURL($base, $package, $release, $info, $found, $phpversion = false, $channel = false)
+    {
+        if (!$found) {
+            $release = $info['r'][0];
+        }
+
+        $packageLower = strtolower($package);
+        $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' .
+            'info.xml', false, false, $channel);
+        if (PEAR::isError($pinfo)) {
+            return PEAR::raiseError('Package "' . $package .
+                '" does not have REST info xml available');
+        }
+
+        $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' .
+            $release['v'] . '.xml', false, false, $channel);
+        if (PEAR::isError($releaseinfo)) {
+            return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] .
+                '" does not have REST xml available');
+        }
+
+        $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' .
+            'deps.' . $release['v'] . '.txt', false, true, $channel);
+        if (PEAR::isError($packagexml)) {
+            return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] .
+                '" does not have REST dependency information available');
+        }
+
+        $packagexml = unserialize($packagexml);
+        if (!$packagexml) {
+            $packagexml = array();
+        }
+
+        $allinfo = $this->_rest->retrieveData($base . 'r/' . $packageLower .
+            '/allreleases.xml', false, false, $channel);
+        if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) {
+            $allinfo['r'] = array($allinfo['r']);
+        }
+
+        $compatible = false;
+        foreach ($allinfo['r'] as $release) {
+            if ($release['v'] != $releaseinfo['v']) {
+                continue;
+            }
+
+            if (!isset($release['co'])) {
+                break;
+            }
+
+            $compatible = array();
+            if (!is_array($release['co']) || !isset($release['co'][0])) {
+                $release['co'] = array($release['co']);
+            }
+
+            foreach ($release['co'] as $entry) {
+                $comp = array();
+                $comp['name']    = $entry['p'];
+                $comp['channel'] = $entry['c'];
+                $comp['min']     = $entry['min'];
+                $comp['max']     = $entry['max'];
+                if (isset($entry['x']) && !is_array($entry['x'])) {
+                    $comp['exclude'] = $entry['x'];
+                }
+
+                $compatible[] = $comp;
+            }
+
+            if (count($compatible) == 1) {
+                $compatible = $compatible[0];
+            }
+
+            break;
+        }
+
+        $deprecated = false;
+        if (isset($pinfo['dc']) && isset($pinfo['dp'])) {
+            if (is_array($pinfo['dp'])) {
+                $deprecated = array('channel' => (string) $pinfo['dc'],
+                                    'package' => trim($pinfo['dp']['_content']));
+            } else {
+                $deprecated = array('channel' => (string) $pinfo['dc'],
+                                    'package' => trim($pinfo['dp']));
+            }
+        }
+
+        $return = array(
+            'version'    => $releaseinfo['v'],
+            'info'       => $packagexml,
+            'package'    => $releaseinfo['p']['_content'],
+            'stability'  => $releaseinfo['st'],
+            'compatible' => $compatible,
+            'deprecated' => $deprecated,
+        );
+
+        if ($found) {
+            $return['url'] = $releaseinfo['g'];
+            return $return;
+        }
+
+        $return['php'] = $phpversion;
+        return $return;
+    }
+
+    function listPackages($base, $channel = false)
+    {
+        $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
+        if (PEAR::isError($packagelist)) {
+            return $packagelist;
+        }
+
+        if (!is_array($packagelist) || !isset($packagelist['p'])) {
+            return array();
+        }
+
+        if (!is_array($packagelist['p'])) {
+            $packagelist['p'] = array($packagelist['p']);
+        }
+
+        return $packagelist['p'];
+    }
+
+    /**
+     * List all categories of a REST server
+     *
+     * @param string $base base URL of the server
+     * @return array of categorynames
+     */
+    function listCategories($base, $channel = false)
+    {
+        $categories = array();
+
+        // c/categories.xml does not exist;
+        // check for every package its category manually
+        // This is SLOOOWWWW : ///
+        $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
+        if (PEAR::isError($packagelist)) {
+            return $packagelist;
+        }
+
+        if (!is_array($packagelist) || !isset($packagelist['p'])) {
+            $ret = array();
+            return $ret;
+        }
+
+        if (!is_array($packagelist['p'])) {
+            $packagelist['p'] = array($packagelist['p']);
+        }
+
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        foreach ($packagelist['p'] as $package) {
+                $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
+                if (PEAR::isError($inf)) {
+                    PEAR::popErrorHandling();
+                    return $inf;
+                }
+                $cat = $inf['ca']['_content'];
+                if (!isset($categories[$cat])) {
+                    $categories[$cat] = $inf['ca'];
+                }
+        }
+
+        return array_values($categories);
+    }
+
+    /**
+     * List a category of a REST server
+     *
+     * @param string $base base URL of the server
+     * @param string $category name of the category
+     * @param boolean $info also download full package info
+     * @return array of packagenames
+     */
+    function listCategory($base, $category, $info = false, $channel = false)
+    {
+        // gives '404 Not Found' error when category doesn't exist
+        $packagelist = $this->_rest->retrieveData($base.'c/'.urlencode($category).'/packages.xml', false, false, $channel);
+        if (PEAR::isError($packagelist)) {
+            return $packagelist;
+        }
+
+        if (!is_array($packagelist) || !isset($packagelist['p'])) {
+            return array();
+        }
+
+        if (!is_array($packagelist['p']) ||
+            !isset($packagelist['p'][0])) { // only 1 pkg
+            $packagelist = array($packagelist['p']);
+        } else {
+            $packagelist = $packagelist['p'];
+        }
+
+        if ($info == true) {
+            // get individual package info
+            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+            foreach ($packagelist as $i => $packageitem) {
+                $url = sprintf('%s'.'r/%s/latest.txt',
+                        $base,
+                        strtolower($packageitem['_content']));
+                $version = $this->_rest->retrieveData($url, false, false, $channel);
+                if (PEAR::isError($version)) {
+                    break; // skipit
+                }
+                $url = sprintf('%s'.'r/%s/%s.xml',
+                        $base,
+                        strtolower($packageitem['_content']),
+                        $version);
+                $info = $this->_rest->retrieveData($url, false, false, $channel);
+                if (PEAR::isError($info)) {
+                    break; // skipit
+                }
+                $packagelist[$i]['info'] = $info;
+            }
+            PEAR::popErrorHandling();
+        }
+
+        return $packagelist;
+    }
+
+
+    function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false)
+    {
+        $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
+        if (PEAR::isError($packagelist)) {
+            return $packagelist;
+        }
+        if ($this->_rest->config->get('verbose') > 0) {
+            $ui = &PEAR_Frontend::singleton();
+            $ui->log('Retrieving data...0%', true);
+        }
+        $ret = array();
+        if (!is_array($packagelist) || !isset($packagelist['p'])) {
+            return $ret;
+        }
+        if (!is_array($packagelist['p'])) {
+            $packagelist['p'] = array($packagelist['p']);
+        }
+
+        // only search-packagename = quicksearch !
+        if ($searchpackage && (!$searchsummary || empty($searchpackage))) {
+            $newpackagelist = array();
+            foreach ($packagelist['p'] as $package) {
+                if (!empty($searchpackage) && stristr($package, $searchpackage) !== false) {
+                    $newpackagelist[] = $package;
+                }
+            }
+            $packagelist['p'] = $newpackagelist;
+        }
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        $next = .1;
+        foreach ($packagelist['p'] as $progress => $package) {
+            if ($this->_rest->config->get('verbose') > 0) {
+                if ($progress / count($packagelist['p']) >= $next) {
+                    if ($next == .5) {
+                        $ui->log('50%', false);
+                    } else {
+                        $ui->log('.', false);
+                    }
+                    $next += .1;
+                }
+            }
+
+            if ($basic) { // remote-list command
+                if ($dostable) {
+                    $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
+                        '/stable.txt', false, false, $channel);
+                } else {
+                    $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
+                        '/latest.txt', false, false, $channel);
+                }
+                if (PEAR::isError($latest)) {
+                    $latest = false;
+                }
+                $info = array('stable' => $latest);
+            } else { // list-all command
+                $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
+                if (PEAR::isError($inf)) {
+                    PEAR::popErrorHandling();
+                    return $inf;
+                }
+                if ($searchpackage) {
+                    $found = (!empty($searchpackage) && stristr($package, $searchpackage) !== false);
+                    if (!$found && !(isset($searchsummary) && !empty($searchsummary)
+                        && (stristr($inf['s'], $searchsummary) !== false
+                            || stristr($inf['d'], $searchsummary) !== false)))
+                    {
+                        continue;
+                    };
+                }
+                $releases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
+                    '/allreleases.xml', false, false, $channel);
+                if (PEAR::isError($releases)) {
+                    continue;
+                }
+                if (!isset($releases['r'][0])) {
+                    $releases['r'] = array($releases['r']);
+                }
+                unset($latest);
+                unset($unstable);
+                unset($stable);
+                unset($state);
+                foreach ($releases['r'] as $release) {
+                    if (!isset($latest)) {
+                        if ($dostable && $release['s'] == 'stable') {
+                            $latest = $release['v'];
+                            $state = 'stable';
+                        }
+                        if (!$dostable) {
+                            $latest = $release['v'];
+                            $state = $release['s'];
+                        }
+                    }
+                    if (!isset($stable) && $release['s'] == 'stable') {
+                        $stable = $release['v'];
+                        if (!isset($unstable)) {
+                            $unstable = $stable;
+                        }
+                    }
+                    if (!isset($unstable) && $release['s'] != 'stable') {
+                        $latest = $unstable = $release['v'];
+                        $state = $release['s'];
+                    }
+                    if (isset($latest) && !isset($state)) {
+                        $state = $release['s'];
+                    }
+                    if (isset($latest) && isset($stable) && isset($unstable)) {
+                        break;
+                    }
+                }
+                $deps = array();
+                if (!isset($unstable)) {
+                    $unstable = false;
+                    $state = 'stable';
+                    if (isset($stable)) {
+                        $latest = $unstable = $stable;
+                    }
+                } else {
+                    $latest = $unstable;
+                }
+                if (!isset($latest)) {
+                    $latest = false;
+                }
+                if ($latest) {
+                    $d = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' .
+                        $latest . '.txt', false, false, $channel);
+                    if (!PEAR::isError($d)) {
+                        $d = unserialize($d);
+                        if ($d) {
+                            if (isset($d['required'])) {
+                                if (!class_exists('PEAR_PackageFile_v2')) {
+                                    require_once 'PEAR/PackageFile/v2.php';
+                                }
+                                if (!isset($pf)) {
+                                    $pf = new PEAR_PackageFile_v2;
+                                }
+                                $pf->setDeps($d);
+                                $tdeps = $pf->getDeps();
+                            } else {
+                                $tdeps = $d;
+                            }
+                            foreach ($tdeps as $dep) {
+                                if ($dep['type'] !== 'pkg') {
+                                    continue;
+                                }
+                                $deps[] = $dep;
+                            }
+                        }
+                    }
+                }
+                if (!isset($stable)) {
+                    $stable = '-n/a-';
+                }
+                if (!$searchpackage) {
+                    $info = array('stable' => $latest, 'summary' => $inf['s'], 'description' =>
+                        $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'],
+                        'unstable' => $unstable, 'state' => $state);
+                } else {
+                    $info = array('stable' => $stable, 'summary' => $inf['s'], 'description' =>
+                        $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'],
+                        'unstable' => $unstable, 'state' => $state);
+                }
+            }
+            $ret[$package] = $info;
+        }
+        PEAR::popErrorHandling();
+        return $ret;
+    }
+
+    function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg)
+    {
+        $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
+        if (PEAR::isError($packagelist)) {
+            return $packagelist;
+        }
+
+        $ret = array();
+        if (!is_array($packagelist) || !isset($packagelist['p'])) {
+            return $ret;
+        }
+
+        if (!is_array($packagelist['p'])) {
+            $packagelist['p'] = array($packagelist['p']);
+        }
+
+        foreach ($packagelist['p'] as $package) {
+            if (!isset($installed[strtolower($package)])) {
+                continue;
+            }
+
+            $inst_version = $reg->packageInfo($package, 'version', $channel);
+            $inst_state   = $reg->packageInfo($package, 'release_state', $channel);
+            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+            $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
+                '/allreleases.xml', false, false, $channel);
+            PEAR::popErrorHandling();
+            if (PEAR::isError($info)) {
+                continue; // no remote releases
+            }
+
+            if (!isset($info['r'])) {
+                continue;
+            }
+
+            $release = $found = false;
+            if (!is_array($info['r']) || !isset($info['r'][0])) {
+                $info['r'] = array($info['r']);
+            }
+
+            // $info['r'] is sorted by version number
+            usort($info['r'], array($this, '_sortReleasesByVersionNumber'));
+            foreach ($info['r'] as $release) {
+                if ($inst_version && version_compare($release['v'], $inst_version, '<=')) {
+                    // not newer than the one installed
+                    break;
+                }
+
+                // new version > installed version
+                if (!$pref_state) {
+                    // every state is a good state
+                    $found = true;
+                    break;
+                } else {
+                    $new_state = $release['s'];
+                    // if new state >= installed state: go
+                    if (in_array($new_state, $this->betterStates($inst_state, true))) {
+                        $found = true;
+                        break;
+                    } else {
+                        // only allow to lower the state of package,
+                        // if new state >= preferred state: go
+                        if (in_array($new_state, $this->betterStates($pref_state, true))) {
+                            $found = true;
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (!$found) {
+                continue;
+            }
+
+            $relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
+                $release['v'] . '.xml', false, false, $channel);
+            if (PEAR::isError($relinfo)) {
+                return $relinfo;
+            }
+
+            $ret[$package] = array(
+                'version'  => $release['v'],
+                'state'    => $release['s'],
+                'filesize' => $relinfo['f'],
+            );
+        }
+
+        return $ret;
+    }
+
+    function packageInfo($base, $package, $channel = false)
+    {
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        $pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
+        if (PEAR::isError($pinfo)) {
+            PEAR::popErrorHandling();
+            return PEAR::raiseError('Unknown package: "' . $package . '" in channel "' . $channel . '"' . "\n". 'Debug: ' .
+                $pinfo->getMessage());
+        }
+
+        $releases = array();
+        $allreleases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
+            '/allreleases.xml', false, false, $channel);
+        if (!PEAR::isError($allreleases)) {
+            if (!class_exists('PEAR_PackageFile_v2')) {
+                require_once 'PEAR/PackageFile/v2.php';
+            }
+
+            if (!is_array($allreleases['r']) || !isset($allreleases['r'][0])) {
+                $allreleases['r'] = array($allreleases['r']);
+            }
+
+            $pf = new PEAR_PackageFile_v2;
+            foreach ($allreleases['r'] as $release) {
+                $ds = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' .
+                    $release['v'] . '.txt', false, false, $channel);
+                if (PEAR::isError($ds)) {
+                    continue;
+                }
+
+                if (!isset($latest)) {
+                    $latest = $release['v'];
+                }
+
+                $pf->setDeps(unserialize($ds));
+                $ds = $pf->getDeps();
+                $info = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package)
+                    . '/' . $release['v'] . '.xml', false, false, $channel);
+
+                if (PEAR::isError($info)) {
+                    continue;
+                }
+
+                $releases[$release['v']] = array(
+                    'doneby' => $info['m'],
+                    'license' => $info['l'],
+                    'summary' => $info['s'],
+                    'description' => $info['d'],
+                    'releasedate' => $info['da'],
+                    'releasenotes' => $info['n'],
+                    'state' => $release['s'],
+                    'deps' => $ds ? $ds : array(),
+                );
+            }
+        } else {
+            $latest = '';
+        }
+
+        PEAR::popErrorHandling();
+        if (isset($pinfo['dc']) && isset($pinfo['dp'])) {
+            if (is_array($pinfo['dp'])) {
+                $deprecated = array('channel' => (string) $pinfo['dc'],
+                                    'package' => trim($pinfo['dp']['_content']));
+            } else {
+                $deprecated = array('channel' => (string) $pinfo['dc'],
+                                    'package' => trim($pinfo['dp']));
+            }
+        } else {
+            $deprecated = false;
+        }
+
+        if (!isset($latest)) {
+            $latest = '';
+        }
+
+        return array(
+            'name' => $pinfo['n'],
+            'channel' => $pinfo['c'],
+            'category' => $pinfo['ca']['_content'],
+            'stable' => $latest,
+            'license' => $pinfo['l'],
+            'summary' => $pinfo['s'],
+            'description' => $pinfo['d'],
+            'releases' => $releases,
+            'deprecated' => $deprecated,
+            );
+    }
+
+    /**
+     * Return an array containing all of the states that are more stable than
+     * or equal to the passed in state
+     *
+     * @param string Release state
+     * @param boolean Determines whether to include $state in the list
+     * @return false|array False if $state is not a valid release state
+     */
+    function betterStates($state, $include = false)
+    {
+        static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
+        $i = array_search($state, $states);
+        if ($i === false) {
+            return false;
+        }
+
+        if ($include) {
+            $i--;
+        }
+
+        return array_slice($states, $i + 1);
+    }
+
+    /**
+     * Sort releases by version number
+     *
+     * @access private
+     */
+    function _sortReleasesByVersionNumber($a, $b)
+    {
+        if (version_compare($a['v'], $b['v'], '=')) {
+            return 0;
+        }
+
+        if (version_compare($a['v'], $b['v'], '>')) {
+            return -1;
+        }
+
+        if (version_compare($a['v'], $b['v'], '<')) {
+            return 1;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/REST/11.php b/lib/php/PEAR/REST/11.php
new file mode 100644
index 00000000..02a90837
--- /dev/null
+++ b/lib/php/PEAR/REST/11.php
@@ -0,0 +1,341 @@
+<?php
+/**
+ * PEAR_REST_11 - implement faster list-all/remote-list command
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: 11.php 286670 2009-08-02 14:16:06Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.3
+ */
+
+/**
+ * For downloading REST xml/txt files
+ */
+require_once 'PEAR/REST.php';
+
+/**
+ * Implement REST 1.1
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.3
+ */
+class PEAR_REST_11
+{
+    /**
+     * @var PEAR_REST
+     */
+    var $_rest;
+
+    function PEAR_REST_11($config, $options = array())
+    {
+        $this->_rest = &new PEAR_REST($config, $options);
+    }
+
+    function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false)
+    {
+        $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
+        if (PEAR::isError($categorylist)) {
+            return $categorylist;
+        }
+
+        $ret = array();
+        if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) {
+            $categorylist['c'] = array($categorylist['c']);
+        }
+
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+
+        foreach ($categorylist['c'] as $progress => $category) {
+            $category = $category['_content'];
+            $packagesinfo = $this->_rest->retrieveData($base .
+                'c/' . urlencode($category) . '/packagesinfo.xml', false, false, $channel);
+
+            if (PEAR::isError($packagesinfo)) {
+                continue;
+            }
+
+            if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) {
+                continue;
+            }
+
+            if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) {
+                $packagesinfo['pi'] = array($packagesinfo['pi']);
+            }
+
+            foreach ($packagesinfo['pi'] as $packageinfo) {
+                if (empty($packageinfo)) {
+                    continue;
+                }
+
+                $info     = $packageinfo['p'];
+                $package  = $info['n'];
+                $releases = isset($packageinfo['a']) ? $packageinfo['a'] : false;
+                unset($latest);
+                unset($unstable);
+                unset($stable);
+                unset($state);
+
+                if ($releases) {
+                    if (!isset($releases['r'][0])) {
+                        $releases['r'] = array($releases['r']);
+                    }
+
+                    foreach ($releases['r'] as $release) {
+                        if (!isset($latest)) {
+                            if ($dostable && $release['s'] == 'stable') {
+                                $latest = $release['v'];
+                                $state = 'stable';
+                            }
+                            if (!$dostable) {
+                                $latest = $release['v'];
+                                $state = $release['s'];
+                            }
+                        }
+
+                        if (!isset($stable) && $release['s'] == 'stable') {
+                            $stable = $release['v'];
+                            if (!isset($unstable)) {
+                                $unstable = $stable;
+                            }
+                        }
+
+                        if (!isset($unstable) && $release['s'] != 'stable') {
+                            $unstable = $release['v'];
+                            $state = $release['s'];
+                        }
+
+                        if (isset($latest) && !isset($state)) {
+                            $state = $release['s'];
+                        }
+
+                        if (isset($latest) && isset($stable) && isset($unstable)) {
+                            break;
+                        }
+                    }
+                }
+
+                if ($basic) { // remote-list command
+                    if (!isset($latest)) {
+                        $latest = false;
+                    }
+
+                    if ($dostable) {
+                        // $state is not set if there are no releases
+                        if (isset($state) && $state == 'stable') {
+                            $ret[$package] = array('stable' => $latest);
+                        } else {
+                            $ret[$package] = array('stable' => '-n/a-');
+                        }
+                    } else {
+                        $ret[$package] = array('stable' => $latest);
+                    }
+
+                    continue;
+                }
+
+                // list-all command
+                if (!isset($unstable)) {
+                    $unstable = false;
+                    $state = 'stable';
+                    if (isset($stable)) {
+                        $latest = $unstable = $stable;
+                    }
+                } else {
+                    $latest = $unstable;
+                }
+
+                if (!isset($latest)) {
+                    $latest = false;
+                }
+
+                $deps = array();
+                if ($latest && isset($packageinfo['deps'])) {
+                    if (!is_array($packageinfo['deps']) ||
+                          !isset($packageinfo['deps'][0])
+                    ) {
+                        $packageinfo['deps'] = array($packageinfo['deps']);
+                    }
+
+                    $d = false;
+                    foreach ($packageinfo['deps'] as $dep) {
+                        if ($dep['v'] == $latest) {
+                            $d = unserialize($dep['d']);
+                        }
+                    }
+
+                    if ($d) {
+                        if (isset($d['required'])) {
+                            if (!class_exists('PEAR_PackageFile_v2')) {
+                                require_once 'PEAR/PackageFile/v2.php';
+                            }
+
+                            if (!isset($pf)) {
+                                $pf = new PEAR_PackageFile_v2;
+                            }
+
+                            $pf->setDeps($d);
+                            $tdeps = $pf->getDeps();
+                        } else {
+                            $tdeps = $d;
+                        }
+
+                        foreach ($tdeps as $dep) {
+                            if ($dep['type'] !== 'pkg') {
+                                continue;
+                            }
+
+                            $deps[] = $dep;
+                        }
+                    }
+                }
+
+                $info = array(
+                    'stable'      => $latest,
+                    'summary'     => $info['s'],
+                    'description' => $info['d'],
+                    'deps'        => $deps,
+                    'category'    => $info['ca']['_content'],
+                    'unstable'    => $unstable,
+                    'state'       => $state
+                );
+                $ret[$package] = $info;
+            }
+        }
+
+        PEAR::popErrorHandling();
+        return $ret;
+    }
+
+    /**
+     * List all categories of a REST server
+     *
+     * @param string $base base URL of the server
+     * @return array of categorynames
+     */
+    function listCategories($base, $channel = false)
+    {
+        $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
+        if (PEAR::isError($categorylist)) {
+            return $categorylist;
+        }
+
+        if (!is_array($categorylist) || !isset($categorylist['c'])) {
+            return array();
+        }
+
+        if (isset($categorylist['c']['_content'])) {
+            // only 1 category
+            $categorylist['c'] = array($categorylist['c']);
+        }
+
+        return $categorylist['c'];
+    }
+
+    /**
+     * List packages in a category of a REST server
+     *
+     * @param string $base base URL of the server
+     * @param string $category name of the category
+     * @param boolean $info also download full package info
+     * @return array of packagenames
+     */
+    function listCategory($base, $category, $info = false, $channel = false)
+    {
+        if ($info == false) {
+            $url = '%s'.'c/%s/packages.xml';
+        } else {
+            $url = '%s'.'c/%s/packagesinfo.xml';
+        }
+        $url = sprintf($url,
+                    $base,
+                    urlencode($category));
+
+        // gives '404 Not Found' error when category doesn't exist
+        $packagelist = $this->_rest->retrieveData($url, false, false, $channel);
+        if (PEAR::isError($packagelist)) {
+            return $packagelist;
+        }
+        if (!is_array($packagelist)) {
+            return array();
+        }
+
+        if ($info == false) {
+            if (!isset($packagelist['p'])) {
+                return array();
+            }
+            if (!is_array($packagelist['p']) ||
+                !isset($packagelist['p'][0])) { // only 1 pkg
+                $packagelist = array($packagelist['p']);
+            } else {
+                $packagelist = $packagelist['p'];
+            }
+            return $packagelist;
+        }
+
+        // info == true
+        if (!isset($packagelist['pi'])) {
+            return array();
+        }
+
+        if (!is_array($packagelist['pi']) ||
+            !isset($packagelist['pi'][0])) { // only 1 pkg
+            $packagelist_pre = array($packagelist['pi']);
+        } else {
+            $packagelist_pre = $packagelist['pi'];
+        }
+
+        $packagelist = array();
+        foreach ($packagelist_pre as $i => $item) {
+            // compatibility with r/<latest.txt>.xml
+            if (isset($item['a']['r'][0])) {
+                // multiple releases
+                $item['p']['v'] = $item['a']['r'][0]['v'];
+                $item['p']['st'] = $item['a']['r'][0]['s'];
+            } elseif (isset($item['a'])) {
+                // first and only release
+                $item['p']['v'] = $item['a']['r']['v'];
+                $item['p']['st'] = $item['a']['r']['s'];
+            }
+
+            $packagelist[$i] = array('attribs' => $item['p']['r'],
+                                     '_content' => $item['p']['n'],
+                                     'info' => $item['p']);
+        }
+
+        return $packagelist;
+    }
+
+    /**
+     * Return an array containing all of the states that are more stable than
+     * or equal to the passed in state
+     *
+     * @param string Release state
+     * @param boolean Determines whether to include $state in the list
+     * @return false|array False if $state is not a valid release state
+     */
+    function betterStates($state, $include = false)
+    {
+        static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
+        $i = array_search($state, $states);
+        if ($i === false) {
+            return false;
+        }
+        if ($include) {
+            $i--;
+        }
+        return array_slice($states, $i + 1);
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/REST/13.php b/lib/php/PEAR/REST/13.php
new file mode 100644
index 00000000..250adfe5
--- /dev/null
+++ b/lib/php/PEAR/REST/13.php
@@ -0,0 +1,299 @@
+<?php
+/**
+ * PEAR_REST_13
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: 13.php 287110 2009-08-11 18:51:15Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a12
+ */
+
+/**
+ * For downloading REST xml/txt files
+ */
+require_once 'PEAR/REST.php';
+require_once 'PEAR/REST/10.php';
+
+/**
+ * Implement REST 1.3
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a12
+ */
+class PEAR_REST_13 extends PEAR_REST_10
+{
+    /**
+     * Retrieve information about a remote package to be downloaded from a REST server
+     *
+     * This is smart enough to resolve the minimum PHP version dependency prior to download
+     * @param string $base The uri to prepend to all REST calls
+     * @param array $packageinfo an array of format:
+     * <pre>
+     *  array(
+     *   'package' => 'packagename',
+     *   'channel' => 'channelname',
+     *  ['state' => 'alpha' (or valid state),]
+     *  -or-
+     *  ['version' => '1.whatever']
+     * </pre>
+     * @param string $prefstate Current preferred_state config variable value
+     * @param bool $installed the installed version of this package to compare against
+     * @return array|false|PEAR_Error see {@link _returnDownloadURL()}
+     */
+    function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false)
+    {
+        $states = $this->betterStates($prefstate, true);
+        if (!$states) {
+            return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
+        }
+
+        $channel  = $packageinfo['channel'];
+        $package  = $packageinfo['package'];
+        $state    = isset($packageinfo['state'])   ? $packageinfo['state']   : null;
+        $version  = isset($packageinfo['version']) ? $packageinfo['version'] : null;
+        $restFile = $base . 'r/' . strtolower($package) . '/allreleases2.xml';
+
+        $info = $this->_rest->retrieveData($restFile, false, false, $channel);
+        if (PEAR::isError($info)) {
+            return PEAR::raiseError('No releases available for package "' .
+                $channel . '/' . $package . '"');
+        }
+
+        if (!isset($info['r'])) {
+            return false;
+        }
+
+        $release = $found = false;
+        if (!is_array($info['r']) || !isset($info['r'][0])) {
+            $info['r'] = array($info['r']);
+        }
+
+        $skippedphp = false;
+        foreach ($info['r'] as $release) {
+            if (!isset($this->_rest->_options['force']) && ($installed &&
+                  version_compare($release['v'], $installed, '<'))) {
+                continue;
+            }
+
+            if (isset($state)) {
+                // try our preferred state first
+                if ($release['s'] == $state) {
+                    if (!isset($version) && version_compare($release['m'], phpversion(), '>')) {
+                        // skip releases that require a PHP version newer than our PHP version
+                        $skippedphp = $release;
+                        continue;
+                    }
+                    $found = true;
+                    break;
+                }
+
+                // see if there is something newer and more stable
+                // bug #7221
+                if (in_array($release['s'], $this->betterStates($state), true)) {
+                    if (!isset($version) && version_compare($release['m'], phpversion(), '>')) {
+                        // skip releases that require a PHP version newer than our PHP version
+                        $skippedphp = $release;
+                        continue;
+                    }
+                    $found = true;
+                    break;
+                }
+            } elseif (isset($version)) {
+                if ($release['v'] == $version) {
+                    if (!isset($this->_rest->_options['force']) &&
+                          !isset($version) &&
+                          version_compare($release['m'], phpversion(), '>')) {
+                        // skip releases that require a PHP version newer than our PHP version
+                        $skippedphp = $release;
+                        continue;
+                    }
+                    $found = true;
+                    break;
+                }
+            } else {
+                if (in_array($release['s'], $states)) {
+                    if (version_compare($release['m'], phpversion(), '>')) {
+                        // skip releases that require a PHP version newer than our PHP version
+                        $skippedphp = $release;
+                        continue;
+                    }
+                    $found = true;
+                    break;
+                }
+            }
+        }
+
+        if (!$found && $skippedphp) {
+            $found = null;
+        }
+
+        return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel);
+    }
+
+    function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage,
+                               $prefstate = 'stable', $installed = false, $channel = false)
+    {
+        $states = $this->betterStates($prefstate, true);
+        if (!$states) {
+            return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
+        }
+
+        $channel  = $dependency['channel'];
+        $package  = $dependency['name'];
+        $state    = isset($dependency['state'])   ? $dependency['state']   : null;
+        $version  = isset($dependency['version']) ? $dependency['version'] : null;
+        $restFile = $base . 'r/' . strtolower($package) .'/allreleases2.xml';
+
+        $info = $this->_rest->retrieveData($restFile, false, false, $channel);
+        if (PEAR::isError($info)) {
+            return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package']
+                . '" dependency "' . $channel . '/' . $package . '" has no releases');
+        }
+
+        if (!is_array($info) || !isset($info['r'])) {
+            return false;
+        }
+
+        $exclude = array();
+        $min = $max = $recommended = false;
+        if ($xsdversion == '1.0') {
+            $pinfo['package'] = $dependency['name'];
+            $pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this
+            switch ($dependency['rel']) {
+                case 'ge' :
+                    $min = $dependency['version'];
+                break;
+                case 'gt' :
+                    $min = $dependency['version'];
+                    $exclude = array($dependency['version']);
+                break;
+                case 'eq' :
+                    $recommended = $dependency['version'];
+                break;
+                case 'lt' :
+                    $max = $dependency['version'];
+                    $exclude = array($dependency['version']);
+                break;
+                case 'le' :
+                    $max = $dependency['version'];
+                break;
+                case 'ne' :
+                    $exclude = array($dependency['version']);
+                break;
+            }
+        } else {
+            $pinfo['package'] = $dependency['name'];
+            $min = isset($dependency['min']) ? $dependency['min'] : false;
+            $max = isset($dependency['max']) ? $dependency['max'] : false;
+            $recommended = isset($dependency['recommended']) ?
+                $dependency['recommended'] : false;
+            if (isset($dependency['exclude'])) {
+                if (!isset($dependency['exclude'][0])) {
+                    $exclude = array($dependency['exclude']);
+                }
+            }
+        }
+
+        $skippedphp = $found = $release = false;
+        if (!is_array($info['r']) || !isset($info['r'][0])) {
+            $info['r'] = array($info['r']);
+        }
+
+        foreach ($info['r'] as $release) {
+            if (!isset($this->_rest->_options['force']) && ($installed &&
+                  version_compare($release['v'], $installed, '<'))) {
+                continue;
+            }
+
+            if (in_array($release['v'], $exclude)) { // skip excluded versions
+                continue;
+            }
+
+            // allow newer releases to say "I'm OK with the dependent package"
+            if ($xsdversion == '2.0' && isset($release['co'])) {
+                if (!is_array($release['co']) || !isset($release['co'][0])) {
+                    $release['co'] = array($release['co']);
+                }
+
+                foreach ($release['co'] as $entry) {
+                    if (isset($entry['x']) && !is_array($entry['x'])) {
+                        $entry['x'] = array($entry['x']);
+                    } elseif (!isset($entry['x'])) {
+                        $entry['x'] = array();
+                    }
+
+                    if ($entry['c'] == $deppackage['channel'] &&
+                          strtolower($entry['p']) == strtolower($deppackage['package']) &&
+                          version_compare($deppackage['version'], $entry['min'], '>=') &&
+                          version_compare($deppackage['version'], $entry['max'], '<=') &&
+                          !in_array($release['v'], $entry['x'])) {
+                        if (version_compare($release['m'], phpversion(), '>')) {
+                            // skip dependency releases that require a PHP version
+                            // newer than our PHP version
+                            $skippedphp = $release;
+                            continue;
+                        }
+
+                        $recommended = $release['v'];
+                        break;
+                    }
+                }
+            }
+
+            if ($recommended) {
+                if ($release['v'] != $recommended) { // if we want a specific
+                    // version, then skip all others
+                    continue;
+                }
+
+                if (!in_array($release['s'], $states)) {
+                    // the stability is too low, but we must return the
+                    // recommended version if possible
+                    return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel);
+                }
+            }
+
+            if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions
+                continue;
+            }
+
+            if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions
+                continue;
+            }
+
+            if ($installed && version_compare($release['v'], $installed, '<')) {
+                continue;
+            }
+
+            if (in_array($release['s'], $states)) { // if in the preferred state...
+                if (version_compare($release['m'], phpversion(), '>')) {
+                    // skip dependency releases that require a PHP version
+                    // newer than our PHP version
+                    $skippedphp = $release;
+                    continue;
+                }
+
+                $found = true; // ... then use it
+                break;
+            }
+        }
+
+        if (!$found && $skippedphp) {
+            $found = null;
+        }
+
+        return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel);
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Registry.php b/lib/php/PEAR/Registry.php
new file mode 100644
index 00000000..ae110010
--- /dev/null
+++ b/lib/php/PEAR/Registry.php
@@ -0,0 +1,2395 @@
+<?php
+/**
+ * PEAR_Registry
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Registry.php 287555 2009-08-21 21:27:27Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * for PEAR_Error
+ */
+require_once 'PEAR.php';
+require_once 'PEAR/DependencyDB.php';
+
+define('PEAR_REGISTRY_ERROR_LOCK',         -2);
+define('PEAR_REGISTRY_ERROR_FORMAT',       -3);
+define('PEAR_REGISTRY_ERROR_FILE',         -4);
+define('PEAR_REGISTRY_ERROR_CONFLICT',     -5);
+define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6);
+
+/**
+ * Administration class used to maintain the installed package database.
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V. V. Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Registry extends PEAR
+{
+    /**
+     * File containing all channel information.
+     * @var string
+     */
+    var $channels = '';
+
+    /** Directory where registry files are stored.
+     * @var string
+     */
+    var $statedir = '';
+
+    /** File where the file map is stored
+     * @var string
+     */
+    var $filemap = '';
+
+    /** Directory where registry files for channels are stored.
+     * @var string
+     */
+    var $channelsdir = '';
+
+    /** Name of file used for locking the registry
+     * @var string
+     */
+    var $lockfile = '';
+
+    /** File descriptor used during locking
+     * @var resource
+     */
+    var $lock_fp = null;
+
+    /** Mode used during locking
+     * @var int
+     */
+    var $lock_mode = 0; // XXX UNUSED
+
+    /** Cache of package information.  Structure:
+     * array(
+     *   'package' => array('id' => ... ),
+     *   ... )
+     * @var array
+     */
+    var $pkginfo_cache = array();
+
+    /** Cache of file map.  Structure:
+     * array( '/path/to/file' => 'package', ... )
+     * @var array
+     */
+    var $filemap_cache = array();
+
+    /**
+     * @var false|PEAR_ChannelFile
+     */
+    var $_pearChannel;
+
+    /**
+     * @var false|PEAR_ChannelFile
+     */
+    var $_peclChannel;
+
+    /**
+     * @var false|PEAR_ChannelFile
+     */
+    var $_docChannel;
+
+    /**
+     * @var PEAR_DependencyDB
+     */
+    var $_dependencyDB;
+
+    /**
+     * @var PEAR_Config
+     */
+    var $_config;
+
+    /**
+     * PEAR_Registry constructor.
+     *
+     * @param string (optional) PEAR install directory (for .php files)
+     * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if
+     *        default values are not desired.  Only used the very first time a PEAR
+     *        repository is initialized
+     * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if
+     *        default values are not desired.  Only used the very first time a PEAR
+     *        repository is initialized
+     *
+     * @access public
+     */
+    function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false,
+                           $pecl_channel = false)
+    {
+        parent::PEAR();
+        $this->setInstallDir($pear_install_dir);
+        $this->_pearChannel = $pear_channel;
+        $this->_peclChannel = $pecl_channel;
+        $this->_config      = false;
+    }
+
+    function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR)
+    {
+        $ds = DIRECTORY_SEPARATOR;
+        $this->install_dir = $pear_install_dir;
+        $this->channelsdir = $pear_install_dir.$ds.'.channels';
+        $this->statedir    = $pear_install_dir.$ds.'.registry';
+        $this->filemap     = $pear_install_dir.$ds.'.filemap';
+        $this->lockfile    = $pear_install_dir.$ds.'.lock';
+    }
+
+    function hasWriteAccess()
+    {
+        if (!file_exists($this->install_dir)) {
+            $dir = $this->install_dir;
+            while ($dir && $dir != '.') {
+                $olddir = $dir;
+                $dir    = dirname($dir);
+                if ($dir != '.' && file_exists($dir)) {
+                    if (is_writeable($dir)) {
+                        return true;
+                    }
+
+                    return false;
+                }
+
+                if ($dir == $olddir) { // this can happen in safe mode
+                    return @is_writable($dir);
+                }
+            }
+
+            return false;
+        }
+
+        return is_writeable($this->install_dir);
+    }
+
+    function setConfig(&$config, $resetInstallDir = true)
+    {
+        $this->_config = &$config;
+        if ($resetInstallDir) {
+            $this->setInstallDir($config->get('php_dir'));
+        }
+    }
+
+    function _initializeChannelDirs()
+    {
+        static $running = false;
+        if (!$running) {
+            $running = true;
+            $ds = DIRECTORY_SEPARATOR;
+            if (!is_dir($this->channelsdir) ||
+                  !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
+                  !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
+                  !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') ||
+                  !file_exists($this->channelsdir . $ds . '__uri.reg')) {
+                if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
+                    $pear_channel = $this->_pearChannel;
+                    if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) {
+                        if (!class_exists('PEAR_ChannelFile')) {
+                            require_once 'PEAR/ChannelFile.php';
+                        }
+
+                        $pear_channel = new PEAR_ChannelFile;
+                        $pear_channel->setAlias('pear');
+                        $pear_channel->setServer('pear.php.net');
+                        $pear_channel->setSummary('PHP Extension and Application Repository');
+                        $pear_channel->setDefaultPEARProtocols();
+                        $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
+                        $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
+                        $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/');
+                        //$pear_channel->setBaseURL('REST1.4', 'http://pear.php.net/rest/');
+                    } else {
+                        $pear_channel->setServer('pear.php.net');
+                        $pear_channel->setAlias('pear');
+                    }
+
+                    $pear_channel->validate();
+                    $this->_addChannel($pear_channel);
+                }
+
+                if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) {
+                    $pecl_channel = $this->_peclChannel;
+                    if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) {
+                        if (!class_exists('PEAR_ChannelFile')) {
+                            require_once 'PEAR/ChannelFile.php';
+                        }
+
+                        $pecl_channel = new PEAR_ChannelFile;
+                        $pecl_channel->setAlias('pecl');
+                        $pecl_channel->setServer('pecl.php.net');
+                        $pecl_channel->setSummary('PHP Extension Community Library');
+                        $pecl_channel->setDefaultPEARProtocols();
+                        $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/');
+                        $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/');
+                        $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
+                    } else {
+                        $pecl_channel->setServer('pecl.php.net');
+                        $pecl_channel->setAlias('pecl');
+                    }
+
+                    $pecl_channel->validate();
+                    $this->_addChannel($pecl_channel);
+                }
+
+                if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) {
+                    $doc_channel = $this->_docChannel;
+                    if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) {
+                        if (!class_exists('PEAR_ChannelFile')) {
+                            require_once 'PEAR/ChannelFile.php';
+                        }
+
+                        $doc_channel = new PEAR_ChannelFile;
+                        $doc_channel->setAlias('phpdocs');
+                        $doc_channel->setServer('doc.php.net');
+                        $doc_channel->setSummary('PHP Documentation Team');
+                        $doc_channel->setDefaultPEARProtocols();
+                        $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/');
+                        $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/');
+                        $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/');
+                    } else {
+                        $doc_channel->setServer('doc.php.net');
+                        $doc_channel->setAlias('doc');
+                    }
+
+                    $doc_channel->validate();
+                    $this->_addChannel($doc_channel);
+                }
+
+                if (!file_exists($this->channelsdir . $ds . '__uri.reg')) {
+                    if (!class_exists('PEAR_ChannelFile')) {
+                        require_once 'PEAR/ChannelFile.php';
+                    }
+
+                    $private = new PEAR_ChannelFile;
+                    $private->setName('__uri');
+                    $private->setDefaultPEARProtocols();
+                    $private->setBaseURL('REST1.0', '****');
+                    $private->setSummary('Pseudo-channel for static packages');
+                    $this->_addChannel($private);
+                }
+                $this->_rebuildFileMap();
+            }
+
+            $running = false;
+        }
+    }
+
+    function _initializeDirs()
+    {
+        $ds = DIRECTORY_SEPARATOR;
+        // XXX Compatibility code should be removed in the future
+        // rename all registry files if any to lowercase
+        if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) &&
+              $handle = opendir($this->statedir)) {
+            $dest = $this->statedir . $ds;
+            while (false !== ($file = readdir($handle))) {
+                if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) {
+                    rename($dest . $file, $dest . strtolower($file));
+                }
+            }
+            closedir($handle);
+        }
+
+        $this->_initializeChannelDirs();
+        if (!file_exists($this->filemap)) {
+            $this->_rebuildFileMap();
+        }
+        $this->_initializeDepDB();
+    }
+
+    function _initializeDepDB()
+    {
+        if (!isset($this->_dependencyDB)) {
+            static $initializing = false;
+            if (!$initializing) {
+                $initializing = true;
+                if (!$this->_config) { // never used?
+                    $file = OS_WINDOWS ? 'pear.ini' : '.pearrc';
+                    $this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR .
+                        $file);
+                    $this->_config->setRegistry($this);
+                    $this->_config->set('php_dir', $this->install_dir);
+                }
+
+                $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
+                if (PEAR::isError($this->_dependencyDB)) {
+                    // attempt to recover by removing the dep db
+                    if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') .
+                        DIRECTORY_SEPARATOR . '.depdb')) {
+                        @unlink($this->_config->get('php_dir', null, 'pear.php.net') .
+                            DIRECTORY_SEPARATOR . '.depdb');
+                    }
+
+                    $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
+                    if (PEAR::isError($this->_dependencyDB)) {
+                        echo $this->_dependencyDB->getMessage();
+                        echo 'Unrecoverable error';
+                        exit(1);
+                    }
+                }
+
+                $initializing = false;
+            }
+        }
+    }
+
+    /**
+     * PEAR_Registry destructor.  Makes sure no locks are forgotten.
+     *
+     * @access private
+     */
+    function _PEAR_Registry()
+    {
+        parent::_PEAR();
+        if (is_resource($this->lock_fp)) {
+            $this->_unlock();
+        }
+    }
+
+    /**
+     * Make sure the directory where we keep registry files exists.
+     *
+     * @return bool TRUE if directory exists, FALSE if it could not be
+     * created
+     *
+     * @access private
+     */
+    function _assertStateDir($channel = false)
+    {
+        if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
+            return $this->_assertChannelStateDir($channel);
+        }
+
+        static $init = false;
+        if (!file_exists($this->statedir)) {
+            if (!$this->hasWriteAccess()) {
+                return false;
+            }
+
+            require_once 'System.php';
+            if (!System::mkdir(array('-p', $this->statedir))) {
+                return $this->raiseError("could not create directory '{$this->statedir}'");
+            }
+            $init = true;
+        } elseif (!is_dir($this->statedir)) {
+            return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' .
+                'it already exists and is not a directory');
+        }
+
+        $ds = DIRECTORY_SEPARATOR;
+        if (!file_exists($this->channelsdir)) {
+            if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
+                  !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
+                  !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') ||
+                  !file_exists($this->channelsdir . $ds . '__uri.reg')) {
+                $init = true;
+            }
+        } elseif (!is_dir($this->channelsdir)) {
+            return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' .
+                'it already exists and is not a directory');
+        }
+
+        if ($init) {
+            static $running = false;
+            if (!$running) {
+                $running = true;
+                $this->_initializeDirs();
+                $running = false;
+                $init = false;
+            }
+        } else {
+            $this->_initializeDepDB();
+        }
+
+        return true;
+    }
+
+    /**
+     * Make sure the directory where we keep registry files exists for a non-standard channel.
+     *
+     * @param string channel name
+     * @return bool TRUE if directory exists, FALSE if it could not be
+     * created
+     *
+     * @access private
+     */
+    function _assertChannelStateDir($channel)
+    {
+        $ds = DIRECTORY_SEPARATOR;
+        if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
+            if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
+                $this->_initializeChannelDirs();
+            }
+            return $this->_assertStateDir($channel);
+        }
+
+        $channelDir = $this->_channelDirectoryName($channel);
+        if (!is_dir($this->channelsdir) ||
+              !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
+            $this->_initializeChannelDirs();
+        }
+
+        if (!file_exists($channelDir)) {
+            if (!$this->hasWriteAccess()) {
+                return false;
+            }
+
+            require_once 'System.php';
+            if (!System::mkdir(array('-p', $channelDir))) {
+                return $this->raiseError("could not create directory '" . $channelDir .
+                    "'");
+            }
+        } elseif (!is_dir($channelDir)) {
+            return $this->raiseError("could not create directory '" . $channelDir .
+                "', already exists and is not a directory");
+        }
+
+        return true;
+    }
+
+    /**
+     * Make sure the directory where we keep registry files for channels exists
+     *
+     * @return bool TRUE if directory exists, FALSE if it could not be
+     * created
+     *
+     * @access private
+     */
+    function _assertChannelDir()
+    {
+        if (!file_exists($this->channelsdir)) {
+            if (!$this->hasWriteAccess()) {
+                return false;
+            }
+
+            require_once 'System.php';
+            if (!System::mkdir(array('-p', $this->channelsdir))) {
+                return $this->raiseError("could not create directory '{$this->channelsdir}'");
+            }
+        } elseif (!is_dir($this->channelsdir)) {
+            return $this->raiseError("could not create directory '{$this->channelsdir}" .
+                "', it already exists and is not a directory");
+        }
+
+        if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
+            if (!$this->hasWriteAccess()) {
+                return false;
+            }
+
+            require_once 'System.php';
+            if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) {
+                return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'");
+            }
+        } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
+            return $this->raiseError("could not create directory '{$this->channelsdir}" .
+                "/.alias', it already exists and is not a directory");
+        }
+
+        return true;
+    }
+
+    /**
+     * Get the name of the file where data for a given package is stored.
+     *
+     * @param string channel name, or false if this is a PEAR package
+     * @param string package name
+     *
+     * @return string registry file name
+     *
+     * @access public
+     */
+    function _packageFileName($package, $channel = false)
+    {
+        if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
+            return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR .
+                strtolower($package) . '.reg';
+        }
+
+        return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg';
+    }
+
+    /**
+     * Get the name of the file where data for a given channel is stored.
+     * @param string channel name
+     * @return string registry file name
+     */
+    function _channelFileName($channel, $noaliases = false)
+    {
+        if (!$noaliases) {
+            if (file_exists($this->_getChannelAliasFileName($channel))) {
+                $channel = implode('', file($this->_getChannelAliasFileName($channel)));
+            }
+        }
+        return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_',
+            strtolower($channel)) . '.reg';
+    }
+
+    /**
+     * @param string
+     * @return string
+     */
+    function _getChannelAliasFileName($alias)
+    {
+        return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' .
+              DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt';
+    }
+
+    /**
+     * Get the name of a channel from its alias
+     */
+    function _getChannelFromAlias($channel)
+    {
+        if (!$this->_channelExists($channel)) {
+            if ($channel == 'pear.php.net') {
+                return 'pear.php.net';
+            }
+
+            if ($channel == 'pecl.php.net') {
+                return 'pecl.php.net';
+            }
+
+            if ($channel == 'doc.php.net') {
+                return 'doc.php.net';
+            }
+
+            if ($channel == '__uri') {
+                return '__uri';
+            }
+
+            return false;
+        }
+
+        $channel = strtolower($channel);
+        if (file_exists($this->_getChannelAliasFileName($channel))) {
+            // translate an alias to an actual channel
+            return implode('', file($this->_getChannelAliasFileName($channel)));
+        }
+
+        return $channel;
+    }
+
+    /**
+     * Get the alias of a channel from its alias or its name
+     */
+    function _getAlias($channel)
+    {
+        if (!$this->_channelExists($channel)) {
+            if ($channel == 'pear.php.net') {
+                return 'pear';
+            }
+
+            if ($channel == 'pecl.php.net') {
+                return 'pecl';
+            }
+
+            if ($channel == 'doc.php.net') {
+                return 'phpdocs';
+            }
+
+            return false;
+        }
+
+        $channel = $this->_getChannel($channel);
+        if (PEAR::isError($channel)) {
+            return $channel;
+        }
+
+        return $channel->getAlias();
+    }
+
+    /**
+     * Get the name of the file where data for a given package is stored.
+     *
+     * @param string channel name, or false if this is a PEAR package
+     * @param string package name
+     *
+     * @return string registry file name
+     *
+     * @access public
+     */
+    function _channelDirectoryName($channel)
+    {
+        if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
+            return $this->statedir;
+        }
+
+        $ch = $this->_getChannelFromAlias($channel);
+        if (!$ch) {
+            $ch = $channel;
+        }
+
+        return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' .
+            str_replace('/', '_', $ch));
+    }
+
+    function _openPackageFile($package, $mode, $channel = false)
+    {
+        if (!$this->_assertStateDir($channel)) {
+            return null;
+        }
+
+        if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
+            return null;
+        }
+
+        $file = $this->_packageFileName($package, $channel);
+        if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
+            return null;
+        }
+
+        $fp = @fopen($file, $mode);
+        if (!$fp) {
+            return null;
+        }
+
+        return $fp;
+    }
+
+    function _closePackageFile($fp)
+    {
+        fclose($fp);
+    }
+
+    function _openChannelFile($channel, $mode)
+    {
+        if (!$this->_assertChannelDir()) {
+            return null;
+        }
+
+        if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
+            return null;
+        }
+
+        $file = $this->_channelFileName($channel);
+        if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
+            return null;
+        }
+
+        $fp = @fopen($file, $mode);
+        if (!$fp) {
+            return null;
+        }
+
+        return $fp;
+    }
+
+    function _closeChannelFile($fp)
+    {
+        fclose($fp);
+    }
+
+    function _rebuildFileMap()
+    {
+        if (!class_exists('PEAR_Installer_Role')) {
+            require_once 'PEAR/Installer/Role.php';
+        }
+
+        $channels = $this->_listAllPackages();
+        $files = array();
+        foreach ($channels as $channel => $packages) {
+            foreach ($packages as $package) {
+                $version = $this->_packageInfo($package, 'version', $channel);
+                $filelist = $this->_packageInfo($package, 'filelist', $channel);
+                if (!is_array($filelist)) {
+                    continue;
+                }
+
+                foreach ($filelist as $name => $attrs) {
+                    if (isset($attrs['attribs'])) {
+                        $attrs = $attrs['attribs'];
+                    }
+
+                    // it is possible for conflicting packages in different channels to
+                    // conflict with data files/doc files
+                    if ($name == 'dirtree') {
+                        continue;
+                    }
+
+                    if (isset($attrs['role']) && !in_array($attrs['role'],
+                          PEAR_Installer_Role::getInstallableRoles())) {
+                        // these are not installed
+                        continue;
+                    }
+
+                    if (isset($attrs['role']) && !in_array($attrs['role'],
+                          PEAR_Installer_Role::getBaseinstallRoles())) {
+                        $attrs['baseinstalldir'] = $package;
+                    }
+
+                    if (isset($attrs['baseinstalldir'])) {
+                        $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name;
+                    } else {
+                        $file = $name;
+                    }
+
+                    $file = preg_replace(',^/+,', '', $file);
+                    if ($channel != 'pear.php.net') {
+                        if (!isset($files[$attrs['role']])) {
+                            $files[$attrs['role']] = array();
+                        }
+                        $files[$attrs['role']][$file] = array(strtolower($channel),
+                            strtolower($package));
+                    } else {
+                        if (!isset($files[$attrs['role']])) {
+                            $files[$attrs['role']] = array();
+                        }
+                        $files[$attrs['role']][$file] = strtolower($package);
+                    }
+                }
+            }
+        }
+
+
+        $this->_assertStateDir();
+        if (!$this->hasWriteAccess()) {
+            return false;
+        }
+
+        $fp = @fopen($this->filemap, 'wb');
+        if (!$fp) {
+            return false;
+        }
+
+        $this->filemap_cache = $files;
+        fwrite($fp, serialize($files));
+        fclose($fp);
+        return true;
+    }
+
+    function _readFileMap()
+    {
+        if (!file_exists($this->filemap)) {
+            return array();
+        }
+
+        $fp = @fopen($this->filemap, 'r');
+        if (!$fp) {
+            return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg);
+        }
+
+        clearstatcache();
+        $rt = get_magic_quotes_runtime();
+        set_magic_quotes_runtime(0);
+        $fsize = filesize($this->filemap);
+        fclose($fp);
+        $data = file_get_contents($this->filemap);
+        set_magic_quotes_runtime($rt);
+        $tmp = unserialize($data);
+        if (!$tmp && $fsize > 7) {
+            return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data);
+        }
+
+        $this->filemap_cache = $tmp;
+        return true;
+    }
+
+    /**
+     * Lock the registry.
+     *
+     * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN.
+     *                See flock manual for more information.
+     *
+     * @return bool TRUE on success, FALSE if locking failed, or a
+     *              PEAR error if some other error occurs (such as the
+     *              lock file not being writable).
+     *
+     * @access private
+     */
+    function _lock($mode = LOCK_EX)
+    {
+        if (stristr(php_uname(), 'Windows 9')) {
+            return true;
+        }
+
+        if ($mode != LOCK_UN && is_resource($this->lock_fp)) {
+            // XXX does not check type of lock (LOCK_SH/LOCK_EX)
+            return true;
+        }
+
+        if (!$this->_assertStateDir()) {
+            if ($mode == LOCK_EX) {
+                return $this->raiseError('Registry directory is not writeable by the current user');
+            }
+
+            return true;
+        }
+
+        $open_mode = 'w';
+        // XXX People reported problems with LOCK_SH and 'w'
+        if ($mode === LOCK_SH || $mode === LOCK_UN) {
+            if (!file_exists($this->lockfile)) {
+                touch($this->lockfile);
+            }
+            $open_mode = 'r';
+        }
+
+        if (!is_resource($this->lock_fp)) {
+            $this->lock_fp = @fopen($this->lockfile, $open_mode);
+        }
+
+        if (!is_resource($this->lock_fp)) {
+            $this->lock_fp = null;
+            return $this->raiseError("could not create lock file" .
+                                     (isset($php_errormsg) ? ": " . $php_errormsg : ""));
+        }
+
+        if (!(int)flock($this->lock_fp, $mode)) {
+            switch ($mode) {
+                case LOCK_SH: $str = 'shared';    break;
+                case LOCK_EX: $str = 'exclusive'; break;
+                case LOCK_UN: $str = 'unlock';    break;
+                default:      $str = 'unknown';   break;
+            }
+
+            //is resource at this point, close it on error.
+            fclose($this->lock_fp);
+            $this->lock_fp = null;
+            return $this->raiseError("could not acquire $str lock ($this->lockfile)",
+                                     PEAR_REGISTRY_ERROR_LOCK);
+        }
+
+        return true;
+    }
+
+    function _unlock()
+    {
+        $ret = $this->_lock(LOCK_UN);
+        if (is_resource($this->lock_fp)) {
+            fclose($this->lock_fp);
+        }
+
+        $this->lock_fp = null;
+        return $ret;
+    }
+
+    function _packageExists($package, $channel = false)
+    {
+        return file_exists($this->_packageFileName($package, $channel));
+    }
+
+    /**
+     * Determine whether a channel exists in the registry
+     *
+     * @param string Channel name
+     * @param bool if true, then aliases will be ignored
+     * @return boolean
+     */
+    function _channelExists($channel, $noaliases = false)
+    {
+        $a = file_exists($this->_channelFileName($channel, $noaliases));
+        if (!$a && $channel == 'pear.php.net') {
+            return true;
+        }
+
+        if (!$a && $channel == 'pecl.php.net') {
+            return true;
+        }
+
+        if (!$a && $channel == 'doc.php.net') {
+            return true;
+        }
+
+        return $a;
+    }
+
+    /**
+     * Determine whether a mirror exists within the deafult channel in the registry
+     *
+     * @param string Channel name
+     * @param string Mirror name
+     *
+     * @return boolean
+     */
+    function _mirrorExists($channel, $mirror)
+    {
+        $data = $this->_channelInfo($channel);
+        if (!isset($data['servers']['mirror'])) {
+            return false;
+        }
+
+        foreach ($data['servers']['mirror'] as $m) {
+            if ($m['attribs']['host'] == $mirror) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @param PEAR_ChannelFile Channel object
+     * @param donotuse
+     * @param string Last-Modified HTTP tag from remote request
+     * @return boolean|PEAR_Error True on creation, false if it already exists
+     */
+    function _addChannel($channel, $update = false, $lastmodified = false)
+    {
+        if (!is_a($channel, 'PEAR_ChannelFile')) {
+            return false;
+        }
+
+        if (!$channel->validate()) {
+            return false;
+        }
+
+        if (file_exists($this->_channelFileName($channel->getName()))) {
+            if (!$update) {
+                return false;
+            }
+
+            $checker = $this->_getChannel($channel->getName());
+            if (PEAR::isError($checker)) {
+                return $checker;
+            }
+
+            if ($channel->getAlias() != $checker->getAlias()) {
+                if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) {
+                    @unlink($this->_getChannelAliasFileName($checker->getAlias()));
+                }
+            }
+        } else {
+            if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) {
+                return false;
+            }
+        }
+
+        $ret = $this->_assertChannelDir();
+        if (PEAR::isError($ret)) {
+            return $ret;
+        }
+
+        $ret = $this->_assertChannelStateDir($channel->getName());
+        if (PEAR::isError($ret)) {
+            return $ret;
+        }
+
+        if ($channel->getAlias() != $channel->getName()) {
+            if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) &&
+                  $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) {
+                $channel->setAlias($channel->getName());
+            }
+
+            if (!$this->hasWriteAccess()) {
+                return false;
+            }
+
+            $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w');
+            if (!$fp) {
+                return false;
+            }
+
+            fwrite($fp, $channel->getName());
+            fclose($fp);
+        }
+
+        if (!$this->hasWriteAccess()) {
+            return false;
+        }
+
+        $fp = @fopen($this->_channelFileName($channel->getName()), 'wb');
+        if (!$fp) {
+            return false;
+        }
+
+        $info = $channel->toArray();
+        if ($lastmodified) {
+            $info['_lastmodified'] = $lastmodified;
+        } else {
+            $info['_lastmodified'] = date('r');
+        }
+
+        fwrite($fp, serialize($info));
+        fclose($fp);
+        return true;
+    }
+
+    /**
+     * Deletion fails if there are any packages installed from the channel
+     * @param string|PEAR_ChannelFile channel name
+     * @return boolean|PEAR_Error True on deletion, false if it doesn't exist
+     */
+    function _deleteChannel($channel)
+    {
+        if (!is_string($channel)) {
+            if (!is_a($channel, 'PEAR_ChannelFile')) {
+                return false;
+            }
+
+            if (!$channel->validate()) {
+                return false;
+            }
+            $channel = $channel->getName();
+        }
+
+        if ($this->_getChannelFromAlias($channel) == '__uri') {
+            return false;
+        }
+
+        if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
+            return false;
+        }
+
+        if ($this->_getChannelFromAlias($channel) == 'doc.php.net') {
+            return false;
+        }
+
+        if (!$this->_channelExists($channel)) {
+            return false;
+        }
+
+        if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
+            return false;
+        }
+
+        $channel = $this->_getChannelFromAlias($channel);
+        if ($channel == 'pear.php.net') {
+            return false;
+        }
+
+        $test = $this->_listChannelPackages($channel);
+        if (count($test)) {
+            return false;
+        }
+
+        $test = @rmdir($this->_channelDirectoryName($channel));
+        if (!$test) {
+            return false;
+        }
+
+        $file = $this->_getChannelAliasFileName($this->_getAlias($channel));
+        if (file_exists($file)) {
+            $test = @unlink($file);
+            if (!$test) {
+                return false;
+            }
+        }
+
+        $file = $this->_channelFileName($channel);
+        $ret = true;
+        if (file_exists($file)) {
+            $ret = @unlink($file);
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Determine whether a channel exists in the registry
+     * @param string Channel Alias
+     * @return boolean
+     */
+    function _isChannelAlias($alias)
+    {
+        return file_exists($this->_getChannelAliasFileName($alias));
+    }
+
+    /**
+     * @param string|null
+     * @param string|null
+     * @param string|null
+     * @return array|null
+     * @access private
+     */
+    function _packageInfo($package = null, $key = null, $channel = 'pear.php.net')
+    {
+        if ($package === null) {
+            if ($channel === null) {
+                $channels = $this->_listChannels();
+                $ret = array();
+                foreach ($channels as $channel) {
+                    $channel = strtolower($channel);
+                    $ret[$channel] = array();
+                    $packages = $this->_listPackages($channel);
+                    foreach ($packages as $package) {
+                        $ret[$channel][] = $this->_packageInfo($package, null, $channel);
+                    }
+                }
+
+                return $ret;
+            }
+
+            $ps = $this->_listPackages($channel);
+            if (!count($ps)) {
+                return array();
+            }
+            return array_map(array(&$this, '_packageInfo'),
+                             $ps, array_fill(0, count($ps), null),
+                             array_fill(0, count($ps), $channel));
+        }
+
+        $fp = $this->_openPackageFile($package, 'r', $channel);
+        if ($fp === null) {
+            return null;
+        }
+
+        $rt = get_magic_quotes_runtime();
+        set_magic_quotes_runtime(0);
+        clearstatcache();
+        $this->_closePackageFile($fp);
+        $data = file_get_contents($this->_packageFileName($package, $channel));
+        set_magic_quotes_runtime($rt);
+        $data = unserialize($data);
+        if ($key === null) {
+            return $data;
+        }
+
+        // compatibility for package.xml version 2.0
+        if (isset($data['old'][$key])) {
+            return $data['old'][$key];
+        }
+
+        if (isset($data[$key])) {
+            return $data[$key];
+        }
+
+        return null;
+    }
+
+    /**
+     * @param string Channel name
+     * @param bool whether to strictly retrieve info of channels, not just aliases
+     * @return array|null
+     */
+    function _channelInfo($channel, $noaliases = false)
+    {
+        if (!$this->_channelExists($channel, $noaliases)) {
+            return null;
+        }
+
+        $fp = $this->_openChannelFile($channel, 'r');
+        if ($fp === null) {
+            return null;
+        }
+
+        $rt = get_magic_quotes_runtime();
+        set_magic_quotes_runtime(0);
+        clearstatcache();
+        $this->_closeChannelFile($fp);
+        $data = file_get_contents($this->_channelFileName($channel));
+        set_magic_quotes_runtime($rt);
+        $data = unserialize($data);
+        return $data;
+    }
+
+    function _listChannels()
+    {
+        $channellist = array();
+        if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) {
+            return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri');
+        }
+
+        $dp = opendir($this->channelsdir);
+        while ($ent = readdir($dp)) {
+            if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
+                continue;
+            }
+
+            if ($ent == '__uri.reg') {
+                $channellist[] = '__uri';
+                continue;
+            }
+
+            $channellist[] = str_replace('_', '/', substr($ent, 0, -4));
+        }
+
+        closedir($dp);
+        if (!in_array('pear.php.net', $channellist)) {
+            $channellist[] = 'pear.php.net';
+        }
+
+        if (!in_array('pecl.php.net', $channellist)) {
+            $channellist[] = 'pecl.php.net';
+        }
+
+        if (!in_array('doc.php.net', $channellist)) {
+            $channellist[] = 'doc.php.net';
+        }
+
+
+        if (!in_array('__uri', $channellist)) {
+            $channellist[] = '__uri';
+        }
+
+        natsort($channellist);
+        return $channellist;
+    }
+
+    function _listPackages($channel = false)
+    {
+        if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
+            return $this->_listChannelPackages($channel);
+        }
+
+        if (!file_exists($this->statedir) || !is_dir($this->statedir)) {
+            return array();
+        }
+
+        $pkglist = array();
+        $dp = opendir($this->statedir);
+        if (!$dp) {
+            return $pkglist;
+        }
+
+        while ($ent = readdir($dp)) {
+            if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
+                continue;
+            }
+
+            $pkglist[] = substr($ent, 0, -4);
+        }
+        closedir($dp);
+        return $pkglist;
+    }
+
+    function _listChannelPackages($channel)
+    {
+        $pkglist = array();
+        if (!file_exists($this->_channelDirectoryName($channel)) ||
+              !is_dir($this->_channelDirectoryName($channel))) {
+            return array();
+        }
+
+        $dp = opendir($this->_channelDirectoryName($channel));
+        if (!$dp) {
+            return $pkglist;
+        }
+
+        while ($ent = readdir($dp)) {
+            if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
+                continue;
+            }
+            $pkglist[] = substr($ent, 0, -4);
+        }
+
+        closedir($dp);
+        return $pkglist;
+    }
+
+    function _listAllPackages()
+    {
+        $ret = array();
+        foreach ($this->_listChannels() as $channel) {
+            $ret[$channel] = $this->_listPackages($channel);
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Add an installed package to the registry
+     * @param string package name
+     * @param array package info (parsed by PEAR_Common::infoFrom*() methods)
+     * @return bool success of saving
+     * @access private
+     */
+    function _addPackage($package, $info)
+    {
+        if ($this->_packageExists($package)) {
+            return false;
+        }
+
+        $fp = $this->_openPackageFile($package, 'wb');
+        if ($fp === null) {
+            return false;
+        }
+
+        $info['_lastmodified'] = time();
+        fwrite($fp, serialize($info));
+        $this->_closePackageFile($fp);
+        if (isset($info['filelist'])) {
+            $this->_rebuildFileMap();
+        }
+
+        return true;
+    }
+
+    /**
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @return bool
+     * @access private
+     */
+    function _addPackage2($info)
+    {
+        if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) {
+            return false;
+        }
+
+        if (!$info->validate()) {
+            if (class_exists('PEAR_Common')) {
+                $ui = PEAR_Frontend::singleton();
+                if ($ui) {
+                    foreach ($info->getValidationWarnings() as $err) {
+                        $ui->log($err['message'], true);
+                    }
+                }
+            }
+            return false;
+        }
+
+        $channel = $info->getChannel();
+        $package = $info->getPackage();
+        $save = $info;
+        if ($this->_packageExists($package, $channel)) {
+            return false;
+        }
+
+        if (!$this->_channelExists($channel, true)) {
+            return false;
+        }
+
+        $info = $info->toArray(true);
+        if (!$info) {
+            return false;
+        }
+
+        $fp = $this->_openPackageFile($package, 'wb', $channel);
+        if ($fp === null) {
+            return false;
+        }
+
+        $info['_lastmodified'] = time();
+        fwrite($fp, serialize($info));
+        $this->_closePackageFile($fp);
+        $this->_rebuildFileMap();
+        return true;
+    }
+
+    /**
+     * @param string Package name
+     * @param array parsed package.xml 1.0
+     * @param bool this parameter is only here for BC.  Don't use it.
+     * @access private
+     */
+    function _updatePackage($package, $info, $merge = true)
+    {
+        $oldinfo = $this->_packageInfo($package);
+        if (empty($oldinfo)) {
+            return false;
+        }
+
+        $fp = $this->_openPackageFile($package, 'w');
+        if ($fp === null) {
+            return false;
+        }
+
+        if (is_object($info)) {
+            $info = $info->toArray();
+        }
+        $info['_lastmodified'] = time();
+
+        $newinfo = $info;
+        if ($merge) {
+            $info = array_merge($oldinfo, $info);
+        } else {
+            $diff = $info;
+        }
+
+        fwrite($fp, serialize($info));
+        $this->_closePackageFile($fp);
+        if (isset($newinfo['filelist'])) {
+            $this->_rebuildFileMap();
+        }
+
+        return true;
+    }
+
+    /**
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @return bool
+     * @access private
+     */
+    function _updatePackage2($info)
+    {
+        if (!$this->_packageExists($info->getPackage(), $info->getChannel())) {
+            return false;
+        }
+
+        $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel());
+        if ($fp === null) {
+            return false;
+        }
+
+        $save = $info;
+        $info = $save->getArray(true);
+        $info['_lastmodified'] = time();
+        fwrite($fp, serialize($info));
+        $this->_closePackageFile($fp);
+        $this->_rebuildFileMap();
+        return true;
+    }
+
+    /**
+     * @param string Package name
+     * @param string Channel name
+     * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null
+     * @access private
+     */
+    function &_getPackage($package, $channel = 'pear.php.net')
+    {
+        $info = $this->_packageInfo($package, null, $channel);
+        if ($info === null) {
+            return $info;
+        }
+
+        $a = $this->_config;
+        if (!$a) {
+            $this->_config = &new PEAR_Config;
+            $this->_config->set('php_dir', $this->statedir);
+        }
+
+        if (!class_exists('PEAR_PackageFile')) {
+            require_once 'PEAR/PackageFile.php';
+        }
+
+        $pkg = &new PEAR_PackageFile($this->_config);
+        $pf = &$pkg->fromArray($info);
+        return $pf;
+    }
+
+    /**
+     * @param string channel name
+     * @param bool whether to strictly retrieve channel names
+     * @return PEAR_ChannelFile|PEAR_Error
+     * @access private
+     */
+    function &_getChannel($channel, $noaliases = false)
+    {
+        $ch = false;
+        if ($this->_channelExists($channel, $noaliases)) {
+            $chinfo = $this->_channelInfo($channel, $noaliases);
+            if ($chinfo) {
+                if (!class_exists('PEAR_ChannelFile')) {
+                    require_once 'PEAR/ChannelFile.php';
+                }
+
+                $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo);
+            }
+        }
+
+        if ($ch) {
+            if ($ch->validate()) {
+                return $ch;
+            }
+
+            foreach ($ch->getErrors(true) as $err) {
+                $message = $err['message'] . "\n";
+            }
+
+            $ch = PEAR::raiseError($message);
+            return $ch;
+        }
+
+        if ($this->_getChannelFromAlias($channel) == 'pear.php.net') {
+            // the registry is not properly set up, so use defaults
+            if (!class_exists('PEAR_ChannelFile')) {
+                require_once 'PEAR/ChannelFile.php';
+            }
+
+            $pear_channel = new PEAR_ChannelFile;
+            $pear_channel->setServer('pear.php.net');
+            $pear_channel->setAlias('pear');
+            $pear_channel->setSummary('PHP Extension and Application Repository');
+            $pear_channel->setDefaultPEARProtocols();
+            $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
+            $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
+            $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/');
+            return $pear_channel;
+        }
+
+        if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
+            // the registry is not properly set up, so use defaults
+            if (!class_exists('PEAR_ChannelFile')) {
+                require_once 'PEAR/ChannelFile.php';
+            }
+            $pear_channel = new PEAR_ChannelFile;
+            $pear_channel->setServer('pecl.php.net');
+            $pear_channel->setAlias('pecl');
+            $pear_channel->setSummary('PHP Extension Community Library');
+            $pear_channel->setDefaultPEARProtocols();
+            $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/');
+            $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/');
+            $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
+            return $pear_channel;
+        }
+
+        if ($this->_getChannelFromAlias($channel) == 'doc.php.net') {
+            // the registry is not properly set up, so use defaults
+            if (!class_exists('PEAR_ChannelFile')) {
+                require_once 'PEAR/ChannelFile.php';
+            }
+
+            $doc_channel = new PEAR_ChannelFile;
+            $doc_channel->setServer('doc.php.net');
+            $doc_channel->setAlias('phpdocs');
+            $doc_channel->setSummary('PHP Documentation Team');
+            $doc_channel->setDefaultPEARProtocols();
+            $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/');
+            $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/');
+            $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/');
+            return $doc_channel;
+        }
+
+
+        if ($this->_getChannelFromAlias($channel) == '__uri') {
+            // the registry is not properly set up, so use defaults
+            if (!class_exists('PEAR_ChannelFile')) {
+                require_once 'PEAR/ChannelFile.php';
+            }
+
+            $private = new PEAR_ChannelFile;
+            $private->setName('__uri');
+            $private->setDefaultPEARProtocols();
+            $private->setBaseURL('REST1.0', '****');
+            $private->setSummary('Pseudo-channel for static packages');
+            return $private;
+        }
+
+        return $ch;
+    }
+
+    /**
+     * @param string Package name
+     * @param string Channel name
+     * @return bool
+     */
+    function packageExists($package, $channel = 'pear.php.net')
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_packageExists($package, $channel);
+        $this->_unlock();
+        return $ret;
+    }
+
+    // }}}
+
+    // {{{ channelExists()
+
+    /**
+     * @param string channel name
+     * @param bool if true, then aliases will be ignored
+     * @return bool
+     */
+    function channelExists($channel, $noaliases = false)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_channelExists($channel, $noaliases);
+        $this->_unlock();
+        return $ret;
+    }
+
+    // }}}
+
+    /**
+     * @param string channel name mirror is in
+     * @param string mirror name
+     *
+     * @return bool
+     */
+    function mirrorExists($channel, $mirror)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+
+        $ret = $this->_mirrorExists($channel, $mirror);
+        $this->_unlock();
+        return $ret;
+    }
+
+    // {{{ isAlias()
+
+    /**
+     * Determines whether the parameter is an alias of a channel
+     * @param string
+     * @return bool
+     */
+    function isAlias($alias)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_isChannelAlias($alias);
+        $this->_unlock();
+        return $ret;
+    }
+
+    // }}}
+    // {{{ packageInfo()
+
+    /**
+     * @param string|null
+     * @param string|null
+     * @param string
+     * @return array|null
+     */
+    function packageInfo($package = null, $key = null, $channel = 'pear.php.net')
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_packageInfo($package, $key, $channel);
+        $this->_unlock();
+        return $ret;
+    }
+
+    // }}}
+    // {{{ channelInfo()
+
+    /**
+     * Retrieve a raw array of channel data.
+     *
+     * Do not use this, instead use {@link getChannel()} for normal
+     * operations.  Array structure is undefined in this method
+     * @param string channel name
+     * @param bool whether to strictly retrieve information only on non-aliases
+     * @return array|null|PEAR_Error
+     */
+    function channelInfo($channel = null, $noaliases = false)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_channelInfo($channel, $noaliases);
+        $this->_unlock();
+        return $ret;
+    }
+
+    // }}}
+
+    /**
+     * @param string
+     */
+    function channelName($channel)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_getChannelFromAlias($channel);
+        $this->_unlock();
+        return $ret;
+    }
+
+    /**
+     * @param string
+     */
+    function channelAlias($channel)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_getAlias($channel);
+        $this->_unlock();
+        return $ret;
+    }
+    // {{{ listPackages()
+
+    function listPackages($channel = false)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_listPackages($channel);
+        $this->_unlock();
+        return $ret;
+    }
+
+    // }}}
+    // {{{ listAllPackages()
+
+    function listAllPackages()
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_listAllPackages();
+        $this->_unlock();
+        return $ret;
+    }
+
+    // }}}
+    // {{{ listChannel()
+
+    function listChannels()
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = $this->_listChannels();
+        $this->_unlock();
+        return $ret;
+    }
+
+    // }}}
+    // {{{ addPackage()
+
+    /**
+     * Add an installed package to the registry
+     * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object
+     *               that will be passed to {@link addPackage2()}
+     * @param array package info (parsed by PEAR_Common::infoFrom*() methods)
+     * @return bool success of saving
+     */
+    function addPackage($package, $info)
+    {
+        if (is_object($info)) {
+            return $this->addPackage2($info);
+        }
+        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
+            return $e;
+        }
+        $ret = $this->_addPackage($package, $info);
+        $this->_unlock();
+        if ($ret) {
+            if (!class_exists('PEAR_PackageFile_v1')) {
+                require_once 'PEAR/PackageFile/v1.php';
+            }
+            $pf = new PEAR_PackageFile_v1;
+            $pf->setConfig($this->_config);
+            $pf->fromArray($info);
+            $this->_dependencyDB->uninstallPackage($pf);
+            $this->_dependencyDB->installPackage($pf);
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ addPackage2()
+
+    function addPackage2($info)
+    {
+        if (!is_object($info)) {
+            return $this->addPackage($info['package'], $info);
+        }
+        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
+            return $e;
+        }
+        $ret = $this->_addPackage2($info);
+        $this->_unlock();
+        if ($ret) {
+            $this->_dependencyDB->uninstallPackage($info);
+            $this->_dependencyDB->installPackage($info);
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ updateChannel()
+
+    /**
+     * For future expandibility purposes, separate this
+     * @param PEAR_ChannelFile
+     */
+    function updateChannel($channel, $lastmodified = null)
+    {
+        if ($channel->getName() == '__uri') {
+            return false;
+        }
+        return $this->addChannel($channel, $lastmodified, true);
+    }
+
+    // }}}
+    // {{{ deleteChannel()
+
+    /**
+     * Deletion fails if there are any packages installed from the channel
+     * @param string|PEAR_ChannelFile channel name
+     * @return boolean|PEAR_Error True on deletion, false if it doesn't exist
+     */
+    function deleteChannel($channel)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
+            return $e;
+        }
+
+        $ret = $this->_deleteChannel($channel);
+        $this->_unlock();
+        if ($ret && is_a($this->_config, 'PEAR_Config')) {
+            $this->_config->setChannels($this->listChannels());
+        }
+
+        return $ret;
+    }
+
+    // }}}
+    // {{{ addChannel()
+
+    /**
+     * @param PEAR_ChannelFile Channel object
+     * @param string Last-Modified header from HTTP for caching
+     * @return boolean|PEAR_Error True on creation, false if it already exists
+     */
+    function addChannel($channel, $lastmodified = false, $update = false)
+    {
+        if (!is_a($channel, 'PEAR_ChannelFile') || !$channel->validate()) {
+            return false;
+        }
+
+        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
+            return $e;
+        }
+
+        $ret = $this->_addChannel($channel, $update, $lastmodified);
+        $this->_unlock();
+        if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) {
+            $this->_config->setChannels($this->listChannels());
+        }
+
+        return $ret;
+    }
+
+    // }}}
+    // {{{ deletePackage()
+
+    function deletePackage($package, $channel = 'pear.php.net')
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
+            return $e;
+        }
+
+        $file = $this->_packageFileName($package, $channel);
+        $ret  = file_exists($file) ? @unlink($file) : false;
+        $this->_rebuildFileMap();
+        $this->_unlock();
+        $p = array('channel' => $channel, 'package' => $package);
+        $this->_dependencyDB->uninstallPackage($p);
+        return $ret;
+    }
+
+    // }}}
+    // {{{ updatePackage()
+
+    function updatePackage($package, $info, $merge = true)
+    {
+        if (is_object($info)) {
+            return $this->updatePackage2($info, $merge);
+        }
+        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
+            return $e;
+        }
+        $ret = $this->_updatePackage($package, $info, $merge);
+        $this->_unlock();
+        if ($ret) {
+            if (!class_exists('PEAR_PackageFile_v1')) {
+                require_once 'PEAR/PackageFile/v1.php';
+            }
+            $pf = new PEAR_PackageFile_v1;
+            $pf->setConfig($this->_config);
+            $pf->fromArray($this->packageInfo($package));
+            $this->_dependencyDB->uninstallPackage($pf);
+            $this->_dependencyDB->installPackage($pf);
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ updatePackage2()
+
+    function updatePackage2($info)
+    {
+
+        if (!is_object($info)) {
+            return $this->updatePackage($info['package'], $info, $merge);
+        }
+
+        if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) {
+            return false;
+        }
+
+        if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
+            return $e;
+        }
+
+        $ret = $this->_updatePackage2($info);
+        $this->_unlock();
+        if ($ret) {
+            $this->_dependencyDB->uninstallPackage($info);
+            $this->_dependencyDB->installPackage($info);
+        }
+
+        return $ret;
+    }
+
+    // }}}
+    // {{{ getChannel()
+    /**
+     * @param string channel name
+     * @param bool whether to strictly return raw channels (no aliases)
+     * @return PEAR_ChannelFile|PEAR_Error
+     */
+    function &getChannel($channel, $noaliases = false)
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $ret = &$this->_getChannel($channel, $noaliases);
+        $this->_unlock();
+        if (!$ret) {
+            return PEAR::raiseError('Unknown channel: ' . $channel);
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ getPackage()
+    /**
+     * @param string package name
+     * @param string channel name
+     * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null
+     */
+    function &getPackage($package, $channel = 'pear.php.net')
+    {
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        $pf = &$this->_getPackage($package, $channel);
+        $this->_unlock();
+        return $pf;
+    }
+
+    // }}}
+
+    /**
+     * Get PEAR_PackageFile_v[1/2] objects representing the contents of
+     * a dependency group that are installed.
+     *
+     * This is used at uninstall-time
+     * @param array
+     * @return array|false
+     */
+    function getInstalledGroup($group)
+    {
+        $ret = array();
+        if (isset($group['package'])) {
+            if (!isset($group['package'][0])) {
+                $group['package'] = array($group['package']);
+            }
+            foreach ($group['package'] as $package) {
+                $depchannel = isset($package['channel']) ? $package['channel'] : '__uri';
+                $p = &$this->getPackage($package['name'], $depchannel);
+                if ($p) {
+                    $save = &$p;
+                    $ret[] = &$save;
+                }
+            }
+        }
+        if (isset($group['subpackage'])) {
+            if (!isset($group['subpackage'][0])) {
+                $group['subpackage'] = array($group['subpackage']);
+            }
+            foreach ($group['subpackage'] as $package) {
+                $depchannel = isset($package['channel']) ? $package['channel'] : '__uri';
+                $p = &$this->getPackage($package['name'], $depchannel);
+                if ($p) {
+                    $save = &$p;
+                    $ret[] = &$save;
+                }
+            }
+        }
+        if (!count($ret)) {
+            return false;
+        }
+        return $ret;
+    }
+
+    // {{{ getChannelValidator()
+    /**
+     * @param string channel name
+     * @return PEAR_Validate|false
+     */
+    function &getChannelValidator($channel)
+    {
+        $chan = $this->getChannel($channel);
+        if (PEAR::isError($chan)) {
+            return $chan;
+        }
+        $val = $chan->getValidationObject();
+        return $val;
+    }
+    // }}}
+    // {{{ getChannels()
+    /**
+     * @param string channel name
+     * @return array an array of PEAR_ChannelFile objects representing every installed channel
+     */
+    function &getChannels()
+    {
+        $ret = array();
+        if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+            return $e;
+        }
+        foreach ($this->_listChannels() as $channel) {
+            $e = &$this->_getChannel($channel);
+            if (!$e || PEAR::isError($e)) {
+                continue;
+            }
+            $ret[] = $e;
+        }
+        $this->_unlock();
+        return $ret;
+    }
+
+    // }}}
+    // {{{ checkFileMap()
+
+    /**
+     * Test whether a file or set of files belongs to a package.
+     *
+     * If an array is passed in
+     * @param string|array file path, absolute or relative to the pear
+     *                     install dir
+     * @param string|array name of PEAR package or array('package' => name, 'channel' =>
+     *                     channel) of a package that will be ignored
+     * @param string API version - 1.1 will exclude any files belonging to a package
+     * @param array private recursion variable
+     * @return array|false which package and channel the file belongs to, or an empty
+     *                     string if the file does not belong to an installed package,
+     *                     or belongs to the second parameter's package
+     */
+    function checkFileMap($path, $package = false, $api = '1.0', $attrs = false)
+    {
+        if (is_array($path)) {
+            static $notempty;
+            if (empty($notempty)) {
+                if (!class_exists('PEAR_Installer_Role')) {
+                    require_once 'PEAR/Installer/Role.php';
+                }
+                $notempty = create_function('$a','return !empty($a);');
+            }
+            $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1]))
+                : strtolower($package);
+            $pkgs = array();
+            foreach ($path as $name => $attrs) {
+                if (is_array($attrs)) {
+                    if (isset($attrs['install-as'])) {
+                        $name = $attrs['install-as'];
+                    }
+                    if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) {
+                        // these are not installed
+                        continue;
+                    }
+                    if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) {
+                        $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package;
+                    }
+                    if (isset($attrs['baseinstalldir'])) {
+                        $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name;
+                    }
+                }
+                $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs);
+                if (PEAR::isError($pkgs[$name])) {
+                    return $pkgs[$name];
+                }
+            }
+            return array_filter($pkgs, $notempty);
+        }
+        if (empty($this->filemap_cache)) {
+            if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
+                return $e;
+            }
+            $err = $this->_readFileMap();
+            $this->_unlock();
+            if (PEAR::isError($err)) {
+                return $err;
+            }
+        }
+        if (!$attrs) {
+            $attrs = array('role' => 'php'); // any old call would be for PHP role only
+        }
+        if (isset($this->filemap_cache[$attrs['role']][$path])) {
+            if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) {
+                return false;
+            }
+            return $this->filemap_cache[$attrs['role']][$path];
+        }
+        $l = strlen($this->install_dir);
+        if (substr($path, 0, $l) == $this->install_dir) {
+            $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l));
+        }
+        if (isset($this->filemap_cache[$attrs['role']][$path])) {
+            if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) {
+                return false;
+            }
+            return $this->filemap_cache[$attrs['role']][$path];
+        }
+        return false;
+    }
+
+    // }}}
+    // {{{ flush()
+    /**
+     * Force a reload of the filemap
+     * @since 1.5.0RC3
+     */
+    function flushFileMap()
+    {
+        $this->filemap_cache = null;
+        clearstatcache(); // ensure that the next read gets the full, current filemap
+    }
+
+    // }}}
+    // {{{ apiVersion()
+    /**
+     * Get the expected API version.  Channels API is version 1.1, as it is backwards
+     * compatible with 1.0
+     * @return string
+     */
+    function apiVersion()
+    {
+        return '1.1';
+    }
+    // }}}
+
+
+    /**
+     * Parse a package name, or validate a parsed package name array
+     * @param string|array pass in an array of format
+     *                     array(
+     *                      'package' => 'pname',
+     *                     ['channel' => 'channame',]
+     *                     ['version' => 'version',]
+     *                     ['state' => 'state',]
+     *                     ['group' => 'groupname'])
+     *                     or a string of format
+     *                     [channel://][channame/]pname[-version|-state][/group=groupname]
+     * @return array|PEAR_Error
+     */
+    function parsePackageName($param, $defaultchannel = 'pear.php.net')
+    {
+        $saveparam = $param;
+        if (is_array($param)) {
+            // convert to string for error messages
+            $saveparam = $this->parsedPackageNameToString($param);
+            // process the array
+            if (!isset($param['package'])) {
+                return PEAR::raiseError('parsePackageName(): array $param ' .
+                    'must contain a valid package name in index "param"',
+                    'package', null, null, $param);
+            }
+            if (!isset($param['uri'])) {
+                if (!isset($param['channel'])) {
+                    $param['channel'] = $defaultchannel;
+                }
+            } else {
+                $param['channel'] = '__uri';
+            }
+        } else {
+            $components = @parse_url((string) $param);
+            if (isset($components['scheme'])) {
+                if ($components['scheme'] == 'http') {
+                    // uri package
+                    $param = array('uri' => $param, 'channel' => '__uri');
+                } elseif($components['scheme'] != 'channel') {
+                    return PEAR::raiseError('parsePackageName(): only channel:// uris may ' .
+                        'be downloaded, not "' . $param . '"', 'invalid', null, null, $param);
+                }
+            }
+            if (!isset($components['path'])) {
+                return PEAR::raiseError('parsePackageName(): array $param ' .
+                    'must contain a valid package name in "' . $param . '"',
+                    'package', null, null, $param);
+            }
+            if (isset($components['host'])) {
+                // remove the leading "/"
+                $components['path'] = substr($components['path'], 1);
+            }
+            if (!isset($components['scheme'])) {
+                if (strpos($components['path'], '/') !== false) {
+                    if ($components['path']{0} == '/') {
+                        return PEAR::raiseError('parsePackageName(): this is not ' .
+                            'a package name, it begins with "/" in "' . $param . '"',
+                            'invalid', null, null, $param);
+                    }
+                    $parts = explode('/', $components['path']);
+                    $components['host'] = array_shift($parts);
+                    if (count($parts) > 1) {
+                        $components['path'] = array_pop($parts);
+                        $components['host'] .= '/' . implode('/', $parts);
+                    } else {
+                        $components['path'] = implode('/', $parts);
+                    }
+                } else {
+                    $components['host'] = $defaultchannel;
+                }
+            } else {
+                if (strpos($components['path'], '/')) {
+                    $parts = explode('/', $components['path']);
+                    $components['path'] = array_pop($parts);
+                    $components['host'] .= '/' . implode('/', $parts);
+                }
+            }
+
+            if (is_array($param)) {
+                $param['package'] = $components['path'];
+            } else {
+                $param = array(
+                    'package' => $components['path']
+                    );
+                if (isset($components['host'])) {
+                    $param['channel'] = $components['host'];
+                }
+            }
+            if (isset($components['fragment'])) {
+                $param['group'] = $components['fragment'];
+            }
+            if (isset($components['user'])) {
+                $param['user'] = $components['user'];
+            }
+            if (isset($components['pass'])) {
+                $param['pass'] = $components['pass'];
+            }
+            if (isset($components['query'])) {
+                parse_str($components['query'], $param['opts']);
+            }
+            // check for extension
+            $pathinfo = pathinfo($param['package']);
+            if (isset($pathinfo['extension']) &&
+                  in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) {
+                $param['extension'] = $pathinfo['extension'];
+                $param['package'] = substr($pathinfo['basename'], 0,
+                    strlen($pathinfo['basename']) - 4);
+            }
+            // check for version
+            if (strpos($param['package'], '-')) {
+                $test = explode('-', $param['package']);
+                if (count($test) != 2) {
+                    return PEAR::raiseError('parsePackageName(): only one version/state ' .
+                        'delimiter "-" is allowed in "' . $saveparam . '"',
+                        'version', null, null, $param);
+                }
+                list($param['package'], $param['version']) = $test;
+            }
+        }
+        // validation
+        $info = $this->channelExists($param['channel']);
+        if (PEAR::isError($info)) {
+            return $info;
+        }
+        if (!$info) {
+            return PEAR::raiseError('unknown channel "' . $param['channel'] .
+                '" in "' . $saveparam . '"', 'channel', null, null, $param);
+        }
+        $chan = $this->getChannel($param['channel']);
+        if (PEAR::isError($chan)) {
+            return $chan;
+        }
+        if (!$chan) {
+            return PEAR::raiseError("Exception: corrupt registry, could not " .
+                "retrieve channel " . $param['channel'] . " information",
+                'registry', null, null, $param);
+        }
+        $param['channel'] = $chan->getName();
+        $validate = $chan->getValidationObject();
+        $vpackage = $chan->getValidationPackage();
+        // validate package name
+        if (!$validate->validPackageName($param['package'], $vpackage['_content'])) {
+            return PEAR::raiseError('parsePackageName(): invalid package name "' .
+                $param['package'] . '" in "' . $saveparam . '"',
+                'package', null, null, $param);
+        }
+        if (isset($param['group'])) {
+            if (!PEAR_Validate::validGroupName($param['group'])) {
+                return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] .
+                    '" is not a valid group name in "' . $saveparam . '"', 'group', null, null,
+                    $param);
+            }
+        }
+        if (isset($param['state'])) {
+            if (!in_array(strtolower($param['state']), $validate->getValidStates())) {
+                return PEAR::raiseError('parsePackageName(): state "' . $param['state']
+                    . '" is not a valid state in "' . $saveparam . '"',
+                    'state', null, null, $param);
+            }
+        }
+        if (isset($param['version'])) {
+            if (isset($param['state'])) {
+                return PEAR::raiseError('parsePackageName(): cannot contain both ' .
+                    'a version and a stability (state) in "' . $saveparam . '"',
+                    'version/state', null, null, $param);
+            }
+            // check whether version is actually a state
+            if (in_array(strtolower($param['version']), $validate->getValidStates())) {
+                $param['state'] = strtolower($param['version']);
+                unset($param['version']);
+            } else {
+                if (!$validate->validVersion($param['version'])) {
+                    return PEAR::raiseError('parsePackageName(): "' . $param['version'] .
+                        '" is neither a valid version nor a valid state in "' .
+                        $saveparam . '"', 'version/state', null, null, $param);
+                }
+            }
+        }
+        return $param;
+    }
+
+    /**
+     * @param array
+     * @return string
+     */
+    function parsedPackageNameToString($parsed, $brief = false)
+    {
+        if (is_string($parsed)) {
+            return $parsed;
+        }
+        if (is_object($parsed)) {
+            $p = $parsed;
+            $parsed = array(
+                'package' => $p->getPackage(),
+                'channel' => $p->getChannel(),
+                'version' => $p->getVersion(),
+            );
+        }
+        if (isset($parsed['uri'])) {
+            return $parsed['uri'];
+        }
+        if ($brief) {
+            if ($channel = $this->channelAlias($parsed['channel'])) {
+                return $channel . '/' . $parsed['package'];
+            }
+        }
+        $upass = '';
+        if (isset($parsed['user'])) {
+            $upass = $parsed['user'];
+            if (isset($parsed['pass'])) {
+                $upass .= ':' . $parsed['pass'];
+            }
+            $upass = "$upass@";
+        }
+        $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package'];
+        if (isset($parsed['version']) || isset($parsed['state'])) {
+            $ver = isset($parsed['version']) ? $parsed['version'] : '';
+            $ver .= isset($parsed['state']) ? $parsed['state'] : '';
+            $ret .= '-' . $ver;
+        }
+        if (isset($parsed['extension'])) {
+            $ret .= '.' . $parsed['extension'];
+        }
+        if (isset($parsed['opts'])) {
+            $ret .= '?';
+            foreach ($parsed['opts'] as $name => $value) {
+                $parsed['opts'][$name] = "$name=$value";
+            }
+            $ret .= implode('&', $parsed['opts']);
+        }
+        if (isset($parsed['group'])) {
+            $ret .= '#' . $parsed['group'];
+        }
+        return $ret;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/RunTest.php b/lib/php/PEAR/RunTest.php
new file mode 100644
index 00000000..9d338e85
--- /dev/null
+++ b/lib/php/PEAR/RunTest.php
@@ -0,0 +1,951 @@
+<?php
+/**
+ * PEAR_RunTest
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: RunTest.php 287447 2009-08-18 11:46:19Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.3.3
+ */
+
+/**
+ * for error handling
+ */
+require_once 'PEAR.php';
+require_once 'PEAR/Config.php';
+
+define('DETAILED', 1);
+putenv("PHP_PEAR_RUNTESTS=1");
+
+/**
+ * Simplified version of PHP's test suite
+ *
+ * Try it with:
+ *
+ * $ php -r 'include "../PEAR/RunTest.php"; $t=new PEAR_RunTest; $o=$t->run("./pear_system.phpt");print_r($o);'
+ *
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.3.3
+ */
+class PEAR_RunTest
+{
+    var $_headers = array();
+    var $_logger;
+    var $_options;
+    var $_php;
+    var $tests_count;
+    var $xdebug_loaded;
+    /**
+     * Saved value of php executable, used to reset $_php when we
+     * have a test that uses cgi
+     *
+     * @var unknown_type
+     */
+    var $_savephp;
+    var $ini_overwrites = array(
+        'output_handler=',
+        'open_basedir=',
+        'safe_mode=0',
+        'disable_functions=',
+        'output_buffering=Off',
+        'display_errors=1',
+        'log_errors=0',
+        'html_errors=0',
+        'track_errors=1',
+        'report_memleaks=0',
+        'report_zend_debug=0',
+        'docref_root=',
+        'docref_ext=.html',
+        'error_prepend_string=',
+        'error_append_string=',
+        'auto_prepend_file=',
+        'auto_append_file=',
+        'magic_quotes_runtime=0',
+        'xdebug.default_enable=0',
+        'allow_url_fopen=1',
+    );
+
+    /**
+     * An object that supports the PEAR_Common->log() signature, or null
+     * @param PEAR_Common|null
+     */
+    function PEAR_RunTest($logger = null, $options = array())
+    {
+        if (!defined('E_DEPRECATED')) {
+            define('E_DEPRECATED', 0);
+        }
+        if (!defined('E_STRICT')) {
+            define('E_STRICT', 0);
+        }
+        $this->ini_overwrites[] = 'error_reporting=' . (E_ALL & ~(E_DEPRECATED | E_STRICT));
+        if (is_null($logger)) {
+            require_once 'PEAR/Common.php';
+            $logger = new PEAR_Common;
+        }
+        $this->_logger  = $logger;
+        $this->_options = $options;
+
+        $conf = &PEAR_Config::singleton();
+        $this->_php = $conf->get('php_bin');
+    }
+
+    /**
+     * Taken from php-src/run-tests.php
+     *
+     * @param string $commandline command name
+     * @param array $env
+     * @param string $stdin standard input to pass to the command
+     * @return unknown
+     */
+    function system_with_timeout($commandline, $env = null, $stdin = null)
+    {
+        $data = '';
+        if (version_compare(phpversion(), '5.0.0', '<')) {
+            $proc = proc_open($commandline, array(
+                0 => array('pipe', 'r'),
+                1 => array('pipe', 'w'),
+                2 => array('pipe', 'w')
+                ), $pipes);
+        } else {
+            $proc = proc_open($commandline, array(
+                0 => array('pipe', 'r'),
+                1 => array('pipe', 'w'),
+                2 => array('pipe', 'w')
+                ), $pipes, null, $env, array('suppress_errors' => true));
+        }
+
+        if (!$proc) {
+            return false;
+        }
+
+        if (is_string($stdin)) {
+            fwrite($pipes[0], $stdin);
+        }
+        fclose($pipes[0]);
+
+        while (true) {
+            /* hide errors from interrupted syscalls */
+            $r = $pipes;
+            $e = $w = null;
+            $n = @stream_select($r, $w, $e, 60);
+
+            if ($n === 0) {
+                /* timed out */
+                $data .= "\n ** ERROR: process timed out **\n";
+                proc_terminate($proc);
+                return array(1234567890, $data);
+            } else if ($n > 0) {
+                $line = fread($pipes[1], 8192);
+                if (strlen($line) == 0) {
+                    /* EOF */
+                    break;
+                }
+                $data .= $line;
+            }
+        }
+        if (function_exists('proc_get_status')) {
+            $stat = proc_get_status($proc);
+            if ($stat['signaled']) {
+                $data .= "\nTermsig=".$stat['stopsig'];
+            }
+        }
+        $code = proc_close($proc);
+        if (function_exists('proc_get_status')) {
+            $code = $stat['exitcode'];
+        }
+        return array($code, $data);
+    }
+
+    /**
+     * Turns a PHP INI string into an array
+     *
+     * Turns -d "include_path=/foo/bar" into this:
+     * array(
+     *   'include_path' => array(
+     *          'operator' => '-d',
+     *          'value'    => '/foo/bar',
+     *   )
+     * )
+     * Works both with quotes and without
+     *
+     * @param string an PHP INI string, -d "include_path=/foo/bar"
+     * @return array
+     */
+    function iniString2array($ini_string)
+    {
+        if (!$ini_string) {
+            return array();
+        }
+        $split = preg_split('/[\s]|=/', $ini_string, -1, PREG_SPLIT_NO_EMPTY);
+        $key   = $split[1][0] == '"'                     ? substr($split[1], 1)     : $split[1];
+        $value = $split[2][strlen($split[2]) - 1] == '"' ? substr($split[2], 0, -1) : $split[2];
+        // FIXME review if this is really the struct to go with
+        $array = array($key => array('operator' => $split[0], 'value' => $value));
+        return $array;
+    }
+
+    function settings2array($settings, $ini_settings)
+    {
+        foreach ($settings as $setting) {
+            if (strpos($setting, '=') !== false) {
+                $setting = explode('=', $setting, 2);
+                $name  = trim(strtolower($setting[0]));
+                $value = trim($setting[1]);
+                $ini_settings[$name] = $value;
+            }
+        }
+        return $ini_settings;
+    }
+
+    function settings2params($ini_settings)
+    {
+        $settings = '';
+        foreach ($ini_settings as $name => $value) {
+            if (is_array($value)) {
+                $operator = $value['operator'];
+                $value    = $value['value'];
+            } else {
+                $operator = '-d';
+            }
+            $value = addslashes($value);
+            $settings .= " $operator \"$name=$value\"";
+        }
+        return $settings;
+    }
+
+    function _preparePhpBin($php, $file, $ini_settings)
+    {
+        $file = escapeshellarg($file);
+        // This was fixed in php 5.3 and is not needed after that
+        if (OS_WINDOWS && version_compare(PHP_VERSION, '5.3', '<')) {
+            $cmd = '"'.escapeshellarg($php).' '.$ini_settings.' -f ' . $file .'"';
+        } else {
+            $cmd = $php . $ini_settings . ' -f ' . $file;
+        }
+
+        return $cmd;
+    }
+
+    function runPHPUnit($file, $ini_settings = '')
+    {
+        if (!file_exists($file) && file_exists(getcwd() . DIRECTORY_SEPARATOR . $file)) {
+            $file = realpath(getcwd() . DIRECTORY_SEPARATOR . $file);
+        } elseif (file_exists($file)) {
+            $file = realpath($file);
+        }
+
+        $cmd = $this->_preparePhpBin($this->_php, $file, $ini_settings);
+        if (isset($this->_logger)) {
+            $this->_logger->log(2, 'Running command "' . $cmd . '"');
+        }
+
+        $savedir = getcwd(); // in case the test moves us around
+        chdir(dirname($file));
+        echo `$cmd`;
+        chdir($savedir);
+        return 'PASSED'; // we have no way of knowing this information so assume passing
+    }
+
+    /**
+     * Runs an individual test case.
+     *
+     * @param string       The filename of the test
+     * @param array|string INI settings to be applied to the test run
+     * @param integer      Number what the current running test is of the
+     *                     whole test suite being runned.
+     *
+     * @return string|object Returns PASSED, WARNED, FAILED depending on how the
+     *                       test came out.
+     *                       PEAR Error when the tester it self fails
+     */
+    function run($file, $ini_settings = array(), $test_number = 1)
+    {
+        if (isset($this->_savephp)) {
+            $this->_php = $this->_savephp;
+            unset($this->_savephp);
+        }
+        if (empty($this->_options['cgi'])) {
+            // try to see if php-cgi is in the path
+            $res = $this->system_with_timeout('php-cgi -v');
+            if (false !== $res && !(is_array($res) && $res === array(127, ''))) {
+                $this->_options['cgi'] = 'php-cgi';
+            }
+        }
+        if (1 < $len = strlen($this->tests_count)) {
+            $test_number = str_pad($test_number, $len, ' ', STR_PAD_LEFT);
+            $test_nr = "[$test_number/$this->tests_count] ";
+        } else {
+            $test_nr = '';
+        }
+
+        $file = realpath($file);
+        $section_text = $this->_readFile($file);
+        if (PEAR::isError($section_text)) {
+            return $section_text;
+        }
+
+        if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) {
+            return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file");
+        }
+
+        $cwd = getcwd();
+
+        $pass_options = '';
+        if (!empty($this->_options['ini'])) {
+            $pass_options = $this->_options['ini'];
+        }
+
+        if (is_string($ini_settings)) {
+            $ini_settings = $this->iniString2array($ini_settings);
+        }
+
+        $ini_settings = $this->settings2array($this->ini_overwrites, $ini_settings);
+        if ($section_text['INI']) {
+            if (strpos($section_text['INI'], '{PWD}') !== false) {
+                $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']);
+            }
+            $ini = preg_split( "/[\n\r]+/", $section_text['INI']);
+            $ini_settings = $this->settings2array($ini, $ini_settings);
+        }
+        $ini_settings = $this->settings2params($ini_settings);
+        $shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file);
+
+        $tested = trim($section_text['TEST']);
+        $tested.= !isset($this->_options['simple']) ? "[$shortname]" : ' ';
+
+        if (!empty($section_text['POST']) || !empty($section_text['POST_RAW']) ||
+              !empty($section_text['UPLOAD']) || !empty($section_text['GET']) ||
+              !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) {
+            if (empty($this->_options['cgi'])) {
+                if (!isset($this->_options['quiet'])) {
+                    $this->_logger->log(0, "SKIP $test_nr$tested (reason: --cgi option needed for this test, type 'pear help run-tests')");
+                }
+                if (isset($this->_options['tapoutput'])) {
+                    return array('ok', ' # skip --cgi option needed for this test, "pear help run-tests" for info');
+                }
+                return 'SKIPPED';
+            }
+            $this->_savephp = $this->_php;
+            $this->_php = $this->_options['cgi'];
+        }
+
+        $temp_dir = realpath(dirname($file));
+        $main_file_name = basename($file, 'phpt');
+        $diff_filename     = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff';
+        $log_filename      = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log';
+        $exp_filename      = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp';
+        $output_filename   = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out';
+        $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem';
+        $temp_file         = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php';
+        $temp_skipif       = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
+        $temp_clean        = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
+        $tmp_post          = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.');
+
+        // unlink old test results
+        $this->_cleanupOldFiles($file);
+
+        // Check if test should be skipped.
+        $res  = $this->_runSkipIf($section_text, $temp_skipif, $tested, $ini_settings);
+        if (count($res) != 2) {
+            return $res;
+        }
+        $info = $res['info'];
+        $warn = $res['warn'];
+
+        // We've satisfied the preconditions - run the test!
+        if (isset($this->_options['coverage']) && $this->xdebug_loaded) {
+            $xdebug_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'xdebug';
+            $text = '<?php';
+            $text .= "\n" . 'function coverage_shutdown() {' .
+                     "\n" . '    $xdebug = var_export(xdebug_get_code_coverage(), true);';
+            if (!function_exists('file_put_contents')) {
+                $text .= "\n" . '    $fh = fopen(\'' . $xdebug_file . '\', "wb");' .
+                        "\n" . '    if ($fh !== false) {' .
+                        "\n" . '        fwrite($fh, $xdebug);' .
+                        "\n" . '        fclose($fh);' .
+                        "\n" . '    }';
+            } else {
+                $text .= "\n" . '    file_put_contents(\'' . $xdebug_file . '\', $xdebug);';
+            }
+
+            $text .= "\n" . 'xdebug_stop_code_coverage();' .
+                "\n" . '} // end coverage_shutdown()' .
+                "\n" . 'register_shutdown_function("coverage_shutdown");';
+            $text .= "\n" . 'xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);' . "\n?>";
+
+            $len_f = 5;
+            if (substr($section_text['FILE'], 0, 5) != '<?php'
+                && substr($section_text['FILE'], 0, 2) == '<?') {
+                $len_f = 2;
+            }
+            $text .= $section_text['FILE'];
+
+            $this->save_text($temp_file, $text);
+        } else {
+            $this->save_text($temp_file, $section_text['FILE']);
+        }
+
+        $args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : '';
+        $cmd = $this->_preparePhpBin($this->_php, $temp_file, $ini_settings);
+        $cmd.= "$args 2>&1";
+        if (isset($this->_logger)) {
+            $this->_logger->log(2, 'Running command "' . $cmd . '"');
+        }
+
+        // Reset environment from any previous test.
+        $env = $this->_resetEnv($section_text, $temp_file);
+
+        $section_text = $this->_processUpload($section_text, $file);
+        if (PEAR::isError($section_text)) {
+            return $section_text;
+        }
+
+        if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) {
+            $post = trim($section_text['POST_RAW']);
+            $raw_lines = explode("\n", $post);
+
+            $request = '';
+            $started = false;
+            foreach ($raw_lines as $i => $line) {
+                if (empty($env['CONTENT_TYPE']) &&
+                    preg_match('/^Content-Type:(.*)/i', $line, $res)) {
+                    $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
+                    continue;
+                }
+                if ($started) {
+                    $request .= "\n";
+                }
+                $started = true;
+                $request .= $line;
+            }
+
+            $env['CONTENT_LENGTH'] = strlen($request);
+            $env['REQUEST_METHOD'] = 'POST';
+
+            $this->save_text($tmp_post, $request);
+            $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post";
+        } elseif (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
+            $post = trim($section_text['POST']);
+            $this->save_text($tmp_post, $post);
+            $content_length = strlen($post);
+
+            $env['REQUEST_METHOD'] = 'POST';
+            $env['CONTENT_TYPE']   = 'application/x-www-form-urlencoded';
+            $env['CONTENT_LENGTH'] = $content_length;
+
+            $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post";
+        } else {
+            $env['REQUEST_METHOD'] = 'GET';
+            $env['CONTENT_TYPE']   = '';
+            $env['CONTENT_LENGTH'] = '';
+        }
+
+        if (OS_WINDOWS && isset($section_text['RETURNS'])) {
+            ob_start();
+            system($cmd, $return_value);
+            $out = ob_get_contents();
+            ob_end_clean();
+            $section_text['RETURNS'] = (int) trim($section_text['RETURNS']);
+            $returnfail = ($return_value != $section_text['RETURNS']);
+        } else {
+            $returnfail = false;
+            $stdin = isset($section_text['STDIN']) ? $section_text['STDIN'] : null;
+            $out = $this->system_with_timeout($cmd, $env, $stdin);
+            $return_value = $out[0];
+            $out = $out[1];
+        }
+
+        $output = preg_replace('/\r\n/', "\n", trim($out));
+
+        if (isset($tmp_post) && realpath($tmp_post) && file_exists($tmp_post)) {
+            @unlink(realpath($tmp_post));
+        }
+        chdir($cwd); // in case the test moves us around
+
+        $this->_testCleanup($section_text, $temp_clean);
+
+        /* when using CGI, strip the headers from the output */
+        $output = $this->_stripHeadersCGI($output);
+
+        if (isset($section_text['EXPECTHEADERS'])) {
+            $testheaders = $this->_processHeaders($section_text['EXPECTHEADERS']);
+            $missing = array_diff_assoc($testheaders, $this->_headers);
+            $changed = '';
+            foreach ($missing as $header => $value) {
+                if (isset($this->_headers[$header])) {
+                    $changed .= "-$header: $value\n+$header: ";
+                    $changed .= $this->_headers[$header];
+                } else {
+                    $changed .= "-$header: $value\n";
+                }
+            }
+            if ($missing) {
+                // tack on failed headers to output:
+                $output .= "\n====EXPECTHEADERS FAILURE====:\n$changed";
+            }
+        }
+        // Does the output match what is expected?
+        do {
+            if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
+                if (isset($section_text['EXPECTF'])) {
+                    $wanted = trim($section_text['EXPECTF']);
+                } else {
+                    $wanted = trim($section_text['EXPECTREGEX']);
+                }
+                $wanted_re = preg_replace('/\r\n/', "\n", $wanted);
+                if (isset($section_text['EXPECTF'])) {
+                    $wanted_re = preg_quote($wanted_re, '/');
+                    // Stick to basics
+                    $wanted_re = str_replace("%s", ".+?", $wanted_re); //not greedy
+                    $wanted_re = str_replace("%i", "[+\-]?[0-9]+", $wanted_re);
+                    $wanted_re = str_replace("%d", "[0-9]+", $wanted_re);
+                    $wanted_re = str_replace("%x", "[0-9a-fA-F]+", $wanted_re);
+                    $wanted_re = str_replace("%f", "[+\-]?\.?[0-9]+\.?[0-9]*(E-?[0-9]+)?", $wanted_re);
+                    $wanted_re = str_replace("%c", ".", $wanted_re);
+                    // %f allows two points "-.0.0" but that is the best *simple* expression
+                }
+
+    /* DEBUG YOUR REGEX HERE
+            var_dump($wanted_re);
+            print(str_repeat('=', 80) . "\n");
+            var_dump($output);
+    */
+                if (!$returnfail && preg_match("/^$wanted_re\$/s", $output)) {
+                    if (file_exists($temp_file)) {
+                        unlink($temp_file);
+                    }
+                    if (array_key_exists('FAIL', $section_text)) {
+                        break;
+                    }
+                    if (!isset($this->_options['quiet'])) {
+                        $this->_logger->log(0, "PASS $test_nr$tested$info");
+                    }
+                    if (isset($this->_options['tapoutput'])) {
+                        return array('ok', ' - ' . $tested);
+                    }
+                    return 'PASSED';
+                }
+            } else {
+                if (isset($section_text['EXPECTFILE'])) {
+                    $f = $temp_dir . '/' . trim($section_text['EXPECTFILE']);
+                    if (!($fp = @fopen($f, 'rb'))) {
+                        return PEAR::raiseError('--EXPECTFILE-- section file ' .
+                            $f . ' not found');
+                    }
+                    fclose($fp);
+                    $section_text['EXPECT'] = file_get_contents($f);
+                }
+
+                if (isset($section_text['EXPECT'])) {
+                    $wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT']));
+                } else {
+                    $wanted = '';
+                }
+
+                // compare and leave on success
+                if (!$returnfail && 0 == strcmp($output, $wanted)) {
+                    if (file_exists($temp_file)) {
+                        unlink($temp_file);
+                    }
+                    if (array_key_exists('FAIL', $section_text)) {
+                        break;
+                    }
+                    if (!isset($this->_options['quiet'])) {
+                        $this->_logger->log(0, "PASS $test_nr$tested$info");
+                    }
+                    if (isset($this->_options['tapoutput'])) {
+                        return array('ok', ' - ' . $tested);
+                    }
+                    return 'PASSED';
+                }
+            }
+        } while (false);
+
+        if (array_key_exists('FAIL', $section_text)) {
+            // we expect a particular failure
+            // this is only used for testing PEAR_RunTest
+            $expectf  = isset($section_text['EXPECTF']) ? $wanted_re : null;
+            $faildiff = $this->generate_diff($wanted, $output, null, $expectf);
+            $faildiff = preg_replace('/\r/', '', $faildiff);
+            $wanted   = preg_replace('/\r/', '', trim($section_text['FAIL']));
+            if ($faildiff == $wanted) {
+                if (!isset($this->_options['quiet'])) {
+                    $this->_logger->log(0, "PASS $test_nr$tested$info");
+                }
+                if (isset($this->_options['tapoutput'])) {
+                    return array('ok', ' - ' . $tested);
+                }
+                return 'PASSED';
+            }
+            unset($section_text['EXPECTF']);
+            $output = $faildiff;
+            if (isset($section_text['RETURNS'])) {
+                return PEAR::raiseError('Cannot have both RETURNS and FAIL in the same test: ' .
+                    $file);
+            }
+        }
+
+        // Test failed so we need to report details.
+        $txt = $warn ? 'WARN ' : 'FAIL ';
+        $this->_logger->log(0, $txt . $test_nr . $tested . $info);
+
+        // write .exp
+        $res = $this->_writeLog($exp_filename, $wanted);
+        if (PEAR::isError($res)) {
+            return $res;
+        }
+
+        // write .out
+        $res = $this->_writeLog($output_filename, $output);
+        if (PEAR::isError($res)) {
+            return $res;
+        }
+
+        // write .diff
+        $returns = isset($section_text['RETURNS']) ?
+                        array(trim($section_text['RETURNS']), $return_value) : null;
+        $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null;
+        $data = $this->generate_diff($wanted, $output, $returns, $expectf);
+        $res  = $this->_writeLog($diff_filename, $data);
+        if (PEAR::isError($res)) {
+            return $res;
+        }
+
+        // write .log
+        $data = "
+---- EXPECTED OUTPUT
+$wanted
+---- ACTUAL OUTPUT
+$output
+---- FAILED
+";
+
+        if ($returnfail) {
+            $data .= "
+---- EXPECTED RETURN
+$section_text[RETURNS]
+---- ACTUAL RETURN
+$return_value
+";
+        }
+
+        $res = $this->_writeLog($log_filename, $data);
+        if (PEAR::isError($res)) {
+            return $res;
+        }
+
+        if (isset($this->_options['tapoutput'])) {
+            $wanted = explode("\n", $wanted);
+            $wanted = "# Expected output:\n#\n#" . implode("\n#", $wanted);
+            $output = explode("\n", $output);
+            $output = "#\n#\n# Actual output:\n#\n#" . implode("\n#", $output);
+            return array($wanted . $output . 'not ok', ' - ' . $tested);
+        }
+        return $warn ? 'WARNED' : 'FAILED';
+    }
+
+    function generate_diff($wanted, $output, $rvalue, $wanted_re)
+    {
+        $w  = explode("\n", $wanted);
+        $o  = explode("\n", $output);
+        $wr = explode("\n", $wanted_re);
+        $w1 = array_diff_assoc($w, $o);
+        $o1 = array_diff_assoc($o, $w);
+        $o2 = $w2 = array();
+        foreach ($w1 as $idx => $val) {
+            if (!$wanted_re || !isset($wr[$idx]) || !isset($o1[$idx]) ||
+                  !preg_match('/^' . $wr[$idx] . '\\z/', $o1[$idx])) {
+                $w2[sprintf("%03d<", $idx)] = sprintf("%03d- ", $idx + 1) . $val;
+            }
+        }
+        foreach ($o1 as $idx => $val) {
+            if (!$wanted_re || !isset($wr[$idx]) ||
+                  !preg_match('/^' . $wr[$idx] . '\\z/', $val)) {
+                $o2[sprintf("%03d>", $idx)] = sprintf("%03d+ ", $idx + 1) . $val;
+            }
+        }
+        $diff = array_merge($w2, $o2);
+        ksort($diff);
+        $extra = $rvalue ? "##EXPECTED: $rvalue[0]\r\n##RETURNED: $rvalue[1]" : '';
+        return implode("\r\n", $diff) . $extra;
+    }
+
+    //  Write the given text to a temporary file, and return the filename.
+    function save_text($filename, $text)
+    {
+        if (!$fp = fopen($filename, 'w')) {
+            return PEAR::raiseError("Cannot open file '" . $filename . "' (save_text)");
+        }
+        fwrite($fp, $text);
+        fclose($fp);
+    if (1 < DETAILED) echo "
+FILE $filename {{{
+$text
+}}}
+";
+    }
+
+    function _cleanupOldFiles($file)
+    {
+        $temp_dir = realpath(dirname($file));
+        $mainFileName = basename($file, 'phpt');
+        $diff_filename     = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'diff';
+        $log_filename      = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'log';
+        $exp_filename      = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'exp';
+        $output_filename   = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'out';
+        $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'mem';
+        $temp_file         = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'php';
+        $temp_skipif       = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'skip.php';
+        $temp_clean        = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'clean.php';
+        $tmp_post          = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.');
+
+        // unlink old test results
+        @unlink($diff_filename);
+        @unlink($log_filename);
+        @unlink($exp_filename);
+        @unlink($output_filename);
+        @unlink($memcheck_filename);
+        @unlink($temp_file);
+        @unlink($temp_skipif);
+        @unlink($tmp_post);
+        @unlink($temp_clean);
+    }
+
+    function _runSkipIf($section_text, $temp_skipif, $tested, $ini_settings)
+    {
+        $info = '';
+        $warn = false;
+        if (array_key_exists('SKIPIF', $section_text) && trim($section_text['SKIPIF'])) {
+            $this->save_text($temp_skipif, $section_text['SKIPIF']);
+            $output = $this->system_with_timeout("$this->_php$ini_settings -f \"$temp_skipif\"");
+            $output = $output[1];
+            $loutput = ltrim($output);
+            unlink($temp_skipif);
+            if (!strncasecmp('skip', $loutput, 4)) {
+                $skipreason = "SKIP $tested";
+                if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) {
+                    $skipreason .= '(reason: ' . $m[1] . ')';
+                }
+                if (!isset($this->_options['quiet'])) {
+                    $this->_logger->log(0, $skipreason);
+                }
+                if (isset($this->_options['tapoutput'])) {
+                    return array('ok', ' # skip ' . $reason);
+                }
+                return 'SKIPPED';
+            }
+
+            if (!strncasecmp('info', $loutput, 4)
+                && preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) {
+                $info = " (info: $m[1])";
+            }
+
+            if (!strncasecmp('warn', $loutput, 4)
+                && preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) {
+                $warn = true; /* only if there is a reason */
+                $info = " (warn: $m[1])";
+            }
+        }
+
+        return array('warn' => $warn, 'info' => $info);
+    }
+
+    function _stripHeadersCGI($output)
+    {
+        $this->headers = array();
+        if (!empty($this->_options['cgi']) &&
+              $this->_php == $this->_options['cgi'] &&
+              preg_match("/^(.*?)(?:\n\n(.*)|\\z)/s", $output, $match)) {
+            $output = isset($match[2]) ? trim($match[2]) : '';
+            $this->_headers = $this->_processHeaders($match[1]);
+        }
+
+        return $output;
+    }
+
+    /**
+     * Return an array that can be used with array_diff() to compare headers
+     *
+     * @param string $text
+     */
+    function _processHeaders($text)
+    {
+        $headers = array();
+        $rh = preg_split("/[\n\r]+/", $text);
+        foreach ($rh as $line) {
+            if (strpos($line, ':')!== false) {
+                $line = explode(':', $line, 2);
+                $headers[trim($line[0])] = trim($line[1]);
+            }
+        }
+        return $headers;
+    }
+
+    function _readFile($file)
+    {
+        // Load the sections of the test file.
+        $section_text = array(
+            'TEST'   => '(unnamed test)',
+            'SKIPIF' => '',
+            'GET'    => '',
+            'COOKIE' => '',
+            'POST'   => '',
+            'ARGS'   => '',
+            'INI'    => '',
+            'CLEAN'  => '',
+        );
+
+        if (!is_file($file) || !$fp = fopen($file, "r")) {
+            return PEAR::raiseError("Cannot open test file: $file");
+        }
+
+        $section = '';
+        while (!feof($fp)) {
+            $line = fgets($fp);
+
+            // Match the beginning of a section.
+            if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
+                $section = $r[1];
+                $section_text[$section] = '';
+                continue;
+            } elseif (empty($section)) {
+                fclose($fp);
+                return PEAR::raiseError("Invalid sections formats in test file: $file");
+            }
+
+            // Add to the section text.
+            $section_text[$section] .= $line;
+        }
+        fclose($fp);
+
+        return $section_text;
+    }
+
+    function _writeLog($logname, $data)
+    {
+        if (!$log = fopen($logname, 'w')) {
+            return PEAR::raiseError("Cannot create test log - $logname");
+        }
+        fwrite($log, $data);
+        fclose($log);
+    }
+
+    function _resetEnv($section_text, $temp_file)
+    {
+        $env = $_ENV;
+        $env['REDIRECT_STATUS'] = '';
+        $env['QUERY_STRING']    = '';
+        $env['PATH_TRANSLATED'] = '';
+        $env['SCRIPT_FILENAME'] = '';
+        $env['REQUEST_METHOD']  = '';
+        $env['CONTENT_TYPE']    = '';
+        $env['CONTENT_LENGTH']  = '';
+        if (!empty($section_text['ENV'])) {
+            if (strpos($section_text['ENV'], '{PWD}') !== false) {
+                $section_text['ENV'] = str_replace('{PWD}', dirname($temp_file), $section_text['ENV']);
+            }
+            foreach (explode("\n", trim($section_text['ENV'])) as $e) {
+                $e = explode('=', trim($e), 2);
+                if (!empty($e[0]) && isset($e[1])) {
+                    $env[$e[0]] = $e[1];
+                }
+            }
+        }
+        if (array_key_exists('GET', $section_text)) {
+            $env['QUERY_STRING'] = trim($section_text['GET']);
+        } else {
+            $env['QUERY_STRING'] = '';
+        }
+        if (array_key_exists('COOKIE', $section_text)) {
+            $env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
+        } else {
+            $env['HTTP_COOKIE'] = '';
+        }
+        $env['REDIRECT_STATUS'] = '1';
+        $env['PATH_TRANSLATED'] = $temp_file;
+        $env['SCRIPT_FILENAME'] = $temp_file;
+
+        return $env;
+    }
+
+    function _processUpload($section_text, $file)
+    {
+        if (array_key_exists('UPLOAD', $section_text) && !empty($section_text['UPLOAD'])) {
+            $upload_files = trim($section_text['UPLOAD']);
+            $upload_files = explode("\n", $upload_files);
+
+            $request = "Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737\n" .
+                       "-----------------------------20896060251896012921717172737\n";
+            foreach ($upload_files as $fileinfo) {
+                $fileinfo = explode('=', $fileinfo);
+                if (count($fileinfo) != 2) {
+                    return PEAR::raiseError("Invalid UPLOAD section in test file: $file");
+                }
+                if (!realpath(dirname($file) . '/' . $fileinfo[1])) {
+                    return PEAR::raiseError("File for upload does not exist: $fileinfo[1] " .
+                        "in test file: $file");
+                }
+                $file_contents = file_get_contents(dirname($file) . '/' . $fileinfo[1]);
+                $fileinfo[1] = basename($fileinfo[1]);
+                $request .= "Content-Disposition: form-data; name=\"$fileinfo[0]\"; filename=\"$fileinfo[1]\"\n";
+                $request .= "Content-Type: text/plain\n\n";
+                $request .= $file_contents . "\n" .
+                    "-----------------------------20896060251896012921717172737\n";
+            }
+
+            if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
+                // encode POST raw
+                $post = trim($section_text['POST']);
+                $post = explode('&', $post);
+                foreach ($post as $i => $post_info) {
+                    $post_info = explode('=', $post_info);
+                    if (count($post_info) != 2) {
+                        return PEAR::raiseError("Invalid POST data in test file: $file");
+                    }
+                    $post_info[0] = rawurldecode($post_info[0]);
+                    $post_info[1] = rawurldecode($post_info[1]);
+                    $post[$i] = $post_info;
+                }
+                foreach ($post as $post_info) {
+                    $request .= "Content-Disposition: form-data; name=\"$post_info[0]\"\n\n";
+                    $request .= $post_info[1] . "\n" .
+                        "-----------------------------20896060251896012921717172737\n";
+                }
+                unset($section_text['POST']);
+            }
+            $section_text['POST_RAW'] = $request;
+        }
+
+        return $section_text;
+    }
+
+    function _testCleanup($section_text, $temp_clean)
+    {
+        if ($section_text['CLEAN']) {
+            // perform test cleanup
+            $this->save_text($temp_clean, $section_text['CLEAN']);
+            $output = $this->system_with_timeout("$this->_php $temp_clean  2>&1");
+            if (strlen($output[1])) {
+                echo "BORKED --CLEAN-- section! output:\n", $output[1];
+            }
+            if (file_exists($temp_clean)) {
+                unlink($temp_clean);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Task/Common.php b/lib/php/PEAR/Task/Common.php
new file mode 100644
index 00000000..e725355e
--- /dev/null
+++ b/lib/php/PEAR/Task/Common.php
@@ -0,0 +1,202 @@
+<?php
+/**
+ * PEAR_Task_Common, base class for installer tasks
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Common.php 276394 2009-02-25 00:15:49Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**#@+
+ * Error codes for task validation routines
+ */
+define('PEAR_TASK_ERROR_NOATTRIBS', 1);
+define('PEAR_TASK_ERROR_MISSING_ATTRIB', 2);
+define('PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE', 3);
+define('PEAR_TASK_ERROR_INVALID', 4);
+/**#@-*/
+define('PEAR_TASK_PACKAGE', 1);
+define('PEAR_TASK_INSTALL', 2);
+define('PEAR_TASK_PACKAGEANDINSTALL', 3);
+/**
+ * A task is an operation that manipulates the contents of a file.
+ *
+ * Simple tasks operate on 1 file.  Multiple tasks are executed after all files have been
+ * processed and installed, and are designed to operate on all files containing the task.
+ * The Post-install script task simply takes advantage of the fact that it will be run
+ * after installation, replace is a simple task.
+ *
+ * Combining tasks is possible, but ordering is significant.
+ *
+ * <file name="test.php" role="php">
+ *  <tasks:replace from="@data-dir@" to="data_dir" type="pear-config"/>
+ *  <tasks:postinstallscript/>
+ * </file>
+ *
+ * This will first replace any instance of @data-dir@ in the test.php file
+ * with the path to the current data directory.  Then, it will include the
+ * test.php file and run the script it contains to configure the package post-installation.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ * @abstract
+ */
+class PEAR_Task_Common
+{
+    /**
+     * Valid types for this version are 'simple' and 'multiple'
+     *
+     * - simple tasks operate on the contents of a file and write out changes to disk
+     * - multiple tasks operate on the contents of many files and write out the
+     *   changes directly to disk
+     *
+     * Child task classes must override this property.
+     * @access protected
+     */
+    var $type = 'simple';
+    /**
+     * Determines which install phase this task is executed under
+     */
+    var $phase = PEAR_TASK_INSTALL;
+    /**
+     * @access protected
+     */
+    var $config;
+    /**
+     * @access protected
+     */
+    var $registry;
+    /**
+     * @access protected
+     */
+    var $logger;
+    /**
+     * @access protected
+     */
+    var $installphase;
+    /**
+     * @param PEAR_Config
+     * @param PEAR_Common
+     */
+    function PEAR_Task_Common(&$config, &$logger, $phase)
+    {
+        $this->config = &$config;
+        $this->registry = &$config->getRegistry();
+        $this->logger = &$logger;
+        $this->installphase = $phase;
+        if ($this->type == 'multiple') {
+            $GLOBALS['_PEAR_TASK_POSTINSTANCES'][get_class($this)][] = &$this;
+        }
+    }
+
+    /**
+     * Validate the basic contents of a task tag.
+     * @param PEAR_PackageFile_v2
+     * @param array
+     * @param PEAR_Config
+     * @param array the entire parsed <file> tag
+     * @return true|array On error, return an array in format:
+     *    array(PEAR_TASK_ERROR_???[, param1][, param2][, ...])
+     *
+     *    For PEAR_TASK_ERROR_MISSING_ATTRIB, pass the attribute name in
+     *    For PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, pass the attribute name and an array
+     *    of legal values in
+     * @static
+     * @abstract
+     */
+    function validateXml($pkg, $xml, $config, $fileXml)
+    {
+    }
+
+    /**
+     * Initialize a task instance with the parameters
+     * @param array raw, parsed xml
+     * @param array attributes from the <file> tag containing this task
+     * @param string|null last installed version of this package
+     * @abstract
+     */
+    function init($xml, $fileAttributes, $lastVersion)
+    {
+    }
+
+    /**
+     * Begin a task processing session.  All multiple tasks will be processed after each file
+     * has been successfully installed, all simple tasks should perform their task here and
+     * return any errors using the custom throwError() method to allow forward compatibility
+     *
+     * This method MUST NOT write out any changes to disk
+     * @param PEAR_PackageFile_v2
+     * @param string file contents
+     * @param string the eventual final file location (informational only)
+     * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
+     *         (use $this->throwError), otherwise return the new contents
+     * @abstract
+     */
+    function startSession($pkg, $contents, $dest)
+    {
+    }
+
+    /**
+     * This method is used to process each of the tasks for a particular multiple class
+     * type.  Simple tasks need not implement this method.
+     * @param array an array of tasks
+     * @access protected
+     * @static
+     * @abstract
+     */
+    function run($tasks)
+    {
+    }
+
+    /**
+     * @static
+     * @final
+     */
+    function hasPostinstallTasks()
+    {
+        return isset($GLOBALS['_PEAR_TASK_POSTINSTANCES']);
+    }
+
+    /**
+     * @static
+     * @final
+     */
+     function runPostinstallTasks()
+     {
+         foreach ($GLOBALS['_PEAR_TASK_POSTINSTANCES'] as $class => $tasks) {
+             $err = call_user_func(array($class, 'run'),
+                  $GLOBALS['_PEAR_TASK_POSTINSTANCES'][$class]);
+             if ($err) {
+                 return PEAR_Task_Common::throwError($err);
+             }
+         }
+         unset($GLOBALS['_PEAR_TASK_POSTINSTANCES']);
+    }
+
+    /**
+     * Determines whether a role is a script
+     * @return bool
+     */
+    function isScript()
+    {
+        return $this->type == 'script';
+    }
+
+    function throwError($msg, $code = -1)
+    {
+        include_once 'PEAR.php';
+        return PEAR::raiseError($msg, $code);
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Task/Postinstallscript.php b/lib/php/PEAR/Task/Postinstallscript.php
new file mode 100644
index 00000000..cc904246
--- /dev/null
+++ b/lib/php/PEAR/Task/Postinstallscript.php
@@ -0,0 +1,323 @@
+<?php
+/**
+ * <tasks:postinstallscript>
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Postinstallscript.php 276385 2009-02-24 23:46:03Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * Base class
+ */
+require_once 'PEAR/Task/Common.php';
+/**
+ * Implements the postinstallscript file task.
+ *
+ * Note that post-install scripts are handled separately from installation, by the
+ * "pear run-scripts" command
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Task_Postinstallscript extends PEAR_Task_Common
+{
+    var $type = 'script';
+    var $_class;
+    var $_params;
+    var $_obj;
+    /**
+     *
+     * @var PEAR_PackageFile_v2
+     */
+    var $_pkg;
+    var $_contents;
+    var $phase = PEAR_TASK_INSTALL;
+
+    /**
+     * Validate the raw xml at parsing-time.
+     *
+     * This also attempts to validate the script to make sure it meets the criteria
+     * for a post-install script
+     * @param PEAR_PackageFile_v2
+     * @param array The XML contents of the <postinstallscript> tag
+     * @param PEAR_Config
+     * @param array the entire parsed <file> tag
+     * @static
+     */
+    function validateXml($pkg, $xml, $config, $fileXml)
+    {
+        if ($fileXml['role'] != 'php') {
+            return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+            $fileXml['name'] . '" must be role="php"');
+        }
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        $file = $pkg->getFileContents($fileXml['name']);
+        if (PEAR::isError($file)) {
+            PEAR::popErrorHandling();
+            return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                $fileXml['name'] . '" is not valid: ' .
+                $file->getMessage());
+        } elseif ($file === null) {
+            return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                $fileXml['name'] . '" could not be retrieved for processing!');
+        } else {
+            $analysis = $pkg->analyzeSourceCode($file, true);
+            if (!$analysis) {
+                PEAR::popErrorHandling();
+                $warnings = '';
+                foreach ($pkg->getValidationWarnings() as $warn) {
+                    $warnings .= $warn['message'] . "\n";
+                }
+                return array(PEAR_TASK_ERROR_INVALID, 'Analysis of post-install script "' .
+                    $fileXml['name'] . '" failed: ' . $warnings);
+            }
+            if (count($analysis['declared_classes']) != 1) {
+                PEAR::popErrorHandling();
+                return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                    $fileXml['name'] . '" must declare exactly 1 class');
+            }
+            $class = $analysis['declared_classes'][0];
+            if ($class != str_replace(array('/', '.php'), array('_', ''),
+                  $fileXml['name']) . '_postinstall') {
+                PEAR::popErrorHandling();
+                return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                    $fileXml['name'] . '" class "' . $class . '" must be named "' .
+                    str_replace(array('/', '.php'), array('_', ''),
+                    $fileXml['name']) . '_postinstall"');
+            }
+            if (!isset($analysis['declared_methods'][$class])) {
+                PEAR::popErrorHandling();
+                return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                    $fileXml['name'] . '" must declare methods init() and run()');
+            }
+            $methods = array('init' => 0, 'run' => 1);
+            foreach ($analysis['declared_methods'][$class] as $method) {
+                if (isset($methods[$method])) {
+                    unset($methods[$method]);
+                }
+            }
+            if (count($methods)) {
+                PEAR::popErrorHandling();
+                return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                    $fileXml['name'] . '" must declare methods init() and run()');
+            }
+        }
+        PEAR::popErrorHandling();
+        $definedparams = array();
+        $tasksNamespace = $pkg->getTasksNs() . ':';
+        if (!isset($xml[$tasksNamespace . 'paramgroup']) && isset($xml['paramgroup'])) {
+            // in order to support the older betas, which did not expect internal tags
+            // to also use the namespace
+            $tasksNamespace = '';
+        }
+        if (isset($xml[$tasksNamespace . 'paramgroup'])) {
+            $params = $xml[$tasksNamespace . 'paramgroup'];
+            if (!is_array($params) || !isset($params[0])) {
+                $params = array($params);
+            }
+            foreach ($params as $param) {
+                if (!isset($param[$tasksNamespace . 'id'])) {
+                    return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                        $fileXml['name'] . '" <paramgroup> must have ' .
+                        'an ' . $tasksNamespace . 'id> tag');
+                }
+                if (isset($param[$tasksNamespace . 'name'])) {
+                    if (!in_array($param[$tasksNamespace . 'name'], $definedparams)) {
+                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                            $fileXml['name'] . '" ' . $tasksNamespace .
+                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
+                            '" parameter "' . $param[$tasksNamespace . 'name'] .
+                            '" has not been previously defined');
+                    }
+                    if (!isset($param[$tasksNamespace . 'conditiontype'])) {
+                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                            $fileXml['name'] . '" ' . $tasksNamespace .
+                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
+                            '" must have a ' . $tasksNamespace .
+                            'conditiontype> tag containing either "=", ' .
+                            '"!=", or "preg_match"');
+                    }
+                    if (!in_array($param[$tasksNamespace . 'conditiontype'],
+                          array('=', '!=', 'preg_match'))) {
+                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                            $fileXml['name'] . '" ' . $tasksNamespace .
+                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
+                            '" must have a ' . $tasksNamespace .
+                            'conditiontype> tag containing either "=", ' .
+                            '"!=", or "preg_match"');
+                    }
+                    if (!isset($param[$tasksNamespace . 'value'])) {
+                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                            $fileXml['name'] . '" ' . $tasksNamespace .
+                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
+                            '" must have a ' . $tasksNamespace .
+                            'value> tag containing expected parameter value');
+                    }
+                }
+                if (isset($param[$tasksNamespace . 'instructions'])) {
+                    if (!is_string($param[$tasksNamespace . 'instructions'])) {
+                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                            $fileXml['name'] . '" ' . $tasksNamespace .
+                            'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
+                            '" ' . $tasksNamespace . 'instructions> must be simple text');
+                    }
+                }
+                if (!isset($param[$tasksNamespace . 'param'])) {
+                    continue; // <param> is no longer required
+                }
+                $subparams = $param[$tasksNamespace . 'param'];
+                if (!is_array($subparams) || !isset($subparams[0])) {
+                    $subparams = array($subparams);
+                }
+                foreach ($subparams as $subparam) {
+                    if (!isset($subparam[$tasksNamespace . 'name'])) {
+                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                            $fileXml['name'] . '" parameter for ' .
+                            $tasksNamespace . 'paramgroup> id "' .
+                            $param[$tasksNamespace . 'id'] . '" must have ' .
+                            'a ' . $tasksNamespace . 'name> tag');
+                    }
+                    if (!preg_match('/[a-zA-Z0-9]+/',
+                          $subparam[$tasksNamespace . 'name'])) {
+                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                            $fileXml['name'] . '" parameter "' .
+                            $subparam[$tasksNamespace . 'name'] .
+                            '" for ' . $tasksNamespace . 'paramgroup> id "' .
+                            $param[$tasksNamespace . 'id'] .
+                            '" is not a valid name.  Must contain only alphanumeric characters');
+                    }
+                    if (!isset($subparam[$tasksNamespace . 'prompt'])) {
+                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                            $fileXml['name'] . '" parameter "' .
+                            $subparam[$tasksNamespace . 'name'] .
+                            '" for ' . $tasksNamespace . 'paramgroup> id "' .
+                            $param[$tasksNamespace . 'id'] .
+                            '" must have a ' . $tasksNamespace . 'prompt> tag');
+                    }
+                    if (!isset($subparam[$tasksNamespace . 'type'])) {
+                        return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
+                            $fileXml['name'] . '" parameter "' .
+                            $subparam[$tasksNamespace . 'name'] .
+                            '" for ' . $tasksNamespace . 'paramgroup> id "' .
+                            $param[$tasksNamespace . 'id'] .
+                            '" must have a ' . $tasksNamespace . 'type> tag');
+                    }
+                    $definedparams[] = $param[$tasksNamespace . 'id'] . '::' .
+                    $subparam[$tasksNamespace . 'name'];
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Initialize a task instance with the parameters
+     * @param array raw, parsed xml
+     * @param array attributes from the <file> tag containing this task
+     * @param string|null last installed version of this package, if any (useful for upgrades)
+     */
+    function init($xml, $fileattribs, $lastversion)
+    {
+        $this->_class = str_replace('/', '_', $fileattribs['name']);
+        $this->_filename = $fileattribs['name'];
+        $this->_class = str_replace ('.php', '', $this->_class) . '_postinstall';
+        $this->_params = $xml;
+        $this->_lastversion = $lastversion;
+    }
+
+    /**
+     * Strip the tasks: namespace from internal params
+     *
+     * @access private
+     */
+    function _stripNamespace($params = null)
+    {
+        if ($params === null) {
+            $params = array();
+            if (!is_array($this->_params)) {
+                return;
+            }
+            foreach ($this->_params as $i => $param) {
+                if (is_array($param)) {
+                    $param = $this->_stripNamespace($param);
+                }
+                $params[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param;
+            }
+            $this->_params = $params;
+        } else {
+            $newparams = array();
+            foreach ($params as $i => $param) {
+                if (is_array($param)) {
+                    $param = $this->_stripNamespace($param);
+                }
+                $newparams[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param;
+            }
+            return $newparams;
+        }
+    }
+
+    /**
+     * Unlike other tasks, the installed file name is passed in instead of the file contents,
+     * because this task is handled post-installation
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @param string file name
+     * @return bool|PEAR_Error false to skip this file, PEAR_Error to fail
+     *         (use $this->throwError)
+     */
+    function startSession($pkg, $contents)
+    {
+        if ($this->installphase != PEAR_TASK_INSTALL) {
+            return false;
+        }
+        // remove the tasks: namespace if present
+        $this->_pkg = $pkg;
+        $this->_stripNamespace();
+        $this->logger->log(0, 'Including external post-installation script "' .
+            $contents . '" - any errors are in this script');
+        include_once $contents;
+        if (class_exists($this->_class)) {
+            $this->logger->log(0, 'Inclusion succeeded');
+        } else {
+            return $this->throwError('init of post-install script class "' . $this->_class
+                . '" failed');
+        }
+        $this->_obj = new $this->_class;
+        $this->logger->log(1, 'running post-install script "' . $this->_class . '->init()"');
+        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+        $res = $this->_obj->init($this->config, $pkg, $this->_lastversion);
+        PEAR::popErrorHandling();
+        if ($res) {
+            $this->logger->log(0, 'init succeeded');
+        } else {
+            return $this->throwError('init of post-install script "' . $this->_class .
+                '->init()" failed');
+        }
+        $this->_contents = $contents;
+        return true;
+    }
+
+    /**
+     * No longer used
+     * @see PEAR_PackageFile_v2::runPostinstallScripts()
+     * @param array an array of tasks
+     * @param string install or upgrade
+     * @access protected
+     * @static
+     */
+    function run()
+    {
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Task/Postinstallscript/rw.php b/lib/php/PEAR/Task/Postinstallscript/rw.php
new file mode 100644
index 00000000..a89e7599
--- /dev/null
+++ b/lib/php/PEAR/Task/Postinstallscript/rw.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * <tasks:postinstallscript> - read/write version
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a10
+ */
+/**
+ * Base class
+ */
+require_once 'PEAR/Task/Postinstallscript.php';
+/**
+ * Abstracts the postinstallscript file task xml.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a10
+ */
+class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript
+{
+    /**
+     * parent package file object
+     *
+     * @var PEAR_PackageFile_v2_rw
+     */
+    var $_pkg;
+    /**
+     * Enter description here...
+     *
+     * @param PEAR_PackageFile_v2_rw $pkg
+     * @param PEAR_Config $config
+     * @param PEAR_Frontend $logger
+     * @param array $fileXml
+     * @return PEAR_Task_Postinstallscript_rw
+     */
+    function PEAR_Task_Postinstallscript_rw(&$pkg, &$config, &$logger, $fileXml)
+    {
+        parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
+        $this->_contents = $fileXml;
+        $this->_pkg = &$pkg;
+        $this->_params = array();
+    }
+
+    function validate()
+    {
+        return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
+    }
+
+    function getName()
+    {
+        return 'postinstallscript';
+    }
+
+    /**
+     * add a simple <paramgroup> to the post-install script
+     *
+     * Order is significant, so call this method in the same
+     * sequence the users should see the paramgroups.  The $params
+     * parameter should either be the result of a call to {@link getParam()}
+     * or an array of calls to getParam().
+     *
+     * Use {@link addConditionTypeGroup()} to add a <paramgroup> containing
+     * a <conditiontype> tag
+     * @param string $id <paramgroup> id as seen by the script
+     * @param array|false $params array of getParam() calls, or false for no params
+     * @param string|false $instructions
+     */
+    function addParamGroup($id, $params = false, $instructions = false)
+    {
+        if ($params && isset($params[0]) && !isset($params[1])) {
+            $params = $params[0];
+        }
+        $stuff =
+            array(
+                $this->_pkg->getTasksNs() . ':id' => $id,
+            );
+        if ($instructions) {
+            $stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions;
+        }
+        if ($params) {
+            $stuff[$this->_pkg->getTasksNs() . ':param'] = $params;
+        }
+        $this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff;
+    }
+
+    /**
+     * add a complex <paramgroup> to the post-install script with conditions
+     *
+     * This inserts a <paramgroup> with
+     *
+     * Order is significant, so call this method in the same
+     * sequence the users should see the paramgroups.  The $params
+     * parameter should either be the result of a call to {@link getParam()}
+     * or an array of calls to getParam().
+     *
+     * Use {@link addParamGroup()} to add a simple <paramgroup>
+     *
+     * @param string $id <paramgroup> id as seen by the script
+     * @param string $oldgroup <paramgroup> id of the section referenced by
+     *                         <conditiontype>
+     * @param string $param name of the <param> from the older section referenced
+     *                      by <contitiontype>
+     * @param string $value value to match of the parameter
+     * @param string $conditiontype one of '=', '!=', 'preg_match'
+     * @param array|false $params array of getParam() calls, or false for no params
+     * @param string|false $instructions
+     */
+    function addConditionTypeGroup($id, $oldgroup, $param, $value, $conditiontype = '=',
+                                   $params = false, $instructions = false)
+    {
+        if ($params && isset($params[0]) && !isset($params[1])) {
+            $params = $params[0];
+        }
+        $stuff = array(
+            $this->_pkg->getTasksNs() . ':id' => $id,
+        );
+        if ($instructions) {
+            $stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions;
+        }
+        $stuff[$this->_pkg->getTasksNs() . ':name'] = $oldgroup . '::' . $param;
+        $stuff[$this->_pkg->getTasksNs() . ':conditiontype'] = $conditiontype;
+        $stuff[$this->_pkg->getTasksNs() . ':value'] = $value;
+        if ($params) {
+            $stuff[$this->_pkg->getTasksNs() . ':param'] = $params;
+        }
+        $this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff;
+    }
+
+    function getXml()
+    {
+        return $this->_params;
+    }
+
+    /**
+     * Use to set up a param tag for use in creating a paramgroup
+     * @static
+     */
+    function getParam($name, $prompt, $type = 'string', $default = null)
+    {
+        if ($default !== null) {
+            return
+            array(
+                $this->_pkg->getTasksNs() . ':name' => $name,
+                $this->_pkg->getTasksNs() . ':prompt' => $prompt,
+                $this->_pkg->getTasksNs() . ':type' => $type,
+                $this->_pkg->getTasksNs() . ':default' => $default
+            );
+        }
+        return
+            array(
+                $this->_pkg->getTasksNs() . ':name' => $name,
+                $this->_pkg->getTasksNs() . ':prompt' => $prompt,
+                $this->_pkg->getTasksNs() . ':type' => $type,
+            );
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Task/Replace.php b/lib/php/PEAR/Task/Replace.php
new file mode 100644
index 00000000..fec254f0
--- /dev/null
+++ b/lib/php/PEAR/Task/Replace.php
@@ -0,0 +1,176 @@
+<?php
+/**
+ * <tasks:replace>
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Replace.php 276394 2009-02-25 00:15:49Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * Base class
+ */
+require_once 'PEAR/Task/Common.php';
+/**
+ * Implements the replace file task.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Task_Replace extends PEAR_Task_Common
+{
+    var $type = 'simple';
+    var $phase = PEAR_TASK_PACKAGEANDINSTALL;
+    var $_replacements;
+
+    /**
+     * Validate the raw xml at parsing-time.
+     * @param PEAR_PackageFile_v2
+     * @param array raw, parsed xml
+     * @param PEAR_Config
+     * @static
+     */
+    function validateXml($pkg, $xml, $config, $fileXml)
+    {
+        if (!isset($xml['attribs'])) {
+            return array(PEAR_TASK_ERROR_NOATTRIBS);
+        }
+        if (!isset($xml['attribs']['type'])) {
+            return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'type');
+        }
+        if (!isset($xml['attribs']['to'])) {
+            return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'to');
+        }
+        if (!isset($xml['attribs']['from'])) {
+            return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'from');
+        }
+        if ($xml['attribs']['type'] == 'pear-config') {
+            if (!in_array($xml['attribs']['to'], $config->getKeys())) {
+                return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
+                    $config->getKeys());
+            }
+        } elseif ($xml['attribs']['type'] == 'php-const') {
+            if (defined($xml['attribs']['to'])) {
+                return true;
+            } else {
+                return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
+                    array('valid PHP constant'));
+            }
+        } elseif ($xml['attribs']['type'] == 'package-info') {
+            if (in_array($xml['attribs']['to'],
+                array('name', 'summary', 'channel', 'notes', 'extends', 'description',
+                    'release_notes', 'license', 'release-license', 'license-uri',
+                    'version', 'api-version', 'state', 'api-state', 'release_date',
+                    'date', 'time'))) {
+                return true;
+            } else {
+                return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
+                    array('name', 'summary', 'channel', 'notes', 'extends', 'description',
+                    'release_notes', 'license', 'release-license', 'license-uri',
+                    'version', 'api-version', 'state', 'api-state', 'release_date',
+                    'date', 'time'));
+            }
+        } else {
+            return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'type', $xml['attribs']['type'],
+                array('pear-config', 'package-info', 'php-const'));
+        }
+        return true;
+    }
+
+    /**
+     * Initialize a task instance with the parameters
+     * @param array raw, parsed xml
+     * @param unused
+     */
+    function init($xml, $attribs)
+    {
+        $this->_replacements = isset($xml['attribs']) ? array($xml) : $xml;
+    }
+
+    /**
+     * Do a package.xml 1.0 replacement, with additional package-info fields available
+     *
+     * See validateXml() source for the complete list of allowed fields
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @param string file contents
+     * @param string the eventual final file location (informational only)
+     * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
+     *         (use $this->throwError), otherwise return the new contents
+     */
+    function startSession($pkg, $contents, $dest)
+    {
+        $subst_from = $subst_to = array();
+        foreach ($this->_replacements as $a) {
+            $a = $a['attribs'];
+            $to = '';
+            if ($a['type'] == 'pear-config') {
+                if ($this->installphase == PEAR_TASK_PACKAGE) {
+                    return false;
+                }
+                if ($a['to'] == 'master_server') {
+                    $chan = $this->registry->getChannel($pkg->getChannel());
+                    if (!PEAR::isError($chan)) {
+                        $to = $chan->getServer();
+                    } else {
+                        $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]");
+                        return false;
+                    }
+                } else {
+                    if ($this->config->isDefinedLayer('ftp')) {
+                        // try the remote config file first
+                        $to = $this->config->get($a['to'], 'ftp', $pkg->getChannel());
+                        if (is_null($to)) {
+                            // then default to local
+                            $to = $this->config->get($a['to'], null, $pkg->getChannel());
+                        }
+                    } else {
+                        $to = $this->config->get($a['to'], null, $pkg->getChannel());
+                    }
+                }
+                if (is_null($to)) {
+                    $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]");
+                    return false;
+                }
+            } elseif ($a['type'] == 'php-const') {
+                if ($this->installphase == PEAR_TASK_PACKAGE) {
+                    return false;
+                }
+                if (defined($a['to'])) {
+                    $to = constant($a['to']);
+                } else {
+                    $this->logger->log(0, "$dest: invalid php-const replacement: $a[to]");
+                    return false;
+                }
+            } else {
+                if ($t = $pkg->packageInfo($a['to'])) {
+                    $to = $t;
+                } else {
+                    $this->logger->log(0, "$dest: invalid package-info replacement: $a[to]");
+                    return false;
+                }
+            }
+            if (!is_null($to)) {
+                $subst_from[] = $a['from'];
+                $subst_to[] = $to;
+            }
+        }
+        $this->logger->log(3, "doing " . sizeof($subst_from) .
+            " substitution(s) for $dest");
+        if (sizeof($subst_from)) {
+            $contents = str_replace($subst_from, $subst_to, $contents);
+        }
+        return $contents;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Task/Replace/rw.php b/lib/php/PEAR/Task/Replace/rw.php
new file mode 100644
index 00000000..9245db8b
--- /dev/null
+++ b/lib/php/PEAR/Task/Replace/rw.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * <tasks:replace> - read/write version
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a10
+ */
+/**
+ * Base class
+ */
+require_once 'PEAR/Task/Replace.php';
+/**
+ * Abstracts the replace task xml.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a10
+ */
+class PEAR_Task_Replace_rw extends PEAR_Task_Replace
+{
+    function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml)
+    {
+        parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
+        $this->_contents = $fileXml;
+        $this->_pkg = &$pkg;
+        $this->_params = array();
+    }
+
+    function validate()
+    {
+        return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
+    }
+
+    function setInfo($from, $to, $type)
+    {
+        $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type));
+    }
+
+    function getName()
+    {
+        return 'replace';
+    }
+
+    function getXml()
+    {
+        return $this->_params;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Task/Unixeol.php b/lib/php/PEAR/Task/Unixeol.php
new file mode 100644
index 00000000..7775e980
--- /dev/null
+++ b/lib/php/PEAR/Task/Unixeol.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * <tasks:unixeol>
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Unixeol.php 276394 2009-02-25 00:15:49Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * Base class
+ */
+require_once 'PEAR/Task/Common.php';
+/**
+ * Implements the unix line endings file task.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Task_Unixeol extends PEAR_Task_Common
+{
+    var $type = 'simple';
+    var $phase = PEAR_TASK_PACKAGE;
+    var $_replacements;
+
+    /**
+     * Validate the raw xml at parsing-time.
+     * @param PEAR_PackageFile_v2
+     * @param array raw, parsed xml
+     * @param PEAR_Config
+     * @static
+     */
+    function validateXml($pkg, $xml, $config, $fileXml)
+    {
+        if ($xml != '') {
+            return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed');
+        }
+        return true;
+    }
+
+    /**
+     * Initialize a task instance with the parameters
+     * @param array raw, parsed xml
+     * @param unused
+     */
+    function init($xml, $attribs)
+    {
+    }
+
+    /**
+     * Replace all line endings with line endings customized for the current OS
+     *
+     * See validateXml() source for the complete list of allowed fields
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @param string file contents
+     * @param string the eventual final file location (informational only)
+     * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
+     *         (use $this->throwError), otherwise return the new contents
+     */
+    function startSession($pkg, $contents, $dest)
+    {
+        $this->logger->log(3, "replacing all line endings with \\n in $dest");
+        return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents);
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Task/Unixeol/rw.php b/lib/php/PEAR/Task/Unixeol/rw.php
new file mode 100644
index 00000000..4335a33d
--- /dev/null
+++ b/lib/php/PEAR/Task/Unixeol/rw.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * <tasks:unixeol> - read/write version
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a10
+ */
+/**
+ * Base class
+ */
+require_once 'PEAR/Task/Unixeol.php';
+/**
+ * Abstracts the unixeol task xml.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a10
+ */
+class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol
+{
+    function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml)
+    {
+        parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
+        $this->_contents = $fileXml;
+        $this->_pkg = &$pkg;
+        $this->_params = array();
+    }
+
+    function validate()
+    {
+        return true;
+    }
+
+    function getName()
+    {
+        return 'unixeol';
+    }
+
+    function getXml()
+    {
+        return '';
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Task/Windowseol.php b/lib/php/PEAR/Task/Windowseol.php
new file mode 100644
index 00000000..a36f7bdd
--- /dev/null
+++ b/lib/php/PEAR/Task/Windowseol.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * <tasks:windowseol>
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Windowseol.php 276394 2009-02-25 00:15:49Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**
+ * Base class
+ */
+require_once 'PEAR/Task/Common.php';
+/**
+ * Implements the windows line endsings file task.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Task_Windowseol extends PEAR_Task_Common
+{
+    var $type = 'simple';
+    var $phase = PEAR_TASK_PACKAGE;
+    var $_replacements;
+
+    /**
+     * Validate the raw xml at parsing-time.
+     * @param PEAR_PackageFile_v2
+     * @param array raw, parsed xml
+     * @param PEAR_Config
+     * @static
+     */
+    function validateXml($pkg, $xml, $config, $fileXml)
+    {
+        if ($xml != '') {
+            return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed');
+        }
+        return true;
+    }
+
+    /**
+     * Initialize a task instance with the parameters
+     * @param array raw, parsed xml
+     * @param unused
+     */
+    function init($xml, $attribs)
+    {
+    }
+
+    /**
+     * Replace all line endings with windows line endings
+     *
+     * See validateXml() source for the complete list of allowed fields
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     * @param string file contents
+     * @param string the eventual final file location (informational only)
+     * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
+     *         (use $this->throwError), otherwise return the new contents
+     */
+    function startSession($pkg, $contents, $dest)
+    {
+        $this->logger->log(3, "replacing all line endings with \\r\\n in $dest");
+        return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents);
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Task/Windowseol/rw.php b/lib/php/PEAR/Task/Windowseol/rw.php
new file mode 100644
index 00000000..191b3a2d
--- /dev/null
+++ b/lib/php/PEAR/Task/Windowseol/rw.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * <tasks:windowseol> - read/write version
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a10
+ */
+/**
+ * Base class
+ */
+require_once 'PEAR/Task/Windowseol.php';
+/**
+ * Abstracts the windowseol task xml.
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a10
+ */
+class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol
+{
+    function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml)
+    {
+        parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
+        $this->_contents = $fileXml;
+        $this->_pkg = &$pkg;
+        $this->_params = array();
+    }
+
+    function validate()
+    {
+        return true;
+    }
+
+    function getName()
+    {
+        return 'windowseol';
+    }
+
+    function getXml()
+    {
+        return '';
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/Validate.php b/lib/php/PEAR/Validate.php
new file mode 100644
index 00000000..75343648
--- /dev/null
+++ b/lib/php/PEAR/Validate.php
@@ -0,0 +1,629 @@
+<?php
+/**
+ * PEAR_Validate
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: Validate.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+/**#@+
+ * Constants for install stage
+ */
+define('PEAR_VALIDATE_INSTALLING', 1);
+define('PEAR_VALIDATE_UNINSTALLING', 2); // this is not bit-mapped like the others
+define('PEAR_VALIDATE_NORMAL', 3);
+define('PEAR_VALIDATE_DOWNLOADING', 4); // this is not bit-mapped like the others
+define('PEAR_VALIDATE_PACKAGING', 7);
+/**#@-*/
+require_once 'PEAR/Common.php';
+require_once 'PEAR/Validator/PECL.php';
+
+/**
+ * Validation class for package.xml - channel-level advanced validation
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a1
+ */
+class PEAR_Validate
+{
+    var $packageregex = _PEAR_COMMON_PACKAGE_NAME_PREG;
+    /**
+     * @var PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     */
+    var $_packagexml;
+    /**
+     * @var int one of the PEAR_VALIDATE_* constants
+     */
+    var $_state = PEAR_VALIDATE_NORMAL;
+    /**
+     * Format: ('error' => array('field' => name, 'reason' => reason), 'warning' => same)
+     * @var array
+     * @access private
+     */
+    var $_failures = array('error' => array(), 'warning' => array());
+
+    /**
+     * Override this method to handle validation of normal package names
+     * @param string
+     * @return bool
+     * @access protected
+     */
+    function _validPackageName($name)
+    {
+        return (bool) preg_match('/^' . $this->packageregex . '\\z/', $name);
+    }
+
+    /**
+     * @param string package name to validate
+     * @param string name of channel-specific validation package
+     * @final
+     */
+    function validPackageName($name, $validatepackagename = false)
+    {
+        if ($validatepackagename) {
+            if (strtolower($name) == strtolower($validatepackagename)) {
+                return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*\\z/', $name);
+            }
+        }
+        return $this->_validPackageName($name);
+    }
+
+    /**
+     * This validates a bundle name, and bundle names must conform
+     * to the PEAR naming convention, so the method is final and static.
+     * @param string
+     * @final
+     * @static
+     */
+    function validGroupName($name)
+    {
+        return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/', $name);
+    }
+
+    /**
+     * Determine whether $state represents a valid stability level
+     * @param string
+     * @return bool
+     * @static
+     * @final
+     */
+    function validState($state)
+    {
+        return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable'));
+    }
+
+    /**
+     * Get a list of valid stability levels
+     * @return array
+     * @static
+     * @final
+     */
+    function getValidStates()
+    {
+        return array('snapshot', 'devel', 'alpha', 'beta', 'stable');
+    }
+
+    /**
+     * Determine whether a version is a properly formatted version number that can be used
+     * by version_compare
+     * @param string
+     * @return bool
+     * @static
+     * @final
+     */
+    function validVersion($ver)
+    {
+        return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
+    }
+
+    /**
+     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
+     */
+    function setPackageFile(&$pf)
+    {
+        $this->_packagexml = &$pf;
+    }
+
+    /**
+     * @access private
+     */
+    function _addFailure($field, $reason)
+    {
+        $this->_failures['errors'][] = array('field' => $field, 'reason' => $reason);
+    }
+
+    /**
+     * @access private
+     */
+    function _addWarning($field, $reason)
+    {
+        $this->_failures['warnings'][] = array('field' => $field, 'reason' => $reason);
+    }
+
+    function getFailures()
+    {
+        $failures = $this->_failures;
+        $this->_failures = array('warnings' => array(), 'errors' => array());
+        return $failures;
+    }
+
+    /**
+     * @param int one of the PEAR_VALIDATE_* constants
+     */
+    function validate($state = null)
+    {
+        if (!isset($this->_packagexml)) {
+            return false;
+        }
+        if ($state !== null) {
+            $this->_state = $state;
+        }
+        $this->_failures = array('warnings' => array(), 'errors' => array());
+        $this->validatePackageName();
+        $this->validateVersion();
+        $this->validateMaintainers();
+        $this->validateDate();
+        $this->validateSummary();
+        $this->validateDescription();
+        $this->validateLicense();
+        $this->validateNotes();
+        if ($this->_packagexml->getPackagexmlVersion() == '1.0') {
+            $this->validateState();
+            $this->validateFilelist();
+        } elseif ($this->_packagexml->getPackagexmlVersion() == '2.0' ||
+                  $this->_packagexml->getPackagexmlVersion() == '2.1') {
+            $this->validateTime();
+            $this->validateStability();
+            $this->validateDeps();
+            $this->validateMainFilelist();
+            $this->validateReleaseFilelist();
+            //$this->validateGlobalTasks();
+            $this->validateChangelog();
+        }
+        return !((bool) count($this->_failures['errors']));
+    }
+
+    /**
+     * @access protected
+     */
+    function validatePackageName()
+    {
+        if ($this->_state == PEAR_VALIDATE_PACKAGING ||
+              $this->_state == PEAR_VALIDATE_NORMAL) {
+            if (($this->_packagexml->getPackagexmlVersion() == '2.0' ||
+                 $this->_packagexml->getPackagexmlVersion() == '2.1') &&
+                  $this->_packagexml->getExtends()) {
+                $version = $this->_packagexml->getVersion() . '';
+                $name = $this->_packagexml->getPackage();
+                $test = array_shift($a = explode('.', $version));
+                if ($test == '0') {
+                    return true;
+                }
+                $vlen = strlen($test);
+                $majver = substr($name, strlen($name) - $vlen);
+                while ($majver && !is_numeric($majver{0})) {
+                    $majver = substr($majver, 1);
+                }
+                if ($majver != $test) {
+                    $this->_addWarning('package', "package $name extends package " .
+                        $this->_packagexml->getExtends() . ' and so the name should ' .
+                        'have a postfix equal to the major version like "' .
+                        $this->_packagexml->getExtends() . $test . '"');
+                    return true;
+                } elseif (substr($name, 0, strlen($name) - $vlen) !=
+                            $this->_packagexml->getExtends()) {
+                    $this->_addWarning('package', "package $name extends package " .
+                        $this->_packagexml->getExtends() . ' and so the name must ' .
+                        'be an extension like "' . $this->_packagexml->getExtends() .
+                        $test . '"');
+                    return true;
+                }
+            }
+        }
+        if (!$this->validPackageName($this->_packagexml->getPackage())) {
+            $this->_addFailure('name', 'package name "' .
+                $this->_packagexml->getPackage() . '" is invalid');
+            return false;
+        }
+    }
+
+    /**
+     * @access protected
+     */
+    function validateVersion()
+    {
+        if ($this->_state != PEAR_VALIDATE_PACKAGING) {
+            if (!$this->validVersion($this->_packagexml->getVersion())) {
+                $this->_addFailure('version',
+                    'Invalid version number "' . $this->_packagexml->getVersion() . '"');
+            }
+            return false;
+        }
+        $version = $this->_packagexml->getVersion();
+        $versioncomponents = explode('.', $version);
+        if (count($versioncomponents) != 3) {
+            $this->_addWarning('version',
+                'A version number should have 3 decimals (x.y.z)');
+            return true;
+        }
+        $name = $this->_packagexml->getPackage();
+        // version must be based upon state
+        switch ($this->_packagexml->getState()) {
+            case 'snapshot' :
+                return true;
+            case 'devel' :
+                if ($versioncomponents[0] . 'a' == '0a') {
+                    return true;
+                }
+                if ($versioncomponents[0] == 0) {
+                    $versioncomponents[0] = '0';
+                    $this->_addWarning('version',
+                        'version "' . $version . '" should be "' .
+                        implode('.' ,$versioncomponents) . '"');
+                } else {
+                    $this->_addWarning('version',
+                        'packages with devel stability must be < version 1.0.0');
+                }
+                return true;
+            break;
+            case 'alpha' :
+            case 'beta' :
+                // check for a package that extends a package,
+                // like Foo and Foo2
+                if ($this->_state == PEAR_VALIDATE_PACKAGING) {
+                    if (substr($versioncomponents[2], 1, 2) == 'rc') {
+                        $this->_addFailure('version', 'Release Candidate versions ' .
+                            'must have capital RC, not lower-case rc');
+                        return false;
+                    }
+                }
+                if (!$this->_packagexml->getExtends()) {
+                    if ($versioncomponents[0] == '1') {
+                        if ($versioncomponents[2]{0} == '0') {
+                            if ($versioncomponents[2] == '0') {
+                                // version 1.*.0000
+                                $this->_addWarning('version',
+                                    'version 1.' . $versioncomponents[1] .
+                                        '.0 probably should not be alpha or beta');
+                                return true;
+                            } elseif (strlen($versioncomponents[2]) > 1) {
+                                // version 1.*.0RC1 or 1.*.0beta24 etc.
+                                return true;
+                            } else {
+                                // version 1.*.0
+                                $this->_addWarning('version',
+                                    'version 1.' . $versioncomponents[1] .
+                                        '.0 probably should not be alpha or beta');
+                                return true;
+                            }
+                        } else {
+                            $this->_addWarning('version',
+                                'bugfix versions (1.3.x where x > 0) probably should ' .
+                                'not be alpha or beta');
+                            return true;
+                        }
+                    } elseif ($versioncomponents[0] != '0') {
+                        $this->_addWarning('version',
+                            'major versions greater than 1 are not allowed for packages ' .
+                            'without an <extends> tag or an identical postfix (foo2 v2.0.0)');
+                        return true;
+                    }
+                    if ($versioncomponents[0] . 'a' == '0a') {
+                        return true;
+                    }
+                    if ($versioncomponents[0] == 0) {
+                        $versioncomponents[0] = '0';
+                        $this->_addWarning('version',
+                            'version "' . $version . '" should be "' .
+                            implode('.' ,$versioncomponents) . '"');
+                    }
+                } else {
+                    $vlen = strlen($versioncomponents[0] . '');
+                    $majver = substr($name, strlen($name) - $vlen);
+                    while ($majver && !is_numeric($majver{0})) {
+                        $majver = substr($majver, 1);
+                    }
+                    if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
+                        $this->_addWarning('version', 'first version number "' .
+                            $versioncomponents[0] . '" must match the postfix of ' .
+                            'package name "' . $name . '" (' .
+                            $majver . ')');
+                        return true;
+                    }
+                    if ($versioncomponents[0] == $majver) {
+                        if ($versioncomponents[2]{0} == '0') {
+                            if ($versioncomponents[2] == '0') {
+                                // version 2.*.0000
+                                $this->_addWarning('version',
+                                    "version $majver." . $versioncomponents[1] .
+                                        '.0 probably should not be alpha or beta');
+                                return false;
+                            } elseif (strlen($versioncomponents[2]) > 1) {
+                                // version 2.*.0RC1 or 2.*.0beta24 etc.
+                                return true;
+                            } else {
+                                // version 2.*.0
+                                $this->_addWarning('version',
+                                    "version $majver." . $versioncomponents[1] .
+                                        '.0 cannot be alpha or beta');
+                                return true;
+                            }
+                        } else {
+                            $this->_addWarning('version',
+                                "bugfix versions ($majver.x.y where y > 0) should " .
+                                'not be alpha or beta');
+                            return true;
+                        }
+                    } elseif ($versioncomponents[0] != '0') {
+                        $this->_addWarning('version',
+                            "only versions 0.x.y and $majver.x.y are allowed for alpha/beta releases");
+                        return true;
+                    }
+                    if ($versioncomponents[0] . 'a' == '0a') {
+                        return true;
+                    }
+                    if ($versioncomponents[0] == 0) {
+                        $versioncomponents[0] = '0';
+                        $this->_addWarning('version',
+                            'version "' . $version . '" should be "' .
+                            implode('.' ,$versioncomponents) . '"');
+                    }
+                }
+                return true;
+            break;
+            case 'stable' :
+                if ($versioncomponents[0] == '0') {
+                    $this->_addWarning('version', 'versions less than 1.0.0 cannot ' .
+                    'be stable');
+                    return true;
+                }
+                if (!is_numeric($versioncomponents[2])) {
+                    if (preg_match('/\d+(rc|a|alpha|b|beta)\d*/i',
+                          $versioncomponents[2])) {
+                        $this->_addWarning('version', 'version "' . $version . '" or any ' .
+                            'RC/beta/alpha version cannot be stable');
+                        return true;
+                    }
+                }
+                // check for a package that extends a package,
+                // like Foo and Foo2
+                if ($this->_packagexml->getExtends()) {
+                    $vlen = strlen($versioncomponents[0] . '');
+                    $majver = substr($name, strlen($name) - $vlen);
+                    while ($majver && !is_numeric($majver{0})) {
+                        $majver = substr($majver, 1);
+                    }
+                    if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
+                        $this->_addWarning('version', 'first version number "' .
+                            $versioncomponents[0] . '" must match the postfix of ' .
+                            'package name "' . $name . '" (' .
+                            $majver . ')');
+                        return true;
+                    }
+                } elseif ($versioncomponents[0] > 1) {
+                    $this->_addWarning('version', 'major version x in x.y.z may not be greater than ' .
+                        '1 for any package that does not have an <extends> tag');
+                }
+                return true;
+            break;
+            default :
+                return false;
+            break;
+        }
+    }
+
+    /**
+     * @access protected
+     */
+    function validateMaintainers()
+    {
+        // maintainers can only be truly validated server-side for most channels
+        // but allow this customization for those who wish it
+        return true;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateDate()
+    {
+        if ($this->_state == PEAR_VALIDATE_NORMAL ||
+              $this->_state == PEAR_VALIDATE_PACKAGING) {
+
+            if (!preg_match('/(\d\d\d\d)\-(\d\d)\-(\d\d)/',
+                  $this->_packagexml->getDate(), $res) ||
+                  count($res) < 4
+                  || !checkdate($res[2], $res[3], $res[1])
+                ) {
+                $this->_addFailure('date', 'invalid release date "' .
+                    $this->_packagexml->getDate() . '"');
+                return false;
+            }
+
+            if ($this->_state == PEAR_VALIDATE_PACKAGING &&
+                  $this->_packagexml->getDate() != date('Y-m-d')) {
+                $this->_addWarning('date', 'Release Date "' .
+                    $this->_packagexml->getDate() . '" is not today');
+            }
+        }
+        return true;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateTime()
+    {
+        if (!$this->_packagexml->getTime()) {
+            // default of no time value set
+            return true;
+        }
+
+        // packager automatically sets time, so only validate if pear validate is called
+        if ($this->_state = PEAR_VALIDATE_NORMAL) {
+            if (!preg_match('/\d\d:\d\d:\d\d/',
+                  $this->_packagexml->getTime())) {
+                $this->_addFailure('time', 'invalid release time "' .
+                    $this->_packagexml->getTime() . '"');
+                return false;
+            }
+
+            $result = preg_match('|\d{2}\:\d{2}\:\d{2}|', $this->_packagexml->getTime(), $matches);
+            if ($result === false || empty($matches)) {
+                $this->_addFailure('time', 'invalid release time "' .
+                    $this->_packagexml->getTime() . '"');
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateState()
+    {
+        // this is the closest to "final" php4 can get
+        if (!PEAR_Validate::validState($this->_packagexml->getState())) {
+            if (strtolower($this->_packagexml->getState() == 'rc')) {
+                $this->_addFailure('state', 'RC is not a state, it is a version ' .
+                    'postfix, use ' . $this->_packagexml->getVersion() . 'RC1, state beta');
+            }
+            $this->_addFailure('state', 'invalid release state "' .
+                $this->_packagexml->getState() . '", must be one of: ' .
+                implode(', ', PEAR_Validate::getValidStates()));
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateStability()
+    {
+        $ret = true;
+        $packagestability = $this->_packagexml->getState();
+        $apistability = $this->_packagexml->getState('api');
+        if (!PEAR_Validate::validState($packagestability)) {
+            $this->_addFailure('state', 'invalid release stability "' .
+                $this->_packagexml->getState() . '", must be one of: ' .
+                implode(', ', PEAR_Validate::getValidStates()));
+            $ret = false;
+        }
+        $apistates = PEAR_Validate::getValidStates();
+        array_shift($apistates); // snapshot is not allowed
+        if (!in_array($apistability, $apistates)) {
+            $this->_addFailure('state', 'invalid API stability "' .
+                $this->_packagexml->getState('api') . '", must be one of: ' .
+                implode(', ', $apistates));
+            $ret = false;
+        }
+        return $ret;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateSummary()
+    {
+        return true;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateDescription()
+    {
+        return true;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateLicense()
+    {
+        return true;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateNotes()
+    {
+        return true;
+    }
+
+    /**
+     * for package.xml 2.0 only - channels can't use package.xml 1.0
+     * @access protected
+     */
+    function validateDependencies()
+    {
+        return true;
+    }
+
+    /**
+     * for package.xml 1.0 only
+     * @access private
+     */
+    function _validateFilelist()
+    {
+        return true; // placeholder for now
+    }
+
+    /**
+     * for package.xml 2.0 only
+     * @access protected
+     */
+    function validateMainFilelist()
+    {
+        return true; // placeholder for now
+    }
+
+    /**
+     * for package.xml 2.0 only
+     * @access protected
+     */
+    function validateReleaseFilelist()
+    {
+        return true; // placeholder for now
+    }
+
+    /**
+     * @access protected
+     */
+    function validateChangelog()
+    {
+        return true;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateFilelist()
+    {
+        return true;
+    }
+
+    /**
+     * @access protected
+     */
+    function validateDeps()
+    {
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR/Validator/PECL.php b/lib/php/PEAR/Validator/PECL.php
new file mode 100644
index 00000000..c0c60b85
--- /dev/null
+++ b/lib/php/PEAR/Validator/PECL.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Channel Validator for the pecl.php.net channel
+ *
+ * PHP 4 and PHP 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2006 The PHP Group
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: PECL.php 276383 2009-02-24 23:39:37Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a5
+ */
+/**
+ * This is the parent class for all validators
+ */
+require_once 'PEAR/Validate.php';
+/**
+ * Channel Validator for the pecl.php.net channel
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: 1.9.0
+ * @link       http://pear.php.net/package/PEAR
+ * @since      Class available since Release 1.4.0a5
+ */
+class PEAR_Validator_PECL extends PEAR_Validate
+{
+    function validateVersion()
+    {
+        if ($this->_state == PEAR_VALIDATE_PACKAGING) {
+            $version = $this->_packagexml->getVersion();
+            $versioncomponents = explode('.', $version);
+            $last = array_pop($versioncomponents);
+            if (substr($last, 1, 2) == 'rc') {
+                $this->_addFailure('version', 'Release Candidate versions must have ' .
+                'upper-case RC, not lower-case rc');
+                return false;
+            }
+        }
+        return true;
+    }
+
+    function validatePackageName()
+    {
+        $ret = parent::validatePackageName();
+        if ($this->_packagexml->getPackageType() == 'extsrc' ||
+              $this->_packagexml->getPackageType() == 'zendextsrc') {
+            if (strtolower($this->_packagexml->getPackage()) !=
+                  strtolower($this->_packagexml->getProvidesExtension())) {
+                $this->_addWarning('providesextension', 'package name "' .
+                    $this->_packagexml->getPackage() . '" is different from extension name "' .
+                    $this->_packagexml->getProvidesExtension() . '"');
+            }
+        }
+        return $ret;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/PEAR/XMLParser.php b/lib/php/PEAR/XMLParser.php
new file mode 100644
index 00000000..a56d3106
--- /dev/null
+++ b/lib/php/PEAR/XMLParser.php
@@ -0,0 +1,253 @@
+<?php
+/**
+ * PEAR_XMLParser
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Greg Beaver <cellog@php.net>
+ * @author     Stephan Schmidt (original XML_Unserializer code)
+ * @copyright  1997-2009 The Authors
+ * @license   http://opensource.org/licenses/bsd-license New BSD License
+ * @version    CVS: $Id: XMLParser.php 282970 2009-06-28 23:10:07Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 1.4.0a1
+ */
+
+/**
+ * Parser for any xml file
+ * @category  pear
+ * @package   PEAR
+ * @author    Greg Beaver <cellog@php.net>
+ * @author    Stephan Schmidt (original XML_Unserializer code)
+ * @copyright 1997-2009 The Authors
+ * @license   http://opensource.org/licenses/bsd-license New BSD License
+ * @version   Release: 1.9.0
+ * @link      http://pear.php.net/package/PEAR
+ * @since     Class available since Release 1.4.0a1
+ */
+class PEAR_XMLParser
+{
+    /**
+     * unserilialized data
+     * @var string $_serializedData
+     */
+    var $_unserializedData = null;
+
+    /**
+     * name of the root tag
+     * @var string $_root
+     */
+    var $_root = null;
+
+    /**
+     * stack for all data that is found
+     * @var array    $_dataStack
+     */
+    var $_dataStack = array();
+
+    /**
+     * stack for all values that are generated
+     * @var array    $_valStack
+     */
+    var $_valStack = array();
+
+    /**
+     * current tag depth
+     * @var int    $_depth
+     */
+    var $_depth = 0;
+
+    /**
+     * The XML encoding to use
+     * @var string $encoding
+     */
+    var $encoding = 'ISO-8859-1';
+
+    /**
+     * @return array
+     */
+    function getData()
+    {
+        return $this->_unserializedData;
+    }
+
+    /**
+     * @param string xml content
+     * @return true|PEAR_Error
+     */
+    function parse($data)
+    {
+        if (!extension_loaded('xml')) {
+            include_once 'PEAR.php';
+            return PEAR::raiseError("XML Extension not found", 1);
+        }
+        $this->_dataStack =  $this->_valStack = array();
+        $this->_depth = 0;
+
+        if (
+            strpos($data, 'encoding="UTF-8"')
+            || strpos($data, 'encoding="utf-8"')
+            || strpos($data, "encoding='UTF-8'")
+            || strpos($data, "encoding='utf-8'")
+        ) {
+            $this->encoding = 'UTF-8';
+        }
+
+        if (version_compare(phpversion(), '5.0.0', 'lt') && $this->encoding == 'UTF-8') {
+            $data = utf8_decode($data);
+            $this->encoding = 'ISO-8859-1';
+        }
+
+        $xp = xml_parser_create($this->encoding);
+        xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0);
+        xml_set_object($xp, $this);
+        xml_set_element_handler($xp, 'startHandler', 'endHandler');
+        xml_set_character_data_handler($xp, 'cdataHandler');
+        if (!xml_parse($xp, $data)) {
+            $msg = xml_error_string(xml_get_error_code($xp));
+            $line = xml_get_current_line_number($xp);
+            xml_parser_free($xp);
+            include_once 'PEAR.php';
+            return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2);
+        }
+        xml_parser_free($xp);
+        return true;
+    }
+
+    /**
+     * Start element handler for XML parser
+     *
+     * @access private
+     * @param  object $parser  XML parser object
+     * @param  string $element XML element
+     * @param  array  $attribs attributes of XML tag
+     * @return void
+     */
+    function startHandler($parser, $element, $attribs)
+    {
+        $this->_depth++;
+        $this->_dataStack[$this->_depth] = null;
+
+        $val = array(
+            'name'         => $element,
+            'value'        => null,
+            'type'         => 'string',
+            'childrenKeys' => array(),
+            'aggregKeys'   => array()
+       );
+
+        if (count($attribs) > 0) {
+            $val['children'] = array();
+            $val['type'] = 'array';
+            $val['children']['attribs'] = $attribs;
+        }
+
+        array_push($this->_valStack, $val);
+    }
+
+    /**
+     * post-process data
+     *
+     * @param string $data
+     * @param string $element element name
+     */
+    function postProcess($data, $element)
+    {
+        return trim($data);
+    }
+
+    /**
+     * End element handler for XML parser
+     *
+     * @access private
+     * @param  object XML parser object
+     * @param  string
+     * @return void
+     */
+    function endHandler($parser, $element)
+    {
+        $value = array_pop($this->_valStack);
+        $data  = $this->postProcess($this->_dataStack[$this->_depth], $element);
+
+        // adjust type of the value
+        switch (strtolower($value['type'])) {
+            // unserialize an array
+            case 'array':
+                if ($data !== '') {
+                    $value['children']['_content'] = $data;
+                }
+
+                $value['value'] = isset($value['children']) ? $value['children'] : array();
+                break;
+
+            /*
+             * unserialize a null value
+             */
+            case 'null':
+                $data = null;
+                break;
+
+            /*
+             * unserialize any scalar value
+             */
+            default:
+                settype($data, $value['type']);
+                $value['value'] = $data;
+                break;
+        }
+
+        $parent = array_pop($this->_valStack);
+        if ($parent === null) {
+            $this->_unserializedData = &$value['value'];
+            $this->_root = &$value['name'];
+            return true;
+        }
+
+        // parent has to be an array
+        if (!isset($parent['children']) || !is_array($parent['children'])) {
+            $parent['children'] = array();
+            if ($parent['type'] != 'array') {
+                $parent['type'] = 'array';
+            }
+        }
+
+        if (!empty($value['name'])) {
+            // there already has been a tag with this name
+            if (in_array($value['name'], $parent['childrenKeys'])) {
+                // no aggregate has been created for this tag
+                if (!in_array($value['name'], $parent['aggregKeys'])) {
+                    if (isset($parent['children'][$value['name']])) {
+                        $parent['children'][$value['name']] = array($parent['children'][$value['name']]);
+                    } else {
+                        $parent['children'][$value['name']] = array();
+                    }
+                    array_push($parent['aggregKeys'], $value['name']);
+                }
+                array_push($parent['children'][$value['name']], $value['value']);
+            } else {
+                $parent['children'][$value['name']] = &$value['value'];
+                array_push($parent['childrenKeys'], $value['name']);
+            }
+        } else {
+            array_push($parent['children'],$value['value']);
+        }
+        array_push($this->_valStack, $parent);
+
+        $this->_depth--;
+    }
+
+    /**
+     * Handler for character data
+     *
+     * @access private
+     * @param  object XML parser object
+     * @param  string CDATA
+     * @return void
+     */
+    function cdataHandler($parser, $cdata)
+    {
+        $this->_dataStack[$this->_depth] .= $cdata;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/PEAR5.php b/lib/php/PEAR5.php
new file mode 100644
index 00000000..42860678
--- /dev/null
+++ b/lib/php/PEAR5.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * This is only meant for PHP 5 to get rid of certain strict warning
+ * that doesn't get hidden since it's in the shutdown function
+ */
+class PEAR5
+{
+    /**
+    * If you have a class that's mostly/entirely static, and you need static
+    * properties, you can use this method to simulate them. Eg. in your method(s)
+    * do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar');
+    * You MUST use a reference, or they will not persist!
+    *
+    * @access public
+    * @param  string $class  The calling classname, to prevent clashes
+    * @param  string $var    The variable to retrieve.
+    * @return mixed   A reference to the variable. If not set it will be
+    *                 auto initialised to NULL.
+    */
+    static function &getStaticProperty($class, $var)
+    {
+        static $properties;
+        if (!isset($properties[$class])) {
+            $properties[$class] = array();
+        }
+
+        if (!array_key_exists($var, $properties[$class])) {
+            $properties[$class][$var] = null;
+        }
+
+        return $properties[$class][$var];
+    }
+}
\ No newline at end of file
diff --git a/lib/php/SimpleCAS.php b/lib/php/SimpleCAS.php
new file mode 100644
index 00000000..6de5c28d
--- /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 00000000..b26f5a07
--- /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 00000000..d050a6d4
--- /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 00000000..7879522f
--- /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 00000000..e32d665a
--- /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 00000000..225a759b
--- /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 00000000..3ab250ce
--- /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 00000000..e5560410
--- /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 00000000..b345c776
--- /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 00000000..1b0e97f4
--- /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/Structures/Graph.php b/lib/php/Structures/Graph.php
new file mode 100644
index 00000000..3757f158
--- /dev/null
+++ b/lib/php/Structures/Graph.php
@@ -0,0 +1,154 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+// +-----------------------------------------------------------------------------+
+// | Copyright (c) 2003 S�rgio Gon�alves Carvalho                                |
+// +-----------------------------------------------------------------------------+
+// | This file is part of Structures_Graph.                                      |
+// |                                                                             |
+// | Structures_Graph is free software; you can redistribute it and/or modify    |
+// | it under the terms of the GNU Lesser General Public License as published by |
+// | the Free Software Foundation; either version 2.1 of the License, or         |
+// | (at your option) any later version.                                         |
+// |                                                                             |
+// | Structures_Graph is distributed in the hope that it will be useful,         |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
+// | GNU Lesser General Public License for more details.                         |
+// |                                                                             |
+// | You should have received a copy of the GNU Lesser General Public License    |
+// | along with Structures_Graph; if not, write to the Free Software             |
+// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                    |
+// | 02111-1307 USA                                                              |
+// +-----------------------------------------------------------------------------+
+// | Author: S�rgio Carvalho <sergio.carvalho@portugalmail.com>                  |
+// +-----------------------------------------------------------------------------+
+//
+/**
+ * The Graph.php file contains the definition of the Structures_Graph class 
+ *
+ * @see Structures_Graph
+ * @package Structures_Graph
+ */
+
+/* dependencies {{{ */
+/** PEAR base classes */
+require_once 'PEAR.php';
+/** Graph Node */
+require_once 'Structures/Graph/Node.php';
+/* }}} */
+
+define('STRUCTURES_GRAPH_ERROR_GENERIC', 100);
+
+/* class Structures_Graph {{{ */
+/**
+ * The Structures_Graph class represents a graph data structure. 
+ *
+ * A Graph is a data structure composed by a set of nodes, connected by arcs.
+ * Graphs may either be directed or undirected. In a directed graph, arcs are 
+ * directional, and can be traveled only one way. In an undirected graph, arcs
+ * are bidirectional, and can be traveled both ways.
+ *
+ * @author		S�rgio Carvalho <sergio.carvalho@portugalmail.com> 
+ * @copyright	(c) 2004 by S�rgio Carvalho
+ * @package Structures_Graph
+ */
+/* }}} */
+class Structures_Graph {
+    /* fields {{{ */
+    /**
+     * @access private
+     */
+    var $_nodes = array();
+    /**
+     * @access private
+     */
+    var $_directed = false;
+    /* }}} */
+
+    /* Constructor {{{ */
+    /**
+    *
+    * Constructor
+    *
+    * @param    boolean    Set to true if the graph is directed. Set to false if it is not directed. (Optional, defaults to true)
+    * @access	public
+    */
+    function Structures_Graph($directed = true) {
+        $this->_directed = $directed;
+    }
+    /* }}} */
+
+    /* isDirected {{{ */
+    /**
+    *
+    * Return true if a graph is directed
+    *
+    * @return	boolean	 true if the graph is directed
+    * @access	public
+    */
+    function isDirected() {
+        return (boolean) $this->_directed;
+    }
+    /* }}} */
+
+    /* addNode {{{ */
+    /**
+    *
+    * Add a Node to the Graph
+    *
+    * @param    Structures_Graph_Node   The node to be added.
+    * @access	public
+    */
+    function addNode(&$newNode) {
+        // We only add nodes
+        if (!is_a($newNode, 'Structures_Graph_Node')) return Pear::raiseError('Structures_Graph::addNode received an object that is not a Structures_Graph_Node', STRUCTURES_GRAPH_ERROR_GENERIC);
+        // Graphs are node *sets*, so duplicates are forbidden. We allow nodes that are exactly equal, but disallow equal references.
+        foreach($this->_nodes as $key => $node) {
+            /*
+             ZE1 equality operators choke on the recursive cycle introduced by the _graph field in the Node object.
+             So, we'll check references the hard way (change $this->_nodes[$key] and check if the change reflects in 
+             $node)
+            */
+            $savedData = $this->_nodes[$key];
+            $referenceIsEqualFlag = false;
+            $this->_nodes[$key] = true;
+            if ($node === true) {
+                $this->_nodes[$key] = false;
+                if ($node === false) $referenceIsEqualFlag = true;
+            }
+            $this->_nodes[$key] = $savedData;
+            if ($referenceIsEqualFlag) return Pear::raiseError('Structures_Graph::addNode received an object that is a duplicate for this dataset', STRUCTURES_GRAPH_ERROR_GENERIC);
+        }
+        $this->_nodes[] =& $newNode;
+        $newNode->setGraph($this);
+    }
+    /* }}} */
+
+    /* removeNode (unimplemented) {{{ */
+    /**
+    *
+    * Remove a Node from the Graph
+    *
+    * @todo     This is unimplemented
+    * @param    Structures_Graph_Node   The node to be removed from the graph
+    * @access	public
+    */
+    function removeNode(&$node) {
+    }
+    /* }}} */
+
+    /* getNodes {{{ */
+    /**
+    *
+    * Return the node set, in no particular order. For ordered node sets, use a Graph Manipulator insted.
+    *
+    * @access   public
+    * @see      Structures_Graph_Manipulator_TopologicalSorter
+    * @return   array The set of nodes in this graph
+    */
+    function &getNodes() {
+        return $this->_nodes;
+    }
+    /* }}} */
+}
+?>
diff --git a/lib/php/Structures/Graph/Manipulator/AcyclicTest.php b/lib/php/Structures/Graph/Manipulator/AcyclicTest.php
new file mode 100644
index 00000000..fc1ba92f
--- /dev/null
+++ b/lib/php/Structures/Graph/Manipulator/AcyclicTest.php
@@ -0,0 +1,136 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+// +-----------------------------------------------------------------------------+
+// | Copyright (c) 2003 S�rgio Gon�alves Carvalho                                |
+// +-----------------------------------------------------------------------------+
+// | This file is part of Structures_Graph.                                      |
+// |                                                                             |
+// | Structures_Graph is free software; you can redistribute it and/or modify    |
+// | it under the terms of the GNU Lesser General Public License as published by |
+// | the Free Software Foundation; either version 2.1 of the License, or         |
+// | (at your option) any later version.                                         |
+// |                                                                             |
+// | Structures_Graph is distributed in the hope that it will be useful,         |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
+// | GNU Lesser General Public License for more details.                         |
+// |                                                                             |
+// | You should have received a copy of the GNU Lesser General Public License    |
+// | along with Structures_Graph; if not, write to the Free Software             |
+// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                    |
+// | 02111-1307 USA                                                              |
+// +-----------------------------------------------------------------------------+
+// | Author: S�rgio Carvalho <sergio.carvalho@portugalmail.com>                  |
+// +-----------------------------------------------------------------------------+
+//
+/**
+ * This file contains the definition of the Structures_Graph_Manipulator_AcyclicTest graph manipulator.
+ * 
+ * @see Structures_Graph_Manipulator_AcyclicTest
+ * @package Structures_Graph
+ */
+
+/* dependencies {{{ */
+/** */
+require_once 'PEAR.php';
+/** */
+require_once 'Structures/Graph.php';
+/** */
+require_once 'Structures/Graph/Node.php';
+/* }}} */
+
+/* class Structures_Graph_Manipulator_AcyclicTest {{{ */
+/**
+ * The Structures_Graph_Manipulator_AcyclicTest is a graph manipulator
+ * which tests whether a graph contains a cycle. 
+ * 
+ * The definition of an acyclic graph used in this manipulator is that of a 
+ * DAG. The graph must be directed, or else it is considered cyclic, even when 
+ * there are no arcs.
+ *
+ * @author		S�rgio Carvalho <sergio.carvalho@portugalmail.com> 
+ * @copyright	(c) 2004 by S�rgio Carvalho
+ * @package Structures_Graph
+ */
+class Structures_Graph_Manipulator_AcyclicTest {
+    /* _nonVisitedInDegree {{{ */
+    /**
+    *
+    * This is a variant of Structures_Graph::inDegree which does 
+    * not count nodes marked as visited.
+    *
+    * @access   private
+    * @return	integer	 Number of non-visited nodes that link to this one
+    */
+    function _nonVisitedInDegree(&$node) {
+        $result = 0;
+        $graphNodes =& $node->_graph->getNodes();
+        foreach (array_keys($graphNodes) as $key) {
+            if ((!$graphNodes[$key]->getMetadata('acyclic-test-visited')) && $graphNodes[$key]->connectsTo($node)) $result++;
+        }
+        return $result;
+        
+    }
+    /* }}} */
+
+    /* _isAcyclic {{{ */
+    /**
+    * @access   private
+    */
+    function _isAcyclic(&$graph) {
+        // Mark every node as not visited
+        $nodes =& $graph->getNodes();
+        $nodeKeys = array_keys($nodes);
+        $refGenerator = array();
+        foreach($nodeKeys as $key) {
+            $refGenerator[] = false;
+            $nodes[$key]->setMetadata('acyclic-test-visited', $refGenerator[sizeof($refGenerator) - 1]);
+        }
+
+        // Iteratively peel off leaf nodes
+        do {
+            // Find out which nodes are leafs (excluding visited nodes)
+            $leafNodes = array();
+            foreach($nodeKeys as $key) {
+                if ((!$nodes[$key]->getMetadata('acyclic-test-visited')) && Structures_Graph_Manipulator_AcyclicTest::_nonVisitedInDegree($nodes[$key]) == 0) {
+                    $leafNodes[] =& $nodes[$key];
+                }
+            }
+            // Mark leafs as visited
+            for ($i=sizeof($leafNodes) - 1; $i>=0; $i--) {
+                $visited =& $leafNodes[$i]->getMetadata('acyclic-test-visited');
+                $visited = true;
+                $leafNodes[$i]->setMetadata('acyclic-test-visited', $visited);
+            }
+        } while (sizeof($leafNodes) > 0);
+
+        // If graph is a DAG, there should be no non-visited nodes. Let's try to prove otherwise
+        $result = true;
+        foreach($nodeKeys as $key) if (!$nodes[$key]->getMetadata('acyclic-test-visited')) $result = false;
+        
+        // Cleanup visited marks
+        foreach($nodeKeys as $key) $nodes[$key]->unsetMetadata('acyclic-test-visited');
+
+        return $result;
+    }
+    /* }}} */
+
+    /* isAcyclic {{{ */
+    /**
+    *
+    * isAcyclic returns true if a graph contains no cycles, false otherwise.
+    *
+    * @return	boolean	 true iff graph is acyclic
+    * @access	public
+    */
+    function isAcyclic(&$graph) {
+        // We only test graphs
+        if (!is_a($graph, 'Structures_Graph')) return Pear::raiseError('Structures_Graph_Manipulator_AcyclicTest::isAcyclic received an object that is not a Structures_Graph', STRUCTURES_GRAPH_ERROR_GENERIC);
+        if (!$graph->isDirected()) return false; // Only directed graphs may be acyclic
+
+        return Structures_Graph_Manipulator_AcyclicTest::_isAcyclic($graph);
+    }
+    /* }}} */
+}
+/* }}} */
+?>
diff --git a/lib/php/Structures/Graph/Manipulator/TopologicalSorter.php b/lib/php/Structures/Graph/Manipulator/TopologicalSorter.php
new file mode 100644
index 00000000..98a9fa0b
--- /dev/null
+++ b/lib/php/Structures/Graph/Manipulator/TopologicalSorter.php
@@ -0,0 +1,153 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+// +-----------------------------------------------------------------------------+
+// | Copyright (c) 2003 S�rgio Gon�alves Carvalho                                |
+// +-----------------------------------------------------------------------------+
+// | This file is part of Structures_Graph.                                      |
+// |                                                                             |
+// | Structures_Graph is free software; you can redistribute it and/or modify    |
+// | it under the terms of the GNU Lesser General Public License as published by |
+// | the Free Software Foundation; either version 2.1 of the License, or         |
+// | (at your option) any later version.                                         |
+// |                                                                             |
+// | Structures_Graph is distributed in the hope that it will be useful,         |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
+// | GNU Lesser General Public License for more details.                         |
+// |                                                                             |
+// | You should have received a copy of the GNU Lesser General Public License    |
+// | along with Structures_Graph; if not, write to the Free Software             |
+// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                    |
+// | 02111-1307 USA                                                              |
+// +-----------------------------------------------------------------------------+
+// | Author: S�rgio Carvalho <sergio.carvalho@portugalmail.com>                  |
+// +-----------------------------------------------------------------------------+
+//
+/**
+ * This file contains the definition of the Structures_Graph_Manipulator_TopologicalSorter class.
+ * 
+ * @see Structures_Graph_Manipulator_TopologicalSorter
+ * @package Structures_Graph
+ */
+
+/* dependencies {{{ */
+/** */
+require_once 'PEAR.php';
+/** */
+require_once 'Structures/Graph.php';
+/** */
+require_once 'Structures/Graph/Node.php';
+/** */
+require_once 'Structures/Graph/Manipulator/AcyclicTest.php';
+/* }}} */
+
+/* class Structures_Graph_Manipulator_TopologicalSorter {{{ */
+/**
+ * The Structures_Graph_Manipulator_TopologicalSorter is a manipulator 
+ * which is able to return the set of nodes in a graph, sorted by topological 
+ * order.
+ *
+ * A graph may only be sorted topologically iff it's a DAG. You can test it
+ * with the Structures_Graph_Manipulator_AcyclicTest.
+ * 
+ * @author		S�rgio Carvalho <sergio.carvalho@portugalmail.com> 
+ * @copyright	(c) 2004 by S�rgio Carvalho
+ * @see     Structures_Graph_Manipulator_AcyclicTest
+ * @package Structures_Graph
+ */
+class Structures_Graph_Manipulator_TopologicalSorter {
+    /* _nonVisitedInDegree {{{ */
+    /**
+    *
+    * This is a variant of Structures_Graph::inDegree which does 
+    * not count nodes marked as visited.
+    *
+    * @access   private
+    * @return	integer	 Number of non-visited nodes that link to this one
+    */
+    function _nonVisitedInDegree(&$node) {
+        $result = 0;
+        $graphNodes =& $node->_graph->getNodes();
+        foreach (array_keys($graphNodes) as $key) {
+            if ((!$graphNodes[$key]->getMetadata('topological-sort-visited')) && $graphNodes[$key]->connectsTo($node)) $result++;
+        }
+        return $result;
+        
+    }
+    /* }}} */
+
+    /* _sort {{{ */
+    /**
+    * @access   private
+    */
+    function _sort(&$graph) {
+        // Mark every node as not visited
+        $nodes =& $graph->getNodes();
+        $nodeKeys = array_keys($nodes);
+        $refGenerator = array();
+        foreach($nodeKeys as $key) {
+            $refGenerator[] = false;
+            $nodes[$key]->setMetadata('topological-sort-visited', $refGenerator[sizeof($refGenerator) - 1]);
+        }
+
+        // Iteratively peel off leaf nodes
+        $topologicalLevel = 0;
+        do {
+            // Find out which nodes are leafs (excluding visited nodes)
+            $leafNodes = array();
+            foreach($nodeKeys as $key) {
+                if ((!$nodes[$key]->getMetadata('topological-sort-visited')) && Structures_Graph_Manipulator_TopologicalSorter::_nonVisitedInDegree($nodes[$key]) == 0) {
+                    $leafNodes[] =& $nodes[$key];
+                }
+            }
+            // Mark leafs as visited
+            $refGenerator[] = $topologicalLevel;
+            for ($i=sizeof($leafNodes) - 1; $i>=0; $i--) {
+                $visited =& $leafNodes[$i]->getMetadata('topological-sort-visited');
+                $visited = true;
+                $leafNodes[$i]->setMetadata('topological-sort-visited', $visited);
+                $leafNodes[$i]->setMetadata('topological-sort-level', $refGenerator[sizeof($refGenerator) - 1]);
+            }
+            $topologicalLevel++;
+        } while (sizeof($leafNodes) > 0);
+
+        // Cleanup visited marks
+        foreach($nodeKeys as $key) $nodes[$key]->unsetMetadata('topological-sort-visited');
+    }
+    /* }}} */
+
+    /* sort {{{ */
+    /**
+    *
+    * sort returns the graph's nodes, sorted by topological order. 
+    * 
+    * The result is an array with 
+    * as many entries as topological levels. Each entry in this array is an array of nodes within
+    * the given topological level.
+    *
+    * @return	array	 The graph's nodes, sorted by topological order.
+    * @access	public
+    */
+    function sort(&$graph) {
+        // We only sort graphs
+        if (!is_a($graph, 'Structures_Graph')) return Pear::raiseError('Structures_Graph_Manipulator_TopologicalSorter::sort received an object that is not a Structures_Graph', STRUCTURES_GRAPH_ERROR_GENERIC);
+        if (!Structures_Graph_Manipulator_AcyclicTest::isAcyclic($graph)) return Pear::raiseError('Structures_Graph_Manipulator_TopologicalSorter::sort received an graph that has cycles', STRUCTURES_GRAPH_ERROR_GENERIC);
+
+        Structures_Graph_Manipulator_TopologicalSorter::_sort($graph);
+        $result = array();
+
+        // Fill out result array
+        $nodes =& $graph->getNodes();
+        $nodeKeys = array_keys($nodes);
+        foreach($nodeKeys as $key) {
+            if (!array_key_exists($nodes[$key]->getMetadata('topological-sort-level'), $result)) $result[$nodes[$key]->getMetadata('topological-sort-level')] = array();
+            $result[$nodes[$key]->getMetadata('topological-sort-level')][] =& $nodes[$key];
+            $nodes[$key]->unsetMetadata('topological-sort-level');
+        }
+
+        return $result;
+    }
+    /* }}} */
+}
+/* }}} */
+?>
diff --git a/lib/php/Structures/Graph/Node.php b/lib/php/Structures/Graph/Node.php
new file mode 100644
index 00000000..a2ea415e
--- /dev/null
+++ b/lib/php/Structures/Graph/Node.php
@@ -0,0 +1,338 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+// +-----------------------------------------------------------------------------+
+// | Copyright (c) 2003 S�rgio Gon�alves Carvalho                                |
+// +-----------------------------------------------------------------------------+
+// | This file is part of Structures_Graph.                                      |
+// |                                                                             |
+// | Structures_Graph is free software; you can redistribute it and/or modify    |
+// | it under the terms of the GNU Lesser General Public License as published by |
+// | the Free Software Foundation; either version 2.1 of the License, or         |
+// | (at your option) any later version.                                         |
+// |                                                                             |
+// | Structures_Graph is distributed in the hope that it will be useful,         |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
+// | GNU Lesser General Public License for more details.                         |
+// |                                                                             |
+// | You should have received a copy of the GNU Lesser General Public License    |
+// | along with Structures_Graph; if not, write to the Free Software             |
+// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                    |
+// | 02111-1307 USA                                                              |
+// +-----------------------------------------------------------------------------+
+// | Author: S�rgio Carvalho <sergio.carvalho@portugalmail.com>                  |
+// +-----------------------------------------------------------------------------+
+//
+/**
+ * This file contains the definition of the Structures_Graph_Node class
+ * 
+ * @see Structures_Graph_Node
+ * @package Structures_Graph
+ */
+
+/* dependencies {{{ */
+/** */
+require_once 'PEAR.php';
+/** */
+require_once 'Structures/Graph.php';
+/* }}} */
+
+/* class Structures_Graph_Node {{{ */
+/**
+ * The Structures_Graph_Node class represents a Node that can be member of a 
+ * graph node set.
+ *
+ * A graph node can contain data. Under this API, the node contains default data, 
+ * and key index data. It behaves, thus, both as a regular data node, and as a 
+ * dictionary (or associative array) node.
+ * 
+ * Regular data is accessed via getData and setData. Key indexed data is accessed
+ * via getMetadata and setMetadata.
+ *
+ * @author		S�rgio Carvalho <sergio.carvalho@portugalmail.com> 
+ * @copyright	(c) 2004 by S�rgio Carvalho
+ * @package Structures_Graph
+ */
+/* }}} */
+class Structures_Graph_Node {
+    /* fields {{{ */
+    /** 
+     * @access private 
+     */
+    var $_data = null;
+    /** @access private */
+    var $_metadata = array();
+    /** @access private */
+    var $_arcs = array();
+    /** @access private */
+    var $_graph = null;
+    /* }}} */
+
+    /* Constructor {{{ */
+    /**
+    *
+    * Constructor
+    *
+    * @access	public
+    */
+    function Structures_Graph_Node() {
+    }
+    /* }}} */
+
+    /* getGraph {{{ */
+    /**
+    *
+    * Node graph getter
+    *
+    * @return	Structures_Graph	Graph where node is stored
+    * @access	public
+    */
+    function &getGraph() {
+        return $this->_graph;
+    }
+    /* }}} */
+
+    /* setGraph {{{ */
+    /**
+    *
+    * Node graph setter. This method should not be called directly. Use Graph::addNode instead.
+    *
+    * @param    Structures_Graph   Set the graph for this node. 
+    * @see      Structures_Graph::addNode()
+    * @access	public
+    */
+    function setGraph(&$graph) {
+        $this->_graph =& $graph;
+    }
+    /* }}} */
+
+    /* getData {{{ */
+    /**
+    *
+    * Node data getter.
+    * 
+    * Each graph node can contain a reference to one variable. This is the getter for that reference.
+    *
+    * @return	mixed	Data stored in node
+    * @access	public
+    */
+    function &getData() {
+        return $this->_data;
+    }
+    /* }}} */
+
+    /* setData {{{ */
+    /**
+    *
+    * Node data setter
+    *
+    * Each graph node can contain a reference to one variable. This is the setter for that reference.
+    *
+    * @return	mixed	Data to store in node
+    * @access	public
+    */
+    function setData($data) {
+        $this->_data =& $data;
+    }
+    /* }}} */
+
+    /* metadataKeyExists {{{ */
+    /**
+    *
+    * Test for existence of metadata under a given key.
+    *
+    * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an 
+    * associative array or in a dictionary. This method tests whether a given metadata key exists for this node.
+    *
+    * @param    string    Key to test
+    * @return	boolean	 
+    * @access	public
+    */
+    function metadataKeyExists($key) {
+        return array_key_exists($key, $this->_metadata);
+    }
+    /* }}} */
+
+    /* getMetadata {{{ */
+    /**
+    *
+    * Node metadata getter
+    *
+    * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an 
+    * associative array or in a dictionary. This method gets the data under the given key. If the key does
+    * not exist, an error will be thrown, so testing using metadataKeyExists might be needed.
+    *
+    * @param    string  Key
+    * @param    boolean nullIfNonexistent (defaults to false).
+    * @return	mixed	Metadata Data stored in node under given key
+    * @see      metadataKeyExists
+    * @access	public
+    */
+    function &getMetadata($key, $nullIfNonexistent = false) {
+        if (array_key_exists($key, $this->_metadata)) {
+            return $this->_metadata[$key];
+        } else {
+            if ($nullIfNonexistent) {
+                $a = null;
+                return $a;
+            } else {
+                $a = Pear::raiseError('Structures_Graph_Node::getMetadata: Requested key does not exist', STRUCTURES_GRAPH_ERROR_GENERIC);
+                return $a;
+            }
+        }
+    }
+    /* }}} */
+
+    /* unsetMetadata {{{ */
+    /**
+    *
+    * Delete metadata by key
+    *
+    * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an 
+    * associative array or in a dictionary. This method removes any data that might be stored under the provided key.
+    * If the key does not exist, no error is thrown, so it is safe using this method without testing for key existence.
+    *
+    * @param    string  Key
+    * @access	public
+    */
+    function unsetMetadata($key) {
+        if (array_key_exists($key, $this->_metadata)) unset($this->_metadata[$key]);
+    }
+    /* }}} */
+
+    /* setMetadata {{{ */
+    /**
+    *
+    * Node metadata setter
+    *
+    * Each graph node can contain multiple 'metadata' entries, each stored under a different key, as in an 
+    * associative array or in a dictionary. This method stores data under the given key. If the key already exists,
+    * previously stored data is discarded.
+    *
+    * @param    string  Key
+    * @param    mixed   Data 
+    * @access	public
+    */
+    function setMetadata($key, $data) {
+        $this->_metadata[$key] =& $data;
+    }
+    /* }}} */
+
+    /* _connectTo {{{ */
+    /** @access private */
+    function _connectTo(&$destinationNode) {
+        $this->_arcs[] =& $destinationNode;
+    }
+    /* }}} */
+
+    /* connectTo {{{ */
+    /**
+    *
+    * Connect this node to another one.
+    * 
+    * If the graph is not directed, the reverse arc, connecting $destinationNode to $this is also created.
+    *
+    * @param    Structures_Graph Node to connect to
+    * @access	public
+    */
+    function connectTo(&$destinationNode) {
+        // We only connect to nodes
+        if (!is_a($destinationNode, 'Structures_Graph_Node')) return Pear::raiseError('Structures_Graph_Node::connectTo received an object that is not a Structures_Graph_Node', STRUCTURES_GRAPH_ERROR_GENERIC);
+        // Nodes must already be in graphs to be connected
+        if ($this->_graph == null) return Pear::raiseError('Structures_Graph_Node::connectTo Tried to connect a node that is not in a graph', STRUCTURES_GRAPH_ERROR_GENERIC);
+        if ($destinationNode->getGraph() == null) return Pear::raiseError('Structures_Graph_Node::connectTo Tried to connect to a node that is not in a graph', STRUCTURES_GRAPH_ERROR_GENERIC);
+        // Connect here
+        $this->_connectTo($destinationNode);
+        // If graph is undirected, connect back
+        if (!$this->_graph->isDirected()) {
+            $destinationNode->_connectTo($this);
+        }
+    }
+    /* }}} */
+
+    /* getNeighbours {{{ */
+    /**
+    *
+    * Return nodes connected to this one.
+    * 
+    * @return   array   Array of nodes
+    * @access	public
+    */
+    function getNeighbours() {
+        return $this->_arcs;
+    }
+    /* }}} */
+
+    /* connectsTo {{{ */
+    /**
+    *
+    * Test wether this node has an arc to the target node
+    *
+    * @return	boolean   True if the two nodes are connected
+    * @access	public
+    */
+    function connectsTo(&$target) {
+        $copy = $target;
+        $arcKeys = array_keys($this->_arcs);
+        foreach($arcKeys as $key) {
+            /* ZE1 chokes on this expression:
+                if ($target === $arc) return true;
+              so, we'll use more convoluted stuff
+            */
+            $arc =& $this->_arcs[$key];
+            $target = true;
+            if ($arc === true) {
+                $target = false;
+                if ($arc === false) {
+                    $target = $copy;
+                    return true;
+                }
+            }
+        }
+        $target = $copy;
+        return false;
+    }
+    /* }}} */
+
+    /* inDegree {{{ */
+    /**
+    *
+    * Calculate the in degree of the node.
+    * 
+    * The indegree for a node is the number of arcs entering the node. For non directed graphs, 
+    * the indegree is equal to the outdegree.
+    *
+    * @return	integer	 In degree of the node
+    * @access	public
+    */
+    function inDegree() {
+        if ($this->_graph == null) return 0;
+        if (!$this->_graph->isDirected()) return $this->outDegree();
+        $result = 0;
+        $graphNodes =& $this->_graph->getNodes();
+        foreach (array_keys($graphNodes) as $key) {
+            if ($graphNodes[$key]->connectsTo($this)) $result++;
+        }
+        return $result;
+        
+    }
+    /* }}} */
+
+    /* outDegree {{{ */
+    /**
+    *
+    * Calculate the out degree of the node.
+    *
+    * The outdegree for a node is the number of arcs exiting the node. For non directed graphs,
+    * the outdegree is always equal to the indegree.
+    * 
+    * @return	integer	 Out degree of the node
+    * @access	public
+    */
+    function outDegree() {
+        if ($this->_graph == null) return 0;
+        return sizeof($this->_arcs);
+    }
+    /* }}} */
+}
+?>
diff --git a/lib/php/System.php b/lib/php/System.php
new file mode 100644
index 00000000..69cc7acb
--- /dev/null
+++ b/lib/php/System.php
@@ -0,0 +1,621 @@
+<?php
+/**
+ * File/Directory manipulation
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    System
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: System.php 276386 2009-02-24 23:52:56Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ * @since      File available since Release 0.1
+ */
+
+/**
+ * base class
+ */
+require_once 'PEAR.php';
+require_once 'Console/Getopt.php';
+
+$GLOBALS['_System_temp_files'] = array();
+
+/**
+* System offers cross plattform compatible system functions
+*
+* Static functions for different operations. Should work under
+* Unix and Windows. The names and usage has been taken from its respectively
+* GNU commands. The functions will return (bool) false on error and will
+* trigger the error with the PHP trigger_error() function (you can silence
+* the error by prefixing a '@' sign after the function call, but this
+* is not recommended practice.  Instead use an error handler with
+* {@link set_error_handler()}).
+*
+* Documentation on this class you can find in:
+* http://pear.php.net/manual/
+*
+* Example usage:
+* if (!@System::rm('-r file1 dir1')) {
+*    print "could not delete file1 or dir1";
+* }
+*
+* In case you need to to pass file names with spaces,
+* pass the params as an array:
+*
+* System::rm(array('-r', $file1, $dir1));
+*
+* @category   pear
+* @package    System
+* @author     Tomas V.V. Cox <cox@idecnet.com>
+* @copyright  1997-2006 The PHP Group
+* @license    http://opensource.org/licenses/bsd-license.php New BSD License
+* @version    Release: 1.9.0
+* @link       http://pear.php.net/package/PEAR
+* @since      Class available since Release 0.1
+* @static
+*/
+class System
+{
+    /**
+     * returns the commandline arguments of a function
+     *
+     * @param    string  $argv           the commandline
+     * @param    string  $short_options  the allowed option short-tags
+     * @param    string  $long_options   the allowed option long-tags
+     * @return   array   the given options and there values
+     * @static
+     * @access private
+     */
+    function _parseArgs($argv, $short_options, $long_options = null)
+    {
+        if (!is_array($argv) && $argv !== null) {
+            $argv = preg_split('/\s+/', $argv, -1, PREG_SPLIT_NO_EMPTY);
+        }
+        return Console_Getopt::getopt2($argv, $short_options);
+    }
+
+    /**
+     * Output errors with PHP trigger_error(). You can silence the errors
+     * with prefixing a "@" sign to the function call: @System::mkdir(..);
+     *
+     * @param mixed $error a PEAR error or a string with the error message
+     * @return bool false
+     * @static
+     * @access private
+     */
+    function raiseError($error)
+    {
+        if (PEAR::isError($error)) {
+            $error = $error->getMessage();
+        }
+        trigger_error($error, E_USER_WARNING);
+        return false;
+    }
+
+    /**
+     * Creates a nested array representing the structure of a directory
+     *
+     * System::_dirToStruct('dir1', 0) =>
+     *   Array
+     *    (
+     *    [dirs] => Array
+     *        (
+     *            [0] => dir1
+     *        )
+     *
+     *    [files] => Array
+     *        (
+     *            [0] => dir1/file2
+     *            [1] => dir1/file3
+     *        )
+     *    )
+     * @param    string  $sPath      Name of the directory
+     * @param    integer $maxinst    max. deep of the lookup
+     * @param    integer $aktinst    starting deep of the lookup
+     * @param    bool    $silent     if true, do not emit errors.
+     * @return   array   the structure of the dir
+     * @static
+     * @access   private
+     */
+    function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false)
+    {
+        $struct = array('dirs' => array(), 'files' => array());
+        if (($dir = @opendir($sPath)) === false) {
+            if (!$silent) {
+                System::raiseError("Could not open dir $sPath");
+            }
+            return $struct; // XXX could not open error
+        }
+
+        $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ?
+        $list = array();
+        while (false !== ($file = readdir($dir))) {
+            if ($file != '.' && $file != '..') {
+                $list[] = $file;
+            }
+        }
+
+        closedir($dir);
+        natsort($list);
+        if ($aktinst < $maxinst || $maxinst == 0) {
+            foreach ($list as $val) {
+                $path = $sPath . DIRECTORY_SEPARATOR . $val;
+                if (is_dir($path) && !is_link($path)) {
+                    $tmp    = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent);
+                    $struct = array_merge_recursive($struct, $tmp);
+                } else {
+                    $struct['files'][] = $path;
+                }
+            }
+        }
+
+        return $struct;
+    }
+
+    /**
+     * Creates a nested array representing the structure of a directory and files
+     *
+     * @param    array $files Array listing files and dirs
+     * @return   array
+     * @static
+     * @see System::_dirToStruct()
+     */
+    function _multipleToStruct($files)
+    {
+        $struct = array('dirs' => array(), 'files' => array());
+        settype($files, 'array');
+        foreach ($files as $file) {
+            if (is_dir($file) && !is_link($file)) {
+                $tmp    = System::_dirToStruct($file, 0);
+                $struct = array_merge_recursive($tmp, $struct);
+            } else {
+                if (!in_array($file, $struct['files'])) {
+                    $struct['files'][] = $file;
+                }
+            }
+        }
+        return $struct;
+    }
+
+    /**
+     * The rm command for removing files.
+     * Supports multiple files and dirs and also recursive deletes
+     *
+     * @param    string  $args   the arguments for rm
+     * @return   mixed   PEAR_Error or true for success
+     * @static
+     * @access   public
+     */
+    function rm($args)
+    {
+        $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-)
+        if (PEAR::isError($opts)) {
+            return System::raiseError($opts);
+        }
+        foreach ($opts[0] as $opt) {
+            if ($opt[0] == 'r') {
+                $do_recursive = true;
+            }
+        }
+        $ret = true;
+        if (isset($do_recursive)) {
+            $struct = System::_multipleToStruct($opts[1]);
+            foreach ($struct['files'] as $file) {
+                if (!@unlink($file)) {
+                    $ret = false;
+                }
+            }
+
+            rsort($struct['dirs']);
+            foreach ($struct['dirs'] as $dir) {
+                if (!@rmdir($dir)) {
+                    $ret = false;
+                }
+            }
+        } else {
+            foreach ($opts[1] as $file) {
+                $delete = (is_dir($file)) ? 'rmdir' : 'unlink';
+                if (!@$delete($file)) {
+                    $ret = false;
+                }
+            }
+        }
+        return $ret;
+    }
+
+    /**
+     * Make directories.
+     *
+     * The -p option will create parent directories
+     * @param    string  $args    the name of the director(y|ies) to create
+     * @return   bool    True for success
+     * @static
+     * @access   public
+     */
+    function mkDir($args)
+    {
+        $opts = System::_parseArgs($args, 'pm:');
+        if (PEAR::isError($opts)) {
+            return System::raiseError($opts);
+        }
+
+        $mode = 0777; // default mode
+        foreach ($opts[0] as $opt) {
+            if ($opt[0] == 'p') {
+                $create_parents = true;
+            } elseif ($opt[0] == 'm') {
+                // if the mode is clearly an octal number (starts with 0)
+                // convert it to decimal
+                if (strlen($opt[1]) && $opt[1]{0} == '0') {
+                    $opt[1] = octdec($opt[1]);
+                } else {
+                    // convert to int
+                    $opt[1] += 0;
+                }
+                $mode = $opt[1];
+            }
+        }
+
+        $ret = true;
+        if (isset($create_parents)) {
+            foreach ($opts[1] as $dir) {
+                $dirstack = array();
+                while ((!file_exists($dir) || !is_dir($dir)) &&
+                        $dir != DIRECTORY_SEPARATOR) {
+                    array_unshift($dirstack, $dir);
+                    $dir = dirname($dir);
+                }
+
+                while ($newdir = array_shift($dirstack)) {
+                    if (!is_writeable(dirname($newdir))) {
+                        $ret = false;
+                        break;
+                    }
+
+                    if (!mkdir($newdir, $mode)) {
+                        $ret = false;
+                    }
+                }
+            }
+        } else {
+            foreach($opts[1] as $dir) {
+                if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) {
+                    $ret = false;
+                }
+            }
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Concatenate files
+     *
+     * Usage:
+     * 1) $var = System::cat('sample.txt test.txt');
+     * 2) System::cat('sample.txt test.txt > final.txt');
+     * 3) System::cat('sample.txt test.txt >> final.txt');
+     *
+     * Note: as the class use fopen, urls should work also (test that)
+     *
+     * @param    string  $args   the arguments
+     * @return   boolean true on success
+     * @static
+     * @access   public
+     */
+    function &cat($args)
+    {
+        $ret = null;
+        $files = array();
+        if (!is_array($args)) {
+            $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
+        }
+
+        $count_args = count($args);
+        for ($i = 0; $i < $count_args; $i++) {
+            if ($args[$i] == '>') {
+                $mode = 'wb';
+                $outputfile = $args[$i+1];
+                break;
+            } elseif ($args[$i] == '>>') {
+                $mode = 'ab+';
+                $outputfile = $args[$i+1];
+                break;
+            } else {
+                $files[] = $args[$i];
+            }
+        }
+        $outputfd = false;
+        if (isset($mode)) {
+            if (!$outputfd = fopen($outputfile, $mode)) {
+                $err = System::raiseError("Could not open $outputfile");
+                return $err;
+            }
+            $ret = true;
+        }
+        foreach ($files as $file) {
+            if (!$fd = fopen($file, 'r')) {
+                System::raiseError("Could not open $file");
+                continue;
+            }
+            while ($cont = fread($fd, 2048)) {
+                if (is_resource($outputfd)) {
+                    fwrite($outputfd, $cont);
+                } else {
+                    $ret .= $cont;
+                }
+            }
+            fclose($fd);
+        }
+        if (is_resource($outputfd)) {
+            fclose($outputfd);
+        }
+        return $ret;
+    }
+
+    /**
+     * Creates temporary files or directories. This function will remove
+     * the created files when the scripts finish its execution.
+     *
+     * Usage:
+     *   1) $tempfile = System::mktemp("prefix");
+     *   2) $tempdir  = System::mktemp("-d prefix");
+     *   3) $tempfile = System::mktemp();
+     *   4) $tempfile = System::mktemp("-t /var/tmp prefix");
+     *
+     * prefix -> The string that will be prepended to the temp name
+     *           (defaults to "tmp").
+     * -d     -> A temporary dir will be created instead of a file.
+     * -t     -> The target dir where the temporary (file|dir) will be created. If
+     *           this param is missing by default the env vars TMP on Windows or
+     *           TMPDIR in Unix will be used. If these vars are also missing
+     *           c:\windows\temp or /tmp will be used.
+     *
+     * @param   string  $args  The arguments
+     * @return  mixed   the full path of the created (file|dir) or false
+     * @see System::tmpdir()
+     * @static
+     * @access  public
+     */
+    function mktemp($args = null)
+    {
+        static $first_time = true;
+        $opts = System::_parseArgs($args, 't:d');
+        if (PEAR::isError($opts)) {
+            return System::raiseError($opts);
+        }
+
+        foreach ($opts[0] as $opt) {
+            if ($opt[0] == 'd') {
+                $tmp_is_dir = true;
+            } elseif ($opt[0] == 't') {
+                $tmpdir = $opt[1];
+            }
+        }
+
+        $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
+        if (!isset($tmpdir)) {
+            $tmpdir = System::tmpdir();
+        }
+
+        if (!System::mkDir(array('-p', $tmpdir))) {
+            return false;
+        }
+
+        $tmp = tempnam($tmpdir, $prefix);
+        if (isset($tmp_is_dir)) {
+            unlink($tmp); // be careful possible race condition here
+            if (!mkdir($tmp, 0700)) {
+                return System::raiseError("Unable to create temporary directory $tmpdir");
+            }
+        }
+
+        $GLOBALS['_System_temp_files'][] = $tmp;
+        if (isset($tmp_is_dir)) {
+            //$GLOBALS['_System_temp_files'][] = dirname($tmp);
+        }
+
+        if ($first_time) {
+            PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
+            $first_time = false;
+        }
+
+        return $tmp;
+    }
+
+    /**
+     * Remove temporary files created my mkTemp. This function is executed
+     * at script shutdown time
+     *
+     * @static
+     * @access private
+     */
+    function _removeTmpFiles()
+    {
+        if (count($GLOBALS['_System_temp_files'])) {
+            $delete = $GLOBALS['_System_temp_files'];
+            array_unshift($delete, '-r');
+            System::rm($delete);
+            $GLOBALS['_System_temp_files'] = array();
+        }
+    }
+
+    /**
+     * Get the path of the temporal directory set in the system
+     * by looking in its environments variables.
+     * Note: php.ini-recommended removes the "E" from the variables_order setting,
+     * making unavaible the $_ENV array, that s why we do tests with _ENV
+     *
+     * @static
+     * @return string The temporary directory on the system
+     */
+    function tmpdir()
+    {
+        if (OS_WINDOWS) {
+            if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {
+                return $var;
+            }
+            if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {
+                return $var;
+            }
+            if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) {
+                return $var;
+            }
+            if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {
+                return $var;
+            }
+            return getenv('SystemRoot') . '\temp';
+        }
+        if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
+            return $var;
+        }
+        return realpath('/tmp');
+    }
+
+    /**
+     * The "which" command (show the full path of a command)
+     *
+     * @param string $program The command to search for
+     * @param mixed  $fallback Value to return if $program is not found
+     *
+     * @return mixed A string with the full path or false if not found
+     * @static
+     * @author Stig Bakken <ssb@php.net>
+     */
+    function which($program, $fallback = false)
+    {
+        // enforce API
+        if (!is_string($program) || '' == $program) {
+            return $fallback;
+        }
+
+        // full path given
+        if (basename($program) != $program) {
+            $path_elements[] = dirname($program);
+            $program = basename($program);
+        } else {
+            // Honor safe mode
+            if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) {
+                $path = getenv('PATH');
+                if (!$path) {
+                    $path = getenv('Path'); // some OSes are just stupid enough to do this
+                }
+            }
+            $path_elements = explode(PATH_SEPARATOR, $path);
+        }
+
+        if (OS_WINDOWS) {
+            $exe_suffixes = getenv('PATHEXT')
+                                ? explode(PATH_SEPARATOR, getenv('PATHEXT'))
+                                : array('.exe','.bat','.cmd','.com');
+            // allow passing a command.exe param
+            if (strpos($program, '.') !== false) {
+                array_unshift($exe_suffixes, '');
+            }
+            // is_executable() is not available on windows for PHP4
+            $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file';
+        } else {
+            $exe_suffixes = array('');
+            $pear_is_executable = 'is_executable';
+        }
+
+        foreach ($exe_suffixes as $suff) {
+            foreach ($path_elements as $dir) {
+                $file = $dir . DIRECTORY_SEPARATOR . $program . $suff;
+                if (@$pear_is_executable($file)) {
+                    return $file;
+                }
+            }
+        }
+        return $fallback;
+    }
+
+    /**
+     * The "find" command
+     *
+     * Usage:
+     *
+     * System::find($dir);
+     * System::find("$dir -type d");
+     * System::find("$dir -type f");
+     * System::find("$dir -name *.php");
+     * System::find("$dir -name *.php -name *.htm*");
+     * System::find("$dir -maxdepth 1");
+     *
+     * Params implmented:
+     * $dir            -> Start the search at this directory
+     * -type d         -> return only directories
+     * -type f         -> return only files
+     * -maxdepth <n>   -> max depth of recursion
+     * -name <pattern> -> search pattern (bash style). Multiple -name param allowed
+     *
+     * @param  mixed Either array or string with the command line
+     * @return array Array of found files
+     * @static
+     *
+     */
+    function find($args)
+    {
+        if (!is_array($args)) {
+            $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
+        }
+        $dir = realpath(array_shift($args));
+        if (!$dir) {
+            return array();
+        }
+        $patterns = array();
+        $depth = 0;
+        $do_files = $do_dirs = true;
+        $args_count = count($args);
+        for ($i = 0; $i < $args_count; $i++) {
+            switch ($args[$i]) {
+                case '-type':
+                    if (in_array($args[$i+1], array('d', 'f'))) {
+                        if ($args[$i+1] == 'd') {
+                            $do_files = false;
+                        } else {
+                            $do_dirs = false;
+                        }
+                    }
+                    $i++;
+                    break;
+                case '-name':
+                    $name = preg_quote($args[$i+1], '#');
+                    // our magic characters ? and * have just been escaped,
+                    // so now we change the escaped versions to PCRE operators
+                    $name = strtr($name, array('\?' => '.', '\*' => '.*'));
+                    $patterns[] = '('.$name.')';
+                    $i++;
+                    break;
+                case '-maxdepth':
+                    $depth = $args[$i+1];
+                    break;
+            }
+        }
+        $path = System::_dirToStruct($dir, $depth, 0, true);
+        if ($do_files && $do_dirs) {
+            $files = array_merge($path['files'], $path['dirs']);
+        } elseif ($do_dirs) {
+            $files = $path['dirs'];
+        } else {
+            $files = $path['files'];
+        }
+        if (count($patterns)) {
+            $dsq = preg_quote(DIRECTORY_SEPARATOR, '#');
+            $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#';
+            $ret = array();
+            $files_count = count($files);
+            for ($i = 0; $i < $files_count; $i++) {
+                // only search in the part of the file below the current directory
+                $filepart = basename($files[$i]);
+                if (preg_match($pattern, $filepart)) {
+                    $ret[] = $files[$i];
+                }
+            }
+            return $ret;
+        }
+        return $files;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/UNL/DWT.php b/lib/php/UNL/DWT.php
new file mode 100644
index 00000000..43aac0a3
--- /dev/null
+++ b/lib/php/UNL/DWT.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * This package is intended to create PHP Class files (Objects) from 
+ * Dreamweaver template (.dwt) files. It allows designers to create a
+ * standalone Dreamweaver template for the website design, and developers
+ * to use that design in php pages without interference.
+ *
+ * Similar to the way DB_DataObject works, the DWT package uses a 
+ * Generator to scan a .dwt file for editable regions and creates an 
+ * appropriately named class for that .dwt file with member variables for
+ * each region.
+ *
+ * Once the objects have been generated, you can render a html page from 
+ * the template.
+ * 
+ * $page = new UNL_DWT::factory('Template_style1');
+ * $page->pagetitle = "Contact Information";
+ * $page->maincontent = "Contact us by telephone at 111-222-3333.";
+ * echo $page->toHtml();
+ *
+ * Parts of this package are modeled on (borrowed from) the PEAR package 
+ * DB_DataObject.
+ * 
+ * PHP version 5
+ * 
+ * @category  Templates
+ * @package   UNL_DWT
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @created   01/18/2006
+ * @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_DWT
+ */
+
+/**
+ * Base class which understands Dreamweaver Templates.
+ * 
+ * @category  Templates
+ * @package   UNL_DWT
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @created   01/18/2006
+ * @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_DWT
+ */
+class UNL_DWT
+{
+    
+    public $__template;
+    
+    /**
+     * Run-time configuration options
+     *
+     * @var array
+     * @see UNL_DWT::setOption()
+     */
+    static public $options = array(
+        'debug' => 0,
+    );
+    
+    /**
+     * Constructor
+     */
+    function __construct()
+    {
+        
+    }
+    
+    /**
+     * Returns the given DWT with all regions replaced with their assigned
+     * content.
+     * 
+     * @return string
+     */
+    public function toHtml()
+    {
+        $options = &UNL_DWT::$options;
+        if (!isset($this->__template)) {
+            return '';
+        }
+        /*
+        More Options for this method:
+            Extend this to automatically generate the .tpl files and cache.
+            Check for a cached copy of the template file.
+            Connect to a template server and get the latest template copy.
+            
+            Ex: $p = file_get_contents("http://pear.unl.edu/UNL/Templates/server.php?template=".$this->__template);
+        */
+        $p = file_get_contents($options['tpl_location'].$this->__template);
+        
+        $regions = get_object_vars($this);
+        return $this->replaceRegions($p, $regions);
+    }
+    
+    /**
+    * Replaces region tags within a template file wth their contents.
+    * 
+    * @param string $p       Page with DW Region tags.
+    * @param array  $regions Associative array with content to replace.
+    * 
+    * @return string page with replaced regions
+    */
+    function replaceRegions($p, $regions)
+    {
+        UNL_DWT::debug('Replacing regions.', 'replaceRegions', 5);
+        foreach ($regions as $region=>$value) {
+            /* Replace the region with the replacement text */
+            if (strpos($p, "<!--"." TemplateBeginEditable name=\"{$region}\" -->")) {
+                $p = str_replace(UNL_DWT_between("<!--"." TemplateBeginEditable name=\"{$region}\" -->",
+                                    "<!--"." TemplateEndEditable -->", $p),
+                    $value, $p);
+                UNL_DWT::debug("$region is replaced with $value.",
+                               'replaceRegions', 5);
+            } elseif (strpos($p, "<!--"." InstanceBeginEditable name=\"{$region}\" -->")) {
+                $p = str_replace("<!--"." InstanceBeginEditable name=\"{$region}\" -->".
+                                    UNL_DWT_between("<!--"." InstanceBeginEditable name=\"{$region}\" -->", "<!--"." InstanceEndEditable -->", $p).
+                                    "<!--"." InstanceEndEditable -->", "<!--"." InstanceBeginEditable name=\"{$region}\" -->".$value."<!--"." InstanceEndEditable -->", $p);
+                UNL_DWT::debug("$region is replaced with $value.", 'replaceRegions', 5);
+            } else {
+                UNL_DWT::debug("Could not find region $region!", 'replaceRegions', 3);
+            }    
+        }
+        return $p;
+    }
+    
+    
+    /**
+    * Create a new UNL_DWT object for the specified layout type
+    *
+    * @param string $type     the template type (eg "fixed")
+    * @param array  $coptions an associative array of option names and values
+    *
+    * @return object  a new UNL_DWT.  A UNL_DWT_Error object on failure.
+    *
+    * @see UNL_DWT::setOption()
+    */
+    static function &factory($type, $coptions = false)
+    {
+        $options =& UNL_DWT::$options;
+        
+        include_once $options['class_location']."{$type}.php";
+        
+        if (!is_array($coptions)) {
+            $coptions = array();
+        }
+        
+        $classname = $options['class_prefix'].$type;
+        
+        if (!class_exists($classname)) {
+            throw new UNL_DWT_Exception("Unable to include the {$options['class_location']}{$type}.php file.");
+        }
+        
+        @$obj = new $classname;
+        
+        foreach ($coptions as $option => $value) {
+            $test = $obj->setOption($option, $value);
+        }
+        
+        return $obj;
+    }
+    
+    /**
+    * Sets options.
+    * 
+    * @param string $option Option to set
+    * @param mixed  $value  Value to set for this option
+    *
+    * @return void
+    */
+    function setOption($option, $value)
+    {
+        self::$options[$option] = $value;
+    }
+    
+    /* ----------------------- Debugger ------------------ */
+
+    /**
+     * Debugger. - use this in your extended classes to output debugging 
+     * information.
+     *
+     * Uses UNL_DWT::debugLevel(x) to turn it on
+     *
+     * @param string $message message to output
+     * @param string $logtype bold at start
+     * @param string $level   output level
+     * 
+     * @return   none
+     */
+    static function debug($message, $logtype = 0, $level = 1)
+    {
+        if (empty(self::$options['debug'])  || 
+            (is_numeric(self::$options['debug']) &&  self::$options['debug'] < $level)) {
+            return;
+        }
+        // this is a bit flaky due to php's wonderfull class passing around crap..
+        // but it's about as good as it gets..
+        $class = (isset($this) && ($this instanceof UNL_DWT)) ? get_class($this) : 'UNL_DWT';
+        
+        if (!is_string($message)) {
+            $message = print_r($message, true);
+        }
+        if (!is_numeric(self::$options['debug']) && is_callable(self::$options['debug'])) {
+            return call_user_func(self::$options['debug'], $class, $message, $logtype, $level);
+        }
+        
+        if (!ini_get('html_errors')) {
+            echo "$class   : $logtype       : $message\n";
+            flush();
+            return;
+        }
+        if (!is_string($message)) {
+            $message = print_r($message, true);
+        }
+        $colorize = ($logtype == 'ERROR') ? '<font color="red">' : '<font>';
+        echo "<code>{$colorize}<strong>$class: $logtype:</strong> ". nl2br(htmlspecialchars($message)) . "</font></code><br />\n";
+        flush();
+    }
+
+    /**
+     * sets and returns debug level
+     * eg. UNL_DWT::debugLevel(4);
+     *
+     * @param int $v level
+     * 
+     * @return void
+     */
+    function debugLevel($v = null)
+    {
+        if ($v !== null) {
+            $r = isset(self::$options['debug']) ? self::$options['debug'] : 0;
+            self::$options['debug']  = $v;
+            return $r;
+        }
+        return isset(self::$options['debug']) ? self::$options['debug'] : 0;
+    }
+
+}
+
+/**
+ * exception used by the UNL_DWT class
+ * 
+ * @category  Templates
+ * @package   UNL_DWT
+ * @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_DWT
+ */
+class UNL_DWT_Exception extends Exception
+{
+    
+}
+ 
+if (!function_exists('UNL_DWT_between')) {
+    /**
+     * Returns content between two strings
+     *
+     * @param string $start String which bounds the start
+     * @param string $end   end collecting content when you see this
+     * @param string $p     larger body of content to search
+     * 
+     * @return string
+     */
+    function UNL_DWT_between($start, $end, $p)
+    {
+        if (!empty($start) && strpos($p, $start)!=false) {
+            $p = substr($p, strpos($p, $start)+strlen($start));
+        }
+        if (strpos($p, $end)!=false) {
+            $p = substr($p, 0, strpos($p, $end));
+        }
+        return $p;
+    }
+}
\ No newline at end of file
diff --git a/lib/php/UNL/DWT/Generator.php b/lib/php/UNL/DWT/Generator.php
new file mode 100644
index 00000000..172ac6a8
--- /dev/null
+++ b/lib/php/UNL/DWT/Generator.php
@@ -0,0 +1,476 @@
+<?php
+/**
+ * The Generator is used to generate UNL_DWT classes and cached .tpl files from
+ * Dreamweaver Template files.
+ *
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_DWT
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @created   01/18/2006
+ * @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_DWT
+ */
+
+require_once 'UNL/DWT.php';
+require_once 'UNL/DWT/Region.php';
+
+/**
+ * The generator parses actual .dwt Dreamweaver Template files to create object relationship
+ * files which have member variables for editable regions within the dreamweaver templates.
+ * 
+ * @category  Templates
+ * @package   UNL_DWT
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @created   01/18/2006
+ * @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_DWT
+ */
+class UNL_DWT_Generator extends UNL_DWT
+{
+
+    /**
+     * Array of template names.
+     */
+    var $templates;
+    
+    /**
+     * Current template being output
+     */
+    var $template;
+    
+    /**
+     * Assoc array of template region names.
+     * $_regions[$template] = array();
+     */
+    var $_regions;
+    
+    /**
+     * class being extended (can be overridden by
+     * [UNL_DWT_Generator] extends=xxxx
+     *
+     * @var    string
+     * @access private
+     */
+    var $_extends = 'UNL_DWT';
+    
+    /**
+     * line to use for require_once 'UNL/DWT.php';
+     *
+     * @var    string
+     * @access private
+     */
+    var $_extendsFile = 'UNL/DWT.php';
+    
+    /**
+     * begins generation of template files
+     *
+     * @return void
+     */
+    function start()
+    {
+        $this->debugLevel(3);
+        $this->createTemplateList();
+        $this->generateTemplates();
+        $this->generateClasses();
+    }
+    
+    /**
+     * Generates .tpl files from .dwt
+     * 
+     * @return void
+     */
+    function generateTemplates()
+    {
+        $dwt_location = UNL_DWT::$options['dwt_location'];
+        if (!file_exists(UNL_DWT::$options['dwt_location'])) {
+            include_once 'System.php';
+            System::mkdir(array('-p', UNL_DWT::$options['dwt_location']));
+        }
+        if (!file_exists($options['tpl_location'])) {
+            include_once 'System.php';
+            System::mkdir(array('-p', UNL_DWT::$options['tpl_location']));
+        }
+        foreach ($this->templates as $this->template) {
+            $dwt = file_get_contents($dwt_location.$this->template);
+            $dwt = $this->scanRegions($dwt);
+            
+            $sanitizedName = $this->sanitizeTemplateName($this->template);
+            //Write out the .tpl file?
+            if (strpos(UNL_DWT::$options['tpl_location'], '%s') !== false) {
+                $outfilename = sprintf(UNL_DWT::$options['tpl_location'], $sanitizedName);
+            } else {
+                $outfilename = UNL_DWT::$options['tpl_location']."/{$sanitizedName}.tpl";
+            }
+            $this->debug("Writing {$sanitizedName} to {$outfilename}", 
+                         'generateTemplates');
+            $fh = fopen($outfilename, "w");
+            fputs($fh, $dwt);
+            fclose($fh);
+        }
+    }
+    
+    /**
+     * Create a list of dwts
+     * 
+     * @return void
+     */
+    function createTemplateList()
+    {
+        $this->templates = array();
+        
+        $dwt_location = UNL_DWT::$options['dwt_location'];
+        if (is_dir($dwt_location)) {
+            $handle = opendir($dwt_location);
+            while (false !== ($file = readdir($handle))) {
+                if (isset(UNL_DWT::$options['generator_include_regex']) &&
+                !preg_match(UNL_DWT::$options['generator_include_regex'], $file)) {
+                    continue;
+                } else if (isset(UNL_DWT::$options['generator_exclude_regex']) &&
+                preg_match(UNL_DWT::$options['generator_exclude_regex'], $file)) {
+                    continue;
+                }
+                if (substr($file, strlen($file)-4) == '.dwt') {
+                    $this->debug("Adding {$file} to the list of templates.",
+                                'createTemplateList');
+                    $this->templates[] = $file;
+                }
+            }
+        } else {
+            throw new UNL_DWT_Exception("dwt_location is incorrect\n");
+        }
+    }
+    
+    /**
+     * Generate the classes for templates in $this->templates
+     *
+     * @return void
+     */
+    function generateClasses()
+    {        
+        if ($extends = @UNL_DWT::$options['extends']) {
+            $this->_extends     = $extends;
+            $this->_extendsFile = UNL_DWT::$options['extends_location'];
+        }
+        
+        foreach ($this->templates as $this->template) {
+            $this->classname = $this->generateClassName($this->template);
+            if (strpos(UNL_DWT::$options['class_location'], '%s') !== false) {
+                $outfilename = sprintf(UNL_DWT::$options['class_location'],
+                                    sanitizeTemplateName($this->template));
+            } else {
+                $outfilename = UNL_DWT::$options['class_location']."/".$this->sanitizeTemplateName($this->template).".php";
+            }
+            $oldcontents = '';
+            if (file_exists($outfilename)) {
+                // file_get_contents???
+                $oldcontents = implode('', file($outfilename));
+            }
+            $out = $this->_generateClassTemplate($oldcontents);
+            $this->debug("Writing {$this->classname} to {$outfilename}", 
+                        'generateClasses');
+            $fh = fopen($outfilename, "w");
+            fputs($fh, $out);
+            fclose($fh);
+        }
+    }
+    
+    /**
+     * Generates the class name from a filename.
+     * 
+     * @param string $filename The filename of the template.
+     * 
+     * @return string Sanitized filename prefixed with the class_prefix
+     *                defined in the ini.
+     */
+    function generateClassName($filename)
+    {
+        if (!($class_prefix  = @UNL_DWT::$options['class_prefix'])) {
+            $class_prefix = '';
+        }
+        return $class_prefix.$this->sanitizeTemplateName($filename);;
+    }
+    
+    /**
+     * Cleans the template filename.
+     *
+     * @param string $filename Filename of the template
+     * 
+     * @return string Sanitized template name
+     */
+    function sanitizeTemplateName($filename)
+    {
+        return preg_replace('/[^A-Z0-9]/i', '_', 
+                        ucfirst(str_replace('.dwt', '', $filename)));
+    }
+    
+    /**
+     * Scans the .dwt for regions - all found are loaded into assoc array
+     * $this->_regions[$template].
+     *
+     * @param string $dwt Dreamweaver template file to scan.
+     * 
+     * @return string derived template file.
+     */
+    function scanRegions($dwt)
+    {
+
+        $this->_regions[$this->template] = array();
+        
+        $dwt = str_replace("\r", "\n", $dwt);
+        $dwt = preg_replace("/(\<\!-- InstanceBeginEditable name=\"([A-Za-z0-9]*)\" -->)/i", "\n\\0\n", $dwt);
+        $dwt = preg_replace("/(\<\!-- TemplateBeginEditable name=\"([A-Za-z0-9]*)\" -->)/i", "\n\\0\n", $dwt);
+        $dwt = preg_replace("/\<\!-- InstanceEndEditable -->/", "\n\\0\n", $dwt);
+        $dwt = preg_replace("/\<\!-- TemplateEndEditable -->/", "\n\\0\n", $dwt);
+        $dwt = explode("\n", $dwt);
+        
+        $newRegion = false;
+        $region    = new UNL_DWT_Region();
+        $this->debug("Checking {$this->template}", 'scanRegions', 0);
+        foreach ($dwt as $key=>$fileregion) {
+            $matches = array();
+            if (preg_match("/\<\!-- InstanceBeginEditable name=\"([A-Za-z0-9]*)\" -->/i", $fileregion, $matches)
+                || preg_match("/\<\!-- TemplateBeginEditable name=\"([A-Za-z0-9]*)\" -->/i", $fileregion, $matches)) {
+                if ($newRegion == true) {
+                    // Found a new nested region.
+                    // Remove the previous one.
+                    $dwt[$region->line] = str_replace(array("<!--"." InstanceBeginEditable name=\"{$region->name}\" -->"), '', $dwt[$region->line]);
+                }
+                $newRegion     = true;
+                $region        = new UNL_DWT_Region();
+                $region->name  = $matches[1];
+                $region->line  = $key;
+                $region->value = "";
+            } elseif ((preg_match("/\<\!-- InstanceEndEditable -->/i", $fileregion, $matches) || preg_match("/\<\!-- TemplateEndEditable -->/", $fileregion, $matches))) {
+                // Region is closing.
+                if ($newRegion===true) {
+                    $region->value = trim($region->value);
+                    if (strpos($region->value, "@@(\" \")@@") === false) {
+                        $this->_regions[$this->template][] = $region;
+                    } else {
+                        // Editable Region tags must be removed within .tpl
+                        unset($dwt[$region->line], $dwt[$key]);
+                    }
+                    $newRegion = false;
+                } else {
+                    // Remove the nested region closing tag.
+                    $dwt[$key] = str_replace("<!--"." InstanceEndEditable -->", '', $fileregion);
+                }
+            } else {
+                if ($newRegion===true) {
+                    // Add the value of this region.
+                    $region->value .= trim($fileregion)." ";
+                }
+            }
+        }
+        $dwt = implode("\n", $dwt);
+        $dwt = preg_replace("/<!--"." InstanceParam name=\"([\w]*)\" type=\"([\w]*)\" value=\"([\w]*)\" -->/", '', $dwt);
+        $dwt = str_replace(array(    "<!--"." TemplateBeginEditable ",
+                                    "<!--"." TemplateEndEditable -->",
+                                    "\n\n"),
+                            array(    "<!--"." InstanceBeginEditable ",
+                                    "<!--"." InstanceEndEditable -->",
+                                    "\n"), $dwt);
+        if (preg_match("<!--"." InstanceBegin template=\"([\/\w\d\.]+)\" codeOutsideHTMLIsLocked=\"([\w]+)\" -->", $dwt)) {
+            $dwt = preg_replace("/<!--"." InstanceBegin template=\"([\/\w\d\.]+)\" codeOutsideHTMLIsLocked=\"([\w]+)\" -->/", "<!--"." InstanceBegin template=\"/Templates/{$this->template}\" codeOutsideHTMLIsLocked=\"\\2\" -->", $dwt);
+        } else {
+            $dwt = preg_replace("/<html[^>]*>/", "\\0<!--"." InstanceBegin template=\"/Templates/{$this->template}\" codeOutsideHTMLIsLocked=\"false\" -->", $dwt);
+        }
+        $dwt = str_replace('@@(" ")@@', '', $dwt);
+        return $dwt;
+    }
+    
+    /**
+     * The template class geneation part - single file.
+     *
+     * @param string $input file to generate a class for.
+     * 
+     * @return  updated .php file
+     */
+    private function _generateClassTemplate($input = '')
+    {
+        // title = expand me!
+        $foot = "";
+        $head = "<?php\n/**\n * Template Definition for {$this->template}\n */\n";
+        // requires
+        $head .= "require_once '{$this->_extendsFile}';\n\n";
+        // add dummy class header in...
+        // class
+        $head .= "class {$this->classname} extends {$this->_extends} \n{";
+
+        $body  =  "\n    ###START_AUTOCODE\n";
+        $body .= "    /* the code below is auto generated do not remove the above tag */\n\n";
+        // table
+        $padding = (30 - strlen($this->template));
+        if ($padding < 2) {
+            $padding =2;
+        }
+        $p = str_repeat(' ', $padding);        
+        
+        $var   = (substr(phpversion(), 0, 1) > 4) ? 'public' : 'var';
+        $body .= "    {$var} \$__template = '".$this->sanitizeTemplateName($this->template).".tpl';  {$p}// template name\n";
+        
+        $regions = $this->_regions[$this->template];
+        
+        foreach ($regions as $t) {
+            if (!strlen(trim($t->name))) {
+                continue;
+            }
+            $padding = (30 - strlen($t->name));
+            if ($padding < 2) $padding =2;
+            $p = str_repeat(' ', $padding);
+            
+            $body .="    {$var} \${$t->name} = \"".addslashes($t->value)."\"; {$p}// {$t->type}({$t->len})  {$t->flags}\n";
+        }
+        
+        // simple creation tools ! (static stuff!)
+        $body .= "\n";
+        $body .= "    /* Static get */\n";
+        $body .= "    function staticGet(\$k,\$v=NULL) { return UNL_DWT::staticGet('{$this->classname}',\$k,\$v); }\n";
+        
+        // generate getter and setter methods
+        $body .= $this->_generateGetters($input);
+        $body .= $this->_generateSetters($input);
+        
+        $body .= "\n    /* the code above is auto generated do not remove the tag below */";
+        $body .= "\n    ###END_AUTOCODE\n";
+        
+        $foot .= "}\n";
+        $full  = $head . $body . $foot;
+        
+        if (!$input) {
+            return $full;
+        }
+        if (!preg_match('/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n)/s', $input)) {
+            return $full;
+        }
+        if (!preg_match('/(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s', $input)) {
+            return $full;
+        }
+        
+        $class_rewrite = 'UNL_DWT';
+        if (!($class_rewrite = @UNL_DWT::$options['generator_class_rewrite'])) {
+            $class_rewrite = 'UNL_DWT';
+        }
+        if ($class_rewrite == 'ANY') {
+            $class_rewrite = '[a-z_]+';
+        }
+        $input = preg_replace('/(\n|\r\n)class\s*[a-z0-9_]+\s*extends\s*' .$class_rewrite . '\s*\{(\n|\r\n)/si',
+                "\nclass {$this->classname} extends {$this->_extends} \n{\n",
+                $input);
+        
+        return preg_replace('/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n).*(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s',
+                            $body, $input);
+        
+    }
+    
+    /**
+    * Generate getter methods for class definition
+    *
+    * @param string $input Existing class contents
+    * 
+    * @return string
+    */
+    function _generateGetters($input)
+    {
+        $getters = '';
+
+        // only generate if option is set to true
+        if (empty(UNL_DWT::$options['generate_getters'])) {
+            return '';
+        }
+
+        /*
+         * remove auto-generated code from input to be able to check if
+         * the method exists outside of the auto-code
+         */
+        $input = preg_replace('/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n).*(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s', '', $input);
+
+        $getters .= "\n\n";
+        $regions  = $this->_regions[$this->table];
+
+        // loop through properties and create getter methods
+        foreach ($regions = $regions as $t) {
+
+            // build mehtod name
+            $methodName = 'get' . ucfirst($t->name);
+
+            if (!strlen(trim($t->name))
+                || preg_match("/function[\s]+[&]?$methodName\(/i", $input)) {
+                continue;
+            }
+
+            $getters .= "   /**\n";
+            $getters .= "    * Getter for \${$t->name}\n";
+            $getters .= "    *\n";
+            $getters .= (stristr($t->flags, 'multiple_key')) ? "    * @return   object\n"
+                                                             : "    * @return   {$t->type}\n";
+            $getters .= "    * @access   public\n";
+            $getters .= "    */\n";
+            $getters .= (substr(phpversion(), 0, 1) > 4) ? '    public '
+                                                       : '    ';
+            $getters .= "function $methodName() {\n";
+            $getters .= "        return \$this->{$t->name};\n";
+            $getters .= "    }\n\n";
+        }
+   
+        return $getters;
+    }
+
+    /**
+     * Generate setter methods for class definition
+     *
+     * @param string $input Existing class contents
+     * 
+     * @return string
+     */
+    function _generateSetters($input)
+    {
+
+        $setters = '';
+
+        // only generate if option is set to true
+        if (empty(UNL_DWT::$options['generate_setters'])) {
+            return '';
+        }
+
+        /*
+         * remove auto-generated code from input to be able to check if
+         * the method exists outside of the auto-code
+         */
+        $input = preg_replace('/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n).*(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s', '', $input);
+
+        $setters .= "\n";
+        $regions  = $this->_regions[$this->table];
+
+        // loop through properties and create setter methods
+        foreach ($regions = $regions as $t) {
+
+            // build mehtod name
+            $methodName = 'set' . ucfirst($t->name);
+
+            if (!strlen(trim($t->name))
+                || preg_match("/function[\s]+[&]?$methodName\(/i", $input)) {
+                continue;
+            }
+
+            $setters .= "   /**\n";
+            $setters .= "    * Setter for \${$t->name}\n";
+            $setters .= "    *\n";
+            $setters .= "    * @param    mixed   input value\n";
+            $setters .= "    * @access   public\n";
+            $setters .= "    */\n";
+            $setters .= (substr(phpversion(), 0, 1) > 4) ? '    public '
+                                                       : '    ';
+            $setters .= "function $methodName(\$value) {\n";
+            $setters .= "        \$this->{$t->name} = \$value;\n";
+            $setters .= "    }\n\n";
+        }
+        
+        return $setters;
+    } 
+
+}
diff --git a/lib/php/UNL/DWT/Region.php b/lib/php/UNL/DWT/Region.php
new file mode 100644
index 00000000..b0963a1d
--- /dev/null
+++ b/lib/php/UNL/DWT/Region.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Object representing a Dreamweaver template region
+ * 
+ * @category  Templates
+ * @package   UNL_DWT
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @created   01/18/2006
+ * @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_DWT
+ */
+class UNL_DWT_Region
+{
+    var $name;
+    var $type = 'string';
+    var $len;
+    var $line;
+    var $flags;
+    var $value;
+}
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/DWT/Scanner.php b/lib/php/UNL/DWT/Scanner.php
new file mode 100644
index 00000000..67b60600
--- /dev/null
+++ b/lib/php/UNL/DWT/Scanner.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * Handles scanning a dwt file for regions.
+ * 
+ * PHP version 5
+ * 
+ * @category  Templates
+ * @package   UNL_DWT
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @created   01/18/2006
+ * @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_DWT
+ */
+require_once 'UNL/DWT/Region.php';
+
+/**
+ * Will scan a dreamweaver templated file for regions and other relevant info.
+ *
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @created   01/18/2006
+ * @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_DWT
+ */
+class UNL_DWT_Scanner
+{
+    protected $_regions;
+    
+    /**
+     * The contents of the .dwt file you wish to scan.
+     *
+     * @param string $dwt Source of the .dwt file
+     */
+    function __construct($dwt)
+    {
+        $this->scanRegions($dwt);
+    }
+    
+    function scanRegions($dwt)
+    {
+        $this->_regions[] = array();
+        
+        $dwt = str_replace("\r", "\n", $dwt);
+        $dwt = preg_replace("/(\<\!-- InstanceBeginEditable name=\"([A-Za-z0-9]*)\" -->)/i", "\n\\0\n", $dwt);
+        $dwt = preg_replace("/(\<\!-- TemplateBeginEditable name=\"([A-Za-z0-9]*)\" -->)/i", "\n\\0\n", $dwt);
+        $dwt = preg_replace("/\<\!-- InstanceEndEditable -->/", "\n\\0\n", $dwt);
+        $dwt = preg_replace("/\<\!-- TemplateEndEditable -->/", "\n\\0\n", $dwt);
+        $dwt = explode("\n", $dwt);
+        
+        $newRegion = false;
+        $region    = new UNL_DWT_Region();
+        foreach ($dwt as $key=>$fileregion) {
+            $matches = array();
+            if (preg_match("/\<\!-- InstanceBeginEditable name=\"([A-Za-z0-9]*)\" -->/i", $fileregion, $matches)
+                || preg_match("/\<\!-- TemplateBeginEditable name=\"([A-Za-z0-9]*)\" -->/i", $fileregion, $matches)) {
+                if ($newRegion == true) {
+                    // Found a new nested region.
+                    // Remove the previous one.
+                    $dwt[$region->line] = str_replace(array("<!--"." InstanceBeginEditable name=\"{$region->name}\" -->"), '', $dwt[$region->line]);
+                }
+                $newRegion     = true;
+                $region        = new UNL_DWT_Region();
+                $region->name  = $matches[1];
+                $region->line  = $key;
+                $region->value = "";
+            } elseif ((preg_match("/\<\!-- InstanceEndEditable -->/i", $fileregion, $matches) || preg_match("/\<\!-- TemplateEndEditable -->/", $fileregion, $matches))) {
+                // Region is closing.
+                if ($newRegion===true) {
+                    $region->value = trim($region->value);
+                    if (strpos($region->value, "@@(\" \")@@") === false) {
+                        $this->_regions[$region->name] = $region;
+                    } else {
+                        // Editable Region tags must be removed within .tpl
+                        unset($dwt[$region->line], $dwt[$key]);
+                    }
+                    $newRegion = false;
+                } else {
+                    // Remove the nested region closing tag.
+                    $dwt[$key] = str_replace("<!--"." InstanceEndEditable -->", '', $fileregion);
+                }
+            } else {
+                if ($newRegion===true) {
+                    // Add the value of this region.
+                    $region->value .= trim($fileregion)." ";
+                }
+            }
+        }
+    }
+    
+    /**
+     * returns the region object
+     *
+     * @param string $region
+     * 
+     * @return UNL_DWT_Region
+     */
+    public function getRegion($region)
+    {
+        if (isset($this->_regions[$region])) {
+            return $this->_regions[$region];
+        }
+        return null;
+    }
+    
+    /**
+     * returns array of all the regions found
+     *
+     * @return array(UNL_DWT_Region)
+     */
+    public function getRegions()
+    {
+        return $this->_regions;
+    }
+    
+    public function __isset($region)
+    {
+        return isset($this->_regions[$region]);
+    }
+    
+    public function __get($region)
+    {
+        if (isset($this->_regions[$region])) {
+            return $this->_regions[$region]->value;
+        }
+        
+        $trace = debug_backtrace();
+        trigger_error(
+            'Undefined property: ' . $region .
+            ' in ' . $trace[0]['file'] .
+            ' on line ' . $trace[0]['line'],
+            E_USER_NOTICE);
+        return null;
+    }
+    
+}
+
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/DWT/createTemplates.php b/lib/php/UNL/DWT/createTemplates.php
new file mode 100644
index 00000000..df87cc25
--- /dev/null
+++ b/lib/php/UNL/DWT/createTemplates.php
@@ -0,0 +1,44 @@
+#!/usr/bin/php -q
+<?php
+/**
+ * Tool to generate objects for dreamweaver template files.
+ * 
+ * PHP version 5
+ *  
+ * @package   UNL_DWT
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @created   01/18/2006
+ * @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_DWT
+ */
+
+// since this version doesnt use overload, 
+// and I assume anyone using custom generators should add this..
+define('UNL_DWT_NO_OVERLOAD',1);
+ini_set('display_errors',true);
+require_once 'UNL/DWT/Generator.php';
+
+if (!ini_get('register_argc_argv')) {
+    throw new Exception("\nERROR: You must turn register_argc_argv On in your php.ini file for this to work\neg.\n\nregister_argc_argv = On\n\n");
+}
+
+if (!@$_SERVER['argv'][1]) {
+    throw new Exception("\nERROR: createTemplates.php usage:\n\nC:\php\pear\UNL\DWT\createTemplates.php example.ini\n\n");
+}
+
+$config = parse_ini_file($_SERVER['argv'][1], true);
+foreach($config as $class=>$values) {
+    if ($class == 'UNL_DWT') {
+        UNL_DWT::$options = $values;
+    }
+}
+
+if (empty(UNL_DWT::$options)) {
+    throw new Exception("\nERROR: could not read ini file\n\n");
+}
+set_time_limit(0);
+//UNL_DWT::debugLevel(1);
+$generator = new UNL_DWT_Generator;
+$generator->start();
+ 
diff --git a/lib/php/UNL/Peoplefinder.php b/lib/php/UNL/Peoplefinder.php
new file mode 100644
index 00000000..fd48eed6
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Peoplefinder class for UNL's online directory.
+ * 
+ * PHP version 5
+ * 
+ * @category  Services
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+define('UNL_PF_DISPLAY_LIMIT', 30);
+define('UNL_PF_RESULT_LIMIT', 100);
+
+/**
+ * Peoplefinder class for UNL's online directory.
+ * 
+ * PHP version 5
+ * 
+ * @category  Services
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+class UNL_Peoplefinder
+{
+    static public $resultLimit        = UNL_PF_RESULT_LIMIT;
+    static public $displayResultLimit = UNL_PF_DISPLAY_LIMIT;
+
+    /**
+     * Driver for data retrieval
+     *
+     * @var UNL_Peoplefinder_DriverInterface
+     */
+    public $driver;
+
+    /**
+     * Constructor for the object.
+     */
+    function __construct(UNL_Peoplefinder_DriverInterface $driver = null)
+    {
+        if (!$driver) {
+            $driver = new UNL_Peoplefinder_Driver_WebService();
+        }
+        $this->driver = $driver;
+    }
+
+    function __call($method, $args)
+    {
+        return call_user_func_array(array($this->driver, $method), $args);
+    }
+
+}
diff --git a/lib/php/UNL/Peoplefinder/Department.php b/lib/php/UNL/Peoplefinder/Department.php
new file mode 100644
index 00000000..4400e63a
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Department.php
@@ -0,0 +1,174 @@
+<?php
+require_once 'UNL/LDAP.php';
+/**
+ * Class which represents a department.
+ * 
+ * The departments are pulled from an xml file, generated from SAP data.
+ * hr_tree.xml using TreeML schema
+ * 
+ * The object also allows iterating over all the members of the department.
+ */
+class UNL_Peoplefinder_Department implements Countable, Iterator
+{
+    /**
+     * Name of the organization
+     *
+     * @var string
+     */
+    public $name;
+    
+    /**
+     * The organizational unit number.
+     *
+     * @var number
+     */
+    public $org_unit;
+    
+    /**
+     * Building the department main office is in.
+     *
+     * @var string
+     */
+    public $building;
+    
+    /**
+     * Room
+     *
+     * @var string
+     */
+    public $room;
+    
+    /**
+     * City
+     *
+     * @var string
+     */
+    public $city;
+    
+    /**
+     * State
+     *
+     * @var string
+     */
+    public $state;
+    
+    /**
+     * zip code
+     *
+     * @var string
+     */
+    public $postal_code;
+    
+    protected $_ldap;
+
+    protected $_results;
+    
+    protected $_xml;
+    
+    /**
+     * construct a department
+     *
+     * @param string $name Name of the department
+     */
+    function __construct($name)
+    {
+        $this->name = $name;
+        $this->_xml = new SimpleXMLElement(file_get_contents(dirname(__FILE__).'/../../data/hr_tree.xml'));
+        $results = $this->_xml->xpath('//attribute[@name="org_unit"][@value="50000003"]/..//attribute[@name="name"][@value="'.$this->name.'"]/..');
+        if (isset($results[0])) {
+            foreach ($results[0] as $attribute) {
+                if (isset($attribute['name'])) {
+                    $this->{$attribute['name']} = (string)$attribute['value'];
+                }
+            }
+        } else {
+            throw new Exception('Invalid department name.');
+        }
+    }
+    
+    /**
+     * Retrieves people records from the LDAP directory
+     *
+     * @return resource
+     */
+    function getLDAPResults()
+    {
+        if (!isset($this->_results)) {
+            $options = array(
+                'bind_dn'       => UNL_Peoplefinder_Driver_LDAP::$bindDN,
+                'bind_password' => UNL_Peoplefinder_Driver_LDAP::$bindPW,
+                );
+            
+            $this->_ldap = UNL_LDAP::getConnection($options);
+            $name = str_replace(array('(',')','*','\'','"'), '', $this->name);
+            $this->_results =  $this->_ldap->search('dc=unl,dc=edu',
+                                                    '(unlHRPrimaryDepartment='.$name.')');
+            $this->_results->sort('cn');
+            $this->_results->sort('sn');
+        }
+        return $this->_results;
+    }
+    
+    /**
+     * returns the count of employees
+     *
+     * @return int
+     */
+    function count()
+    {
+        return count($this->getLDAPResults());
+    }
+    
+    function rewind()
+    {
+        $this->getLDAPResults()->rewind();
+    }
+    
+    /**
+     * Get the current record in the iteration
+     *
+     * @return UNL_Peoplefinder_Record
+     */
+    function current()
+    {
+        return UNL_Peoplefinder_Record::fromUNLLDAPEntry($this->getLDAPResults()->current());
+    }
+    
+    function key()
+    {
+        return $this->getLDAPResults()->key();
+    }
+    
+    function next()
+    {
+        $this->getLDAPResults()->next();
+    }
+    
+    function valid()
+    {
+        return $this->getLDAPResults()->valid();
+    }
+    
+    function hasChildren()
+    {
+        $results = $this->_xml->xpath('//attribute[@name="org_unit"][@value="50000003"]/..//attribute[@name="name"][@value="'.$this->name.'"]/../branch');
+        return count($results)?true:false;
+    }
+    
+    function getChildren()
+    {
+        $children = array();
+        $results = $this->_xml->xpath('//attribute[@name="org_unit"][@value="50000003"]/..//attribute[@name="name"][@value="'.$this->name.'"]/../branch');
+        foreach ($results as $result) {
+            foreach ($result[0] as $attribute) {
+                if (isset($attribute['name'])
+                    && $attribute['name']=='name') {
+                    $children[] = (string)$attribute['value'];
+                    break;
+                }
+            }
+        }
+        asort($children);
+        return $children;
+    }
+}
diff --git a/lib/php/UNL/Peoplefinder/Department/Search.php b/lib/php/UNL/Peoplefinder/Department/Search.php
new file mode 100644
index 00000000..58648ae9
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Department/Search.php
@@ -0,0 +1,57 @@
+<?php
+class UNL_Peoplefinder_Department_Search implements Countable, Iterator
+{
+    public $q;
+    
+    /**
+     * SimpleXMLElement for the HR XML Tree
+     * 
+     * @var SimpleXMLElement
+     */
+    protected $xml;
+    
+    protected $results;
+    
+    protected $current = 0;
+    
+    function __construct($q)
+    {
+        $q = strtolower(str_replace('"', '', $q));
+        $this->xml = new SimpleXMLElement(file_get_contents(dirname(__FILE__).'/../../../data/hr_tree.xml'));
+        $this->results = $this->xml->xpath('//attribute[@name="org_unit"][@value="50000003"]/..//attribute[@name="name"][contains(translate(@value,"ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"),"'.$q.'")]');
+    }
+    
+    function current()
+    {
+        return new UNL_Peoplefinder_Department($this->results[$this->current]['value']);
+    }
+    
+    function next()
+    {
+        $this->current++;
+    }
+    
+    function valid()
+    {
+        if ($this->current < count($this->results)) {
+            return true;
+        }
+        return false;
+    }
+    
+    function count()
+    {
+        return count($this->results);
+    }
+    
+    function rewind()
+    {
+        $this->current = 0;
+    }
+    
+    function key()
+    {
+        return $this->current()->name;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Peoplefinder/Driver/LDAP.php b/lib/php/UNL/Peoplefinder/Driver/LDAP.php
new file mode 100644
index 00000000..fc5928f7
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Driver/LDAP.php
@@ -0,0 +1,275 @@
+<?php
+class UNL_Peoplefinder_Driver_LDAP implements UNL_Peoplefinder_DriverInterface
+{
+    /**
+     * Connection credentials
+     * 
+     * @param string
+     */
+    static public $ldapServer = 'ldap.unl.edu ldap-backup.unl.edu';
+    
+    /**
+     * LDAP Connection bind distinguised name
+     *
+     * @var string
+     * @ignore
+     */
+    static public $bindDN = 'uid=insertyouruidhere,ou=service,dc=unl,dc=edu';
+    
+    /**
+     * LDAP connection password.
+     *
+     * @var string
+     * @ignore
+     */
+    static public $bindPW             = 'putyourpasswordhere';
+    static public $baseDN             = 'dc=unl,dc=edu';
+    static public $ldapTimeout        = 10;
+    
+    /**
+     * Attribute arrays
+     * Attributes are the fields retrieved in an LDAP QUERY, limit this to
+     * ONLY what is USED/DISPLAYED!
+     */
+    
+    /**
+     * List attributes are the attributes displayed in a list of results
+     * 
+     * @var array
+     */
+    public $listAttributes = array(
+        'cn',
+        'eduPersonNickname',
+        'eduPersonPrimaryAffiliation',
+        'givenName',
+        'sn',
+        'telephoneNumber',
+        'uid',
+        'unlHRPrimaryDepartment');
+    
+    /**
+     * Details are for UID detail display only.
+     * @var array
+     */
+    public $detailAttributes = array(
+        'ou',
+        'cn',
+        'eduPersonNickname',
+        'eduPersonPrimaryAffiliation',
+        'givenName',
+        'displayName',
+        'mail',
+        'postalAddress',
+        'sn',
+        'telephoneNumber',
+        'title',
+        'uid',
+        'unlHRPrimaryDepartment',
+        'unlHRAddress',
+        'unlSISClassLevel',
+        'unlSISCollege',
+        'unlSISLocalAddr1',
+        'unlSISLocalAddr2',
+        'unlSISLocalCity',
+        'unlSISLocalState',
+        'unlSISLocalZip',
+        'unlSISPermAddr1',
+        'unlSISPermAddr2',
+        'unlSISPermCity',
+        'unlSISPermState',
+        'unlSISPermZip',
+        'unlSISMajor',
+        'unlEmailAlias');
+    
+    /** Connection details */
+    public $connected = false;
+    public $linkID;
+
+    /** Result Info */
+    public $lastQuery;
+    public $lastResult;
+    public $lastResultCount = 0;
+    
+    function __construct()
+    {
+        
+    }
+    
+    /**
+     * Binds to the LDAP directory using the bind credentials stored in
+     * bindDN and bindPW
+     *
+     * @return bool
+     */
+    function bind()
+    {
+        $this->linkID = ldap_connect(self::$ldapServer);
+        if ($this->linkID) {
+            $this->connected = ldap_bind($this->linkID,
+                                         self::$bindDN,
+                                         self::$bindPW);
+            if ($this->connected) {
+                return $this->connected;
+            }
+        }
+        throw new Exception('Cound not connect to LDAP directory.');
+    }
+    
+    /**
+     * Disconnect from the ldap directory.
+     *
+     * @return unknown
+     */
+    function unbind()
+    {
+        $this->connected = false;
+        return ldap_unbind($this->linkID);
+    }
+    
+    /**
+     * Send a query to the ldap directory
+     *
+     * @param string $filter     LDAP filter (uid=blah)
+     * @param array  $attributes attributes to return for the entries
+     * @param bool   $setResult  whether or not to set the last result
+     * 
+     * @return mixed
+     */
+    function query($filter,$attributes,$setResult=true)
+    {
+        $this->bind();
+        $this->lastQuery = $filter;
+        $sr              = @ldap_search($this->linkID, 
+                                        self::$baseDN,
+                                        $filter,
+                                        $attributes,
+                                        0,
+                                        UNL_Peoplefinder::$resultLimit,
+                                        self::$ldapTimeout);
+        if ($setResult) {
+            $this->lastResultCount = @ldap_count_entries($this->linkID, $sr);
+            $this->lastResult      = @ldap_get_entries($this->linkID, $sr);
+            $this->unbind();
+            //sort the results
+            for ($i=0;$i<$this->lastResult['count'];$i++) {
+                if (isset($this->lastResult[$i]['givenname'])) {
+                    $name = $this->lastResult[$i]['sn'][0]
+                          . ', '
+                          . $this->lastResult[$i]['givenname'][0];
+                } else {
+                    $name = $this->lastResult[$i]['sn'][0];
+                }
+                $this->lastResult[$i]['insensitiveName'] = strtoupper($name);
+            }
+            @reset($this->lastResult);
+            $this->lastResult = @UNL_Peoplefinder_Driver_LDAP_Util::array_csort(
+                                                    $this->lastResult,
+                                                    'insensitiveName',
+                                                    SORT_ASC);
+            return $this->lastResult;
+        } else {
+            $result = ldap_get_entries($this->linkID, $sr);
+            $this->unbind();
+            return $result;
+        }
+    }
+
+    
+    /**
+     * Get records which match the query exactly.
+     *
+     * @param string $q Search string.
+     * 
+     * @return array(UNL_Peoplefinder_Record)
+     */
+    public function getExactMatches($q)
+    {
+        $filter = new UNL_Peoplefinder_Driver_LDAP_StandardFilter($q, '&', false);
+        $this->query($filter->__toString(), $this->detailAttributes);
+        return $this->getRecordsFromResults();
+    }
+    
+    /**
+     * Returns an array of UNL_Peoplefinder_Record objects from the ldap
+     * query result.
+     *
+     * @return array(UNL_Peoplefinder_Record)
+     */
+    protected function getRecordsFromResults()
+    {
+        $r = array();
+        if ($this->lastResultCount > 0) {
+            for ($i = 0; $i < $this->lastResultCount; $i++) {
+                $r[] = UNL_Peoplefinder_Record::fromLDAPEntry($this->lastResult[$i]);
+            }
+        }
+        return $r;
+    }
+    
+    /**
+     * Get results for an advanced/detailed search.
+     *
+     * @param string $sn   Surname/last name
+     * @param string $cn   Common name/first name
+     * @param string $eppa Primary Affiliation
+     * 
+     * @return array(UNL_Peoplefinder_Record)
+     */
+    public function getAdvancedSearchMatches($sn, $cn, $eppa)
+    {
+        $filter = new UNL_Peoplefinder_Driver_LDAP_AdvancedFilter($sn, $cn, $eppa, '&', true);
+        $this->query($filter->__toString(), $this->detailAttributes);
+        return $this->getRecordsFromResults();
+    }
+    
+    /**
+     * Find matches similar to the query given
+     *
+     * @param string $q                Search query
+     * @param array  $excluded_records Array of records to exclude.
+     * 
+     * @return array(UNL_Peoplefinder_Record)
+     */
+    public function getLikeMatches($q, $excluded_records = array())
+    {
+        // Build filter excluding those displayed above
+        $filter = new UNL_Peoplefinder_Driver_LDAP_StandardFilter($q, '&', true);
+        $filter->excludeRecords($excluded_records);
+        $this->query($filter->__toString(), $this->detailAttributes);
+        return $this->getRecordsFromResults();
+    }
+    
+    /**
+     * Get an array of records which matche by the phone number.
+     *
+     * @param string $q EG: 472-1598
+     * 
+     * @return array(UNL_Peoplefinder_Record)
+     */
+    public function getPhoneMatches($q)
+    {
+        $filter = new UNL_Peoplefinder_Driver_LDAP_TelephoneFilter($q);
+        $this->query($filter->__toString(), $this->detailAttributes);
+        return $this->getRecordsFromResults();
+    }
+
+    /**
+     * Get the ldap record for a specific uid eg:bbieber2
+     *
+     * @param string $uid The unique ID for the user you want to get.
+     * 
+     * @return UNL_Peoplefinder_Record
+     */
+    function getUID($uid)
+    {
+        $r = $this->query("(&(uid=$uid))", $this->detailAttributes, false);
+        if (isset($r[0])) {
+            return UNL_Peoplefinder_Record::fromLDAPEntry($r[0]);
+        } else {
+            header('HTTP/1.0 404 Not Found');
+            throw new Exception('Cannot find that UID.');
+        }
+    }
+    
+    
+}
diff --git a/lib/php/UNL/Peoplefinder/Driver/LDAP/AdvancedFilter.php b/lib/php/UNL/Peoplefinder/Driver/LDAP/AdvancedFilter.php
new file mode 100644
index 00000000..45e6e82b
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Driver/LDAP/AdvancedFilter.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Builds an advanced filter for searching for people records.
+ *
+ * PHP version 5
+ * 
+ * @category  Default 
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+class UNL_Peoplefinder_Driver_LDAP_AdvancedFilter
+{
+    private $_filter;
+    
+    /**
+     * Construct an advanced filter.
+     *
+     * @param string $sn       Surname 'Bieber'
+     * @param string $cn       Common name 'Brett'
+     * @param string $eppa     Primary affiliation: student/staff/faculty
+     * @param string $operator LDAP operator to use & or |
+     * @param bool   $wild     Append wildcard character to search terms? 
+     */
+    function __construct($sn='',$cn='',$eppa='',$operator='&', $wild=false)
+    {
+        // Advanced Query, search by LastName (sn) and First Name (cn), and affiliation
+        if ($wild == false) {
+            $wildcard = '';
+        } else {
+            $wildcard = '*';
+        }
+        $filterfields = array();
+        $filterfields['sn'] = $sn.$wildcard;
+        $filterfields['cn'] = $cn.$wildcard;
+        $primaryAffiliation ='';
+        // Determine the eduPersonPrimaryAffiliation to query by
+        switch ($eppa) {
+            case 'stu':
+            case 'student':
+                $primaryAffiliation = '(eduPersonPrimaryAffiliation=student)';
+                break;
+            case 'fs':
+            case 'faculty':
+            case 'staff':
+                $primaryAffiliation = '(|(eduPersonPrimaryAffiliation=faculty)(eduPersonPrimaryAffiliation=staff))';
+                break;
+            default:
+                $primaryAffiliation = '(eduPersonPrimaryAffiliation=*)';
+                break;
+        }
+        $this->_filter = '('.$operator.$this->buildFilter($filterfields).$primaryAffiliation.')';
+    }
+    
+    private function buildFilter(&$field_arr, $op='')
+    {
+        $filter='';
+        foreach ($field_arr as $key=>$value) {
+            if (is_array($value)) {
+                $tmpvar = array();
+                $tmpvar[$key]=$value;
+                $filter .= buildFilter($tmpvar);
+            } else {
+                $filter .= "($key=$value)";
+            }
+        }
+        if ($op!='') $filter = "({$op}{$filter})";
+        return $filter;
+    }
+    
+    function __toString()
+    {
+        $this->_filter = '(&'.$this->_filter.'(!(eduPersonPrimaryAffiliation=guest)))';
+        return $this->_filter;
+    }
+
+}
diff --git a/lib/php/UNL/Peoplefinder/Driver/LDAP/OUFilter.php b/lib/php/UNL/Peoplefinder/Driver/LDAP/OUFilter.php
new file mode 100644
index 00000000..0d9027cc
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Driver/LDAP/OUFilter.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Builds a simple ou filter for records.
+ *
+ * PHP version 5
+ *
+ * @category  Default
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+class UNL_Peoplefinder_Driver_LDAP_OUFilter
+{
+    private $_filter;
+    
+    /**
+     * Create a filter for OU filtering.
+     *
+     * @param string $ou Organizational Unit eg:org|College of Engineering
+     */
+    function __construct($ou)
+    {
+        if (!empty($ou)) {
+            $this->_filter = '(ou='.str_replace('-', '*', $ou).')';
+        }
+    }
+    
+    function __toString()
+    {
+        $this->_filter = '(&'.$this->_filter.'(!(eduPersonPrimaryAffiliation=guest)))';
+        return $this->_filter;
+    }
+}
diff --git a/lib/php/UNL/Peoplefinder/Driver/LDAP/StandardFilter.php b/lib/php/UNL/Peoplefinder/Driver/LDAP/StandardFilter.php
new file mode 100644
index 00000000..b6d51957
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Driver/LDAP/StandardFilter.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Class builds a pretty good LDAP filter for searching for people.
+ * 
+ * <code>
+ * <?php
+ * $filter = new UNL_Peoplefinder_StandardFilter('brett bieber','|',false);
+ * echo $filter;
+ * ?>
+ * (|(sn=brett bieber)(cn=brett bieber)(&(| (givenname=brett) (sn=brett) (mail=brett) (unlemailnickname=brett) (unlemailalias=brett))(| (givenname=bieber) (sn=bieber) (mail=bieber) (unlemailnickname=bieber) (unlemailalias=bieber))))
+ * </code>
+ *
+ * PHP version 5
+ * 
+ * @category  Default 
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+class UNL_Peoplefinder_Driver_LDAP_StandardFilter
+{
+    private $_filter;
+    
+    private $_excludeRecords = array();
+    
+    /**
+     * Construct a standard filter.
+     *
+     * @param string $inquery  Search string 'bieber, brett' etc
+     * @param string $operator LDAP operator to use & or |
+     * @param bool   $wild     Append wildcard to search terms?
+     */
+    function __construct($inquery, $operator = '&', $wild = false)
+    {
+        if (!empty($inquery)) {
+            //ignore grouping and wildcard characters
+            $inquery = str_replace(array('"',',','*'),'',$inquery);
+
+            //escape query
+            $inquery = UNL_Peoplefinder_Driver_LDAP_Util::escape_filter_value($inquery);
+            
+            //put the query into an array of words
+            $query = preg_split('/\s+/', $inquery, 4);
+
+            if ($operator!='&') $operator = '|';
+
+            //create our filter
+            //search for the string parts
+            $filter = "($operator";
+            foreach ($query as $arg) {
+                //determine if a wildcard should be used
+                if ($wild) {
+                    $arg = "*$arg*";
+                }
+
+                $filter .= '(|';
+                $filter .= "(mail=$arg)(cn=$arg)(givenName=$arg)(sn=$arg)";
+
+                //find hyphenated and multi-word surnames in the exact matches query
+                if (!$wild) {
+                    $filter .= "(sn=$arg-*)(sn=*$arg)";
+                }
+
+                $filter .= ")";
+            }
+            $filter .= ")";
+
+            //determine if a wildcard should be used
+            if ($wild) {
+                $inquery = "*$inquery*";
+            }
+
+            //and search for the string as entered
+            $filter = "(|" .
+                    "(|(mail=$inquery)(cn=$inquery)(givenName=$inquery)(sn=$inquery))" .
+                    "$filter)";
+        }
+        $this->_filter = $filter;
+    }
+    
+    /**
+     * Allows you to exclude specific records from a result set.
+     *
+     * @param array(string|UNL_Peoplefinder_Record) $records Records to exclude, can be just the uids or record objects
+     */
+    function excludeRecords($records = array())
+    {
+        $this->_excludeRecords = array_merge($this->_excludeRecords, $records);
+    }
+    
+    function __toString()
+    {
+        if (count($this->_excludeRecords)) {
+            $excludeFilter = '';
+            foreach ($this->_excludeRecords as $record) {
+                $excludeFilter .= '(uid='.$record->__toString().')';
+            }
+            $this->_filter = '(&'.$this->_filter.'(!(|'.$excludeFilter.')))';
+        }
+        $this->_filter = '(&'.$this->_filter.'(!(eduPersonPrimaryAffiliation=guest)))';
+        return $this->_filter;
+    }
+}
diff --git a/lib/php/UNL/Peoplefinder/Driver/LDAP/TelephoneFilter.php b/lib/php/UNL/Peoplefinder/Driver/LDAP/TelephoneFilter.php
new file mode 100644
index 00000000..7015152d
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Driver/LDAP/TelephoneFilter.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Builds a simple telephone filter for searching for records.
+ *
+ * PHP version 5
+ * 
+ * @category  Default
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+class UNL_Peoplefinder_Driver_LDAP_TelephoneFilter
+{
+    private $_filter;
+    
+    function __construct($q)
+    {
+        if (!empty($q)) {
+            $this->_filter = '(telephoneNumber=*'.str_replace('-','*',$q).')';
+        }
+    }
+    
+    function __toString()
+    {
+        $this->_filter = '(&'.$this->_filter.'(!(eduPersonPrimaryAffiliation=guest)))';
+        return $this->_filter;
+    }
+}
diff --git a/lib/php/UNL/Peoplefinder/Driver/LDAP/Util.php b/lib/php/UNL/Peoplefinder/Driver/LDAP/Util.php
new file mode 100644
index 00000000..a4823622
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Driver/LDAP/Util.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * LDAP utilities for building search filters
+ *
+ * PHP version 5
+ * 
+ * @category  Default 
+ * @package   UNL_Peoplefinder
+ * @link      http://peoplefinder.unl.edu/
+ */
+class UNL_Peoplefinder_Driver_LDAP_Util
+{
+    /**
+    * Escapes the given VALUES according to RFC 2254 so that they can be safely used in LDAP filters.
+    *
+    * Any control characters with an ACII code < 32 as well as the characters with special meaning in
+    * LDAP filters "*", "(", ")", and "\" (the backslash) are converted into the representation of a
+    * backslash followed by two hex digits representing the hexadecimal value of the character.
+    *
+    * @see Net_LDAP2_Util::escape_filter_value() from Benedikt Hallinger <beni@php.net>
+    * @link http://pear.php.net/package/Net_LDAP2
+    * @author Benedikt Hallinger <beni@php.net>
+    *
+    * @param array $values Array of values to escape
+    *
+    * @static
+    * @return array Array $values, but escaped
+    */
+    public static function escape_filter_value($values = array())
+    {
+        // Parameter validation
+        if (!is_array($values)) {
+            $values = array($values);
+        }
+
+        foreach ($values as $key => $val) {
+            // Escaping of filter meta characters
+            $val = str_replace(array('\\',  '*',   '(',   ')'),
+                               array('\5c', '\2a', '\28', '\29'),
+                               $val);
+
+            // ASCII < 32 escaping
+            $val = self::asc2hex32($val);
+
+            if (null === $val) $val = '\0';  // apply escaped "null" if string is empty
+
+            $values[$key] = $val;
+        }
+
+        return (count($values) == 1) ? $values[0] : $values;
+    }
+
+    /**
+    * Converts all ASCII chars < 32 to "\HEX"
+    *
+    * @see Net_LDAP2_Util::asc2hex32() from Benedikt Hallinger <beni@php.net>
+    * @link http://pear.php.net/package/Net_LDAP2
+    * @author Benedikt Hallinger <beni@php.net>
+    *
+    * @param string $string String to convert
+    *
+    * @static
+    * @return string
+    */
+    public static function asc2hex32($string)
+    {
+        for ($i = 0; $i < strlen($string); $i++) {
+            $char = substr($string, $i, 1);
+            if (ord($char) < 32) {
+                $hex = dechex(ord($char));
+                if (strlen($hex) == 1) $hex = '0'.$hex;
+                $string = str_replace($char, '\\'.$hex, $string);
+            }
+        }
+        return $string;
+    }
+    
+    /**
+     * sort a multidimensional array
+     *
+     * @return array
+     */
+    public static function array_csort()
+    {
+        $args   = func_get_args();
+        $marray = array_shift($args);
+        
+        $msortline = "return(array_multisort(";
+        foreach ($args as $arg) {
+            @$i++;
+            if (is_string($arg)) {
+                foreach ($marray as $row) {
+                    $sortarr[$i][] = $row[$arg];
+                }
+            } else {
+                $sortarr[$i] = $arg;
+            }
+            $msortline .= "\$sortarr[".$i."],";
+        }
+        $msortline .= "\$marray));";
+        
+        eval($msortline);
+        return $marray;
+    }
+}
diff --git a/lib/php/UNL/Peoplefinder/Driver/WebService.php b/lib/php/UNL/Peoplefinder/Driver/WebService.php
new file mode 100644
index 00000000..17e1d714
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Driver/WebService.php
@@ -0,0 +1,40 @@
+<?php
+class UNL_Peoplefinder_Driver_WebService implements UNL_Peoplefinder_DriverInterface
+{
+    public $service_url = 'http://peoplefinder.unl.edu/service.php';
+    
+    function getExactMatches($query)
+    {
+        $results = file_get_contents($this->service_url.'?q='.urlencode($query).'&format=php&method=getExactMatches');
+        if ($results) {
+            $results = unserialize($results);
+        }
+        return $results;
+    }
+    function getAdvancedSearchMatches($sn, $cn, $eppa)
+    {
+        throw new Exception('Not implemented yet');
+    }
+    function getLikeMatches($query)
+    {
+        $results = file_get_contents($this->service_url.'?q='.urlencode($query).'&format=php&method=getLikeMatches');
+        if ($results) {
+            $results = unserialize($results);
+        }
+        return $results;
+    }
+    function getPhoneMatches($query)
+    {
+        throw new Exception('Not implemented yet');
+    }
+    
+    function getUID($uid)
+    {
+        $record = file_get_contents($this->service_url.'?uid='.urlencode($uid).'&format=php');
+        if ($record) {
+            $record = unserialize($record);
+        }
+        return $record;
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Peoplefinder/DriverInterface.php b/lib/php/UNL/Peoplefinder/DriverInterface.php
new file mode 100644
index 00000000..7a1a0dfe
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/DriverInterface.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Interface for a peoplefinder data driver.
+ * 
+ * The driver allows data source abstraction.
+ *
+ */
+interface UNL_Peoplefinder_DriverInterface
+{
+    /**
+     * Return an array of records exactly matching the query.
+     *
+     * @param string $query A general query
+     */
+    function getExactMatches($query);
+    
+    /**
+     * perform a detailed search
+     *
+     * @param string $sn   surname, eg bieber
+     * @param string $cn   common name, eg brett
+     * @param string $eppa eduPersonPrimaryAffiliation, eg staff/faculty/student
+     */
+    function getAdvancedSearchMatches($sn, $cn, $eppa);
+    
+    /**
+     * Return an array of records somewhat matching the query
+     *
+     * @param string $query A general query
+     */
+    function getLikeMatches($query);
+    
+    /**
+     * return matches for a phone number search
+     *
+     * @param string $query Phone number eg: 472-1598
+     */
+    function getPhoneMatches($query);
+    
+    /**
+     * get a UNL_Peoplefinder_Record for the user
+     *
+     * @param string $uid The unique user id eg: bbieber2
+     */
+    function getUID($uid);
+}
diff --git a/lib/php/UNL/Peoplefinder/Record.php b/lib/php/UNL/Peoplefinder/Record.php
new file mode 100644
index 00000000..83d346a2
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Record.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Peoplefinder class for UNL's online directory.
+ *
+ * PHP version 5
+ *
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+class UNL_Peoplefinder_Record
+{
+    public $cn;
+    public $ou;
+    public $eduPersonNickname;
+    public $eduPersonPrimaryAffiliation;
+    public $givenName;
+    public $displayName;
+    public $mail;
+    public $postalAddress;
+    public $sn;
+    public $telephoneNumber;
+    public $title;
+    public $uid;
+    public $unlHRPrimaryDepartment;
+    public $unlHRAddress;
+    public $unlSISClassLevel;
+    public $unlSISCollege;
+//    public $unlSISLocalAddr1;
+//    public $unlSISLocalAddr2;
+//    public $unlSISLocalCity;
+//    public $unlSISLocalPhone;
+//    public $unlSISLocalState;
+//    public $unlSISLocalZip;
+//    public $unlSISPermAddr1;
+//    public $unlSISPermAddr2;
+//    public $unlSISPermCity;
+//    public $unlSISPermState;
+//    public $unlSISPermZip;
+    public $unlSISMajor;
+    public $unlEmailAlias;
+    
+    
+    static function fromLDAPEntry(array $entry)
+    {
+        $r = new self();
+        foreach (get_object_vars($r) as $var=>$val) {
+            if (isset($entry[strtolower($var)], $entry[strtolower($var)][0])) {
+                $r->$var = $entry[strtolower($var)][0];
+            }
+        }
+        return $r;
+    }
+    
+    static function fromUNLLDAPEntry(UNL_LDAP_Entry $entry)
+    {
+        $r = new self();
+        foreach (get_object_vars($r) as $var=>$val) {
+            $r->$var = $entry->$var;
+        }
+        return $r;
+    }
+    
+    /**
+     * Takes in a string from the LDAP directory, usually formatted like:
+     *     ### ___ UNL 68588-####
+     *    Where ### is the room number, ___ = Building Abbreviation, #### zip extension
+     *
+     * @param string
+     * @return array Associative array.
+     */
+    function formatPostalAddress()
+    {
+        /* this is a faculty postal address
+            Currently of the form:
+            ### ___ UNL 68588-####
+            Where ### is the room number, ___ = Building Abbreviation, #### zip extension
+        */
+        /**
+         * We assumed that the address format is: ### ___ UNL 68588-####.
+         * Some 'fortunate' people have addresses not in this format.
+         */
+        //RLIM
+        // treat UNL as the delimiter for the streetaddress and zip
+        if (strpos($this->postalAddress,'UNL')) {
+            $addressComponent = explode('UNL', $this->postalAddress);
+        } elseif (strpos($this->postalAddress,'UNO')) {
+            $addressComponent = explode('UNO', $this->postalAddress);
+        } elseif (strpos($this->postalAddress,'Omaha')) {
+            $addressComponent = explode('Omaha', $this->postalAddress);
+        } else {
+            $addressComponent = array($this->postalAddress);
+        }
+        $address['region']         = 'NE';
+        $address['street-address'] = trim($addressComponent[0]);
+        if (isset($addressComponent[1])) {
+            $address['postal-code'] = trim($addressComponent[1]);
+        } else {
+            $address['postal-code'] = '';
+        }
+        switch (substr($address['postal-code'],0,3)) {
+            case '681':
+                $address['locality'] = 'Omaha';
+            break;
+            case '685':
+            default:
+                $address['locality'] = 'Lincoln';
+            break;
+        }
+        
+        return $address;
+    }
+    
+    function __toString()
+    {
+        return $this->uid;
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Peoplefinder/Renderer/HTML.php b/lib/php/UNL/Peoplefinder/Renderer/HTML.php
new file mode 100644
index 00000000..121f83de
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Renderer/HTML.php
@@ -0,0 +1,518 @@
+<?php
+/**
+ * Peoplefinder HTML Renderer
+ *
+ * PHP version 5
+ *
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+
+/**
+ * Determines if a network in the form of 192.168.17.1/16 or
+ * 127.0.0.1/255.255.255.255 or 10.0.0.1 matches a given ip
+ * @param $network The network and mask
+ * @param $ip The ip to check
+ * @return bool true or false
+ */
+function net_match($network, $ip) {
+     $ip_arr = explode('/', $network);
+     $network_long = ip2long($ip_arr[0]);
+     $x = ip2long($ip_arr[1]);
+     $mask =  long2ip($x) == $ip_arr[1] ? $x : 0xffffffff << (32 - $ip_arr[1]);
+     $ip_long = ip2long($ip);
+     return ($ip_long & $mask) == ($network_long & $mask);
+}
+
+/**
+ * Class to render html output for results
+ *
+ * PHP version 5
+ *
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+class UNL_Peoplefinder_Renderer_HTML
+{
+    
+    protected $trustedIP = false;
+    public $uri;
+    
+    public $displayLimit;
+    
+    /** This can be set to a javascript function name to send the UID to when clicking a uid */
+    public $uid_onclick;
+    /** This defines a mode in which the directory is searched to return one user. */
+    public $choose_uid = false;
+    public $page_onclick;
+    
+    function __construct(array $options = null)
+    {
+        if (isset($_SERVER['REMOTE_ADDR'])) {
+            $validIPs = array('129.93.0.0/16','65.123.32.0/19','64.39.240.0/20','216.128.208.0/20');
+            foreach ($validIPs as $range) {
+                if (net_match($range, $_SERVER['REMOTE_ADDR'])) {
+                    $this->trustedIP = true;
+                    break;
+                }
+            }
+        }
+        $this->displayLimit = UNL_Peoplefinder::$displayResultLimit;
+        $this->uri          = $_SERVER['SCRIPT_NAME'];
+        if (isset($options)) {
+            $this->setOptions($options);
+        }
+    }
+    
+    /**
+     * This function sets parameters for this class.
+     *
+     * @param array $options an associative array of options to set.
+     */
+    function setOptions(array $options)
+    {
+        foreach ($options as $option=>$val) {
+            if (property_exists($this,$option)) {
+                $this->$option = $val;
+            } else {
+                echo 'Warning: Trying to set unkown option ['.$option.'] for object '.get_class($this)."\n";
+            }
+        }
+    }
+
+    /**
+     * Renders a peoplefinder record object
+     *
+     * @param UNL_Peoplefinder_Record $r record to render
+     */
+    public function renderRecord(UNL_Peoplefinder_Record $r)
+    {
+        echo "<div class='vcard {$r->eduPersonPrimaryAffiliation}'>\n";
+        if (isset($r->mail)
+            && ($r->eduPersonPrimaryAffiliation != 'student' || $this->displayStudentEmail==true)) {
+            $displayEmail = true;
+        } else {
+            $displayEmail = false;
+        }
+        if ($displayEmail && isset($r->unlEmailAlias)) echo "<a class='email' href='mailto:{$r->unlEmailAlias}@unl.edu'>";
+        if ($r->ou == 'org') {
+            echo '<span class="cn">'.$r->cn.'</span>'.PHP_EOL;
+        } else {
+            echo '<span class="fn">'.$r->displayName.'</span>'.PHP_EOL;
+            if (isset($r->eduPersonNickname)) echo '<span class="nickname">'.$r->eduPersonNickname.'</span>'.PHP_EOL;
+        }
+        if ($displayEmail && isset($r->unlEmailAlias)) echo "</a>\n";
+        if (!empty($r->eduPersonPrimaryAffiliation)) echo '<span class="eppa">('.$r->eduPersonPrimaryAffiliation.')</span>'.PHP_EOL;
+        echo '<div class="vcardInfo">'.PHP_EOL;
+        echo '<a class="planetred_profile" href="http://planetred.unl.edu/pg/profile/unl_'.$r->uid.'" title="Planet Red Profile for '.$r->cn.'"><img class="photo frame" src="http://planetred.unl.edu/mod/profile/icondirect.php?username=unl_'.$r->uid.'&amp;size=medium"  alt="Photo of '.$r->displayName.'" /></a>';
+        if (isset($r->unlSISClassLevel)) {
+            switch ($r->unlSISClassLevel) {
+                case 'FR':
+                    $class = 'Freshman,';
+                    break;
+                case 'SR':
+                    $class = 'Senior,';
+                    break;
+                case 'SO':
+                    $class = 'Sophomore,';
+                    break;
+                case 'JR':
+                    $class = 'Junior,';
+                    break;
+                case 'GR':
+                    $class = 'Graduate Student,';
+                    break;
+                default:
+                    $class = $r->unlSISClassLevel;
+            }
+            echo '<span class="title">'.$class." ".$this->formatMajor($r->unlSISMajor).'&ndash;'.$this->formatCollege($r->unlSISCollege).'</span>';
+        }
+        
+//        if (isset($r->unlSISLocalAddr1)) {
+//            $localaddr = array($r->unlSISLocalAddr1, $r->unlSISLocalAddr2, $r->unlSISLocalCity, $r->unlSISLocalState, $r->unlSISLocalZip);
+//            $this->renderAddress($localaddr, 'Local', 'workAdr');
+//        }
+//        
+//        if (isset($r->unlSISPermAddr1)) {
+//            $permaddr  = array($r->unlSISPermAddr1, $r->unlSISPermAddr2, $r->unlSISPermCity, $r->unlSISPermState, $r->unlSISPermZip);
+//            $this->renderAddress($permaddr, 'Home', 'homeAdr');
+//        }
+        
+        if (isset($r->title)) {
+            echo "<span class='title'>{$r->title}</span>\n";
+        }
+        
+        if (isset($r->unlHRPrimaryDepartment)) {
+            $org_name = 'University of Nebraska&ndash;Lincoln';
+            if ($r->unlHRPrimaryDepartment == 'Office of the President') {
+                $org_name = 'University of Nebraska';
+            }
+            $dept_url = UNL_PEOPLEFINDER_URI.'departments/?d='.urlencode($r->unlHRPrimaryDepartment);
+            echo "<span class='org'>\n\t<span class='organization-unit'><a href='{$dept_url}'>{$r->unlHRPrimaryDepartment}</a></span>\n\t<span class='organization-name'>$org_name</span></span>\n";
+        }
+        
+        if (isset($r->postalAddress)) {
+            if (strpos($r->postalAddress,'UNL')!= -1 || strpos($r->postalAddress,'UNO')!= -1) {
+                $address = $r->formatpostalAddress();
+
+                if( strpos($address['postal-code'],'68588') == 0 )
+                {
+                    $address['street-address'] = $this->replaceBuildingCode($address['street-address']);
+                }
+
+                echo '<div class="adr workAdr">
+                     <span class="type">Work</span>
+                     <span class="street-address">'. $address['street-address'] . '</span>
+                     <span class="locality">' . $address['locality'] . '</span>
+                     <span class="region">' . $address['region'] . '</span>
+                     <span class="postal-code">' . $address['postal-code'] . '</span>
+                     <div class="country-name">USA</div>
+                    </div>'.PHP_EOL;
+            } else {
+                echo "<span class='adr'>{$r->postalAddress}</span>\n";
+            }
+        }
+        
+        if (strpos($_SERVER['HTTP_USER_AGENT'], "iPhone") === false) {
+            $href = "wtai://wp/mc;";
+            $isIPhone = false;
+        } else {
+            $href = "tel:";
+            $isIPhone = true;
+        }
+        if (isset($r->telephoneNumber)) {
+            
+            echo '<div class="tel workTel">
+                     <span class="type">Work</span>
+                     <span class="value">'.$this->formatPhone($r->telephoneNumber).'</span>
+                    </div>'.PHP_EOL;
+        }
+        
+        if (isset($r->unlSISLocalPhone)) {
+            echo '<div class="tel homeTel">
+                     <span class="type">Phone</span>
+                     <span class="value">'.$this->formatPhone($r->unlSISLocalPhone).'</span>
+                    </div>'.PHP_EOL;
+        }
+        
+        if ($displayEmail) {
+            if ($r->unlEmailAlias != 'president') {
+                $email = $r->unlEmailAlias.'@unl.edu';
+            } else {
+                $email = $r->unlEmailAlias.'@nebraska.edu';
+            }
+            echo "<span class='email'><a class='email' href='mailto:$email'>$email</a></span>\n";
+            if ($this->trustedIP===true) echo "<span class='email delivery'>Delivery Address: {$r->mail}</span>\n";
+        }
+        $linktext = '<img src="/ucomm/templatedependents/templatecss/images/mimetypes/text-vcard.gif" alt="vCard" /> <span class="caption">vCard</span>'.PHP_EOL;
+        echo $this->getVCardLink($r->uid, $linktext, null, 'Download V-Card for '.$r->givenName.' '.$r->sn);
+        echo '</div>'.PHP_EOL.'</div>'.PHP_EOL;
+    }
+    
+    public function renderAddress($address, $type, $class = null)
+    {
+        if (!isset($class)) {
+            $class = '';
+        }
+        $addr = '
+        <div class="adr '.$class.'">
+         <span class="type">'.$type.'</span>
+         <span class="street-address">'.$address[0].'</span>
+         <span class="locality">'.$address[2].'</span>
+         <span class="region">'.$address[3].'</span>
+         <span class="postal-code">'.$address[4].'</span>';
+        if (isset($address[5])) {
+            $addr .= '<div class="country-name">'.$address[5].'</div>';
+        }
+        $addr .= '</div>';
+        echo $addr;
+    }
+    
+    /**
+     * Takes in a street address of a staff or faculty member, a building
+     * code in a string with a link to the building in the virtual tour
+     *
+     * @param string $streetaddress Street Address of a staff or faculty member
+     *
+     * @return string
+     */
+    private function replaceBuildingCode($streetaddress)
+    {
+        require_once 'UNL/Common/Building.php';
+        $regex = "/([A-Za-z0-9].) ([A-Z0-9\&]{2,4})/" ; //& is for M&N Building
+        
+        if (preg_match($regex, $streetaddress, $matches)) {
+            $bldgs = new UNL_Common_Building();
+            
+            if ($bldgs->buildingExists($matches[2])) {
+                
+                $replace = '${1} <a class="location mapurl" href="http://www1.unl.edu/tour/${2}">${2}</a>';
+                return preg_replace($regex, $replace, $streetaddress);
+            }
+        }
+        
+        return $streetaddress;
+    }
+    
+    /**
+     * This function takes in a string representing a phone number
+     * and formats it to be rendered as a clickable calling link
+     * 
+     * @param string $phone A telephone number
+     * @return string
+     */
+    public function formatPhone($phone)
+    {
+        $link = '<a href="';
+        if (strpos($_SERVER['HTTP_USER_AGENT'], "iPhone") === false) {
+            $link .= "wtai://wp/mc;".str_replace(array("(", ")", "-"), "", $phone);
+        } else {
+            $link .= "tel:".$phone;
+        }
+        $link .= '">'.$phone.'</a>';
+        return $link;
+    }
+    
+    /**
+     * This function takes in an array of address information and formats it
+     *
+     * @param array $addressArray Address information
+     * <code>
+     * $addressArray[0] = Address line 1
+     * $addressArray[1] = Address line 2
+     * $addressArray[2] = City
+     * $addressArray[3] = State
+     * $addressArray[4] = Zip
+     * $addressArray[5] = Country
+     * </code>
+     *
+     * @return string
+     */
+    public function formatAddress($addressArray)
+    {
+        if (isset($addressArray[0])) {
+            $address = $addressArray[0]."<br />";
+            if (isset($addressArray[1])) $address .= $addressArray[1]."<br />";
+            $address .= $addressArray[2].", ".$addressArray[3]." ".$addressArray[4];
+            if (isset($addressArray[5])) $address .= "<br />".$addressArray[4];
+        } else {
+            $address = 'Unlisted';
+        }
+        return $address;
+    }
+    
+    public function displayPageLinks($num_records, $start, $end)
+    {
+        //Display Page information
+        $page = (isset($_GET['p']))?$_GET['p']:0;
+        $next = $page + 1;
+        if ($page>=1) $prevLink = '<a class="previous" href="'.$this->uri.'?'.preg_replace('/[&]?p=\d/','',$_SERVER['QUERY_STRING']).'&amp;p='.($page-1).'">&lt;&lt;&nbsp;</a>';
+        else $prevLink = '&lt;&lt;&nbsp;';
+        if ($end < $num_records) $nextLink = "<a class='next' href='".$this->uri."?".preg_replace("/[&]?p=\d/","",$_SERVER['QUERY_STRING'])."&amp;p=$next'>&nbsp;&gt;&gt;</a>";
+        else $nextLink = '&nbsp;&gt;&gt;';
+        return '<div class="cNav">'.$prevLink.$nextLink.'</div>';
+    }
+    
+    public function renderListRecord(UNL_Peoplefinder_Record $r)
+    {
+        if ($r->ou == 'org') {
+            $linktext = $r->cn;
+        } else {
+            $linktext = $r->sn . ',&nbsp;'. $r->givenName;
+            if (isset($r->eduPersonNickname)) {
+                $linktext .= ' "'.$r->eduPersonNickname.'"';
+            }
+        }
+        
+        echo '<div class="fn">'.$this->getUIDLink($r->uid, $linktext, $this->uid_onclick).'</div>'.PHP_EOL;
+        if (isset($r->eduPersonPrimaryAffiliation)) echo '<div class="eppa">('.$r->eduPersonPrimaryAffiliation.')</div>'.PHP_EOL;
+        if (isset($r->unlHRPrimaryDepartment)) echo '<div class="organization-unit">'.$r->unlHRPrimaryDepartment.'</div>'.PHP_EOL;
+        if (isset($r->title)) echo '<div class="title">'.$r->title.'</div>'.PHP_EOL;
+        if (isset($r->telephoneNumber)) echo '<div class="tel">'.$this->formatPhone($r->telephoneNumber).'</div>'.PHP_EOL;
+        
+        echo $this->getUIDLink($r->uid, 'contact info', $this->uid_onclick, 'cInfo');
+		if ($this->choose_uid) {
+		    echo '<div class="pfchooser"><a href="#" onclick="return pfCatchUID(\''.$r->uid.'\');">Choose this person</a></div>'.PHP_EOL;
+		}
+    }
+    
+    public function renderSearchResults(array $records, $start=0, $num_rows=UNL_PF_DISPLAY_LIMIT)
+    {
+        if (($start+$num_rows)>count($records)) {
+            $end = count($records);
+        } else {
+            $end = $start+$num_rows;
+        }
+        if ($start > 0 || $end < count($records)) {
+            $navlinks = $this->displayPageLinks(count($records), $start, $end);
+        } else {
+            $navlinks = '';
+        }
+        echo "<div class='result_head'>Results ".($start+1)." - $end out of ".count($records).':'.$navlinks.'</div>'.PHP_EOL;
+        echo '<ul>';
+        for ($i = $start; $i<$end; $i++) {
+            $even_odd = ($i % 2) ? '' : 'alt';
+            if ($records[$i]->ou == 'org') {
+                $class = 'org_Sresult';
+            } else {
+                $class = 'ppl_Sresult';
+            }
+            $class .= ' '.$records[$i]->eduPersonPrimaryAffiliation;
+            echo '<li class="'.$class.' '.$even_odd.'">';
+            $this->renderListRecord($records[$i]);
+            echo '</li>'.PHP_EOL;
+        }
+        echo '</ul>';
+        echo "<div class='result_head'>$navlinks</div>";
+    }
+    
+    public function getUIDLink($uid, $linktext = null, $onclick = null, $class = null)
+    {
+        $uri = $this->uri.'?uid='.$uid;
+        if (isset($linktext)) {
+            $link = '<a href="'.$uri.'"';
+            if (isset($onclick)) {
+                $link .= ' onclick="return '.$this->uid_onclick.'(\''.$uid.'\');"';
+            }
+            if (isset($class)) {
+                $link .= ' class="'.$class.'"';
+            }
+            $link .= '>'.$linktext.'</a>';
+            return $link;
+        } else {
+            return $uri;
+        }
+    }
+    
+    /**
+     * Formats a major subject code into a text description.
+     *
+     * @param string $subject Subject code for the major eg: MSYM
+     * 
+     * @return string
+     */
+    public function formatMajor($subject)
+    {
+
+        include_once 'Cache/Lite.php';
+        $c = new Cache_Lite();
+        if ($subject_xml = $c->get('catalog subjects')) {
+            
+        } else {
+            if ($subject_xml = file_get_contents('http://bulletin.unl.edu/?view=subjects&format=xml')) {
+                $c->save($subject_xml);
+            } else {
+                $c->extendLife();
+                $c->get('catalog subjects');
+            }
+        }
+        
+        $d = new DOMDocument();
+        $d->loadXML($subject_xml);
+        if ($subject_el = $d->getElementById($subject)) {
+            return $subject_el->textContent;
+        }
+        
+        switch ($subject) {
+            case 'UNDL':
+                return 'Undeclared';
+            case 'PBAC':
+                return 'Non-Degree Post-Baccalaureate';
+            default:
+                return $subject;
+        }
+    }
+    
+    /**
+     * Format a three letter college abbreviation into the full college name.
+     *
+     * @param string $college College abbreviation = FPA
+     * 
+     * @return string College of Fine &amp; Performing Arts
+     */
+    public function formatCollege($college)
+    {
+        include_once 'UNL/Common/Colleges.php';
+        $colleges = new UNL_Common_Colleges();
+        if (isset($colleges->colleges[$college])) {
+            return htmlentities($colleges->colleges[$college]);
+        }
+        
+        return $college;
+    }
+    
+    public function getVCardLink($uid, $linktext = null,$onclick = null,$title = null)
+    {
+
+        $uri = $this->uri.'vcards/'.$uid;
+        if (isset($linktext)) {
+            $link = '<a href="'.$uri.'"';
+            if (isset($onclick)) {
+                $link .= ' onclick="return '.$onclick.'(\''.$uid.'\');"';
+            }
+            if (isset($title)) {
+                $link .= ' title="'.$title.'"';
+            }
+            $link .= ' class="vcf">'.$linktext.'</a>';
+            return $link;
+        } else {
+            return $uri;
+        }
+    }
+    
+    
+    
+    public function renderError()
+    {
+        echo "<p>Please enter more information or <a href='".$_SERVER['PHP_SELF']."?adv=y' title='Click here to perform a detailed Peoplefinder search'>try a Detailed Search.</a></p>";
+    }
+    
+    /**
+     * Displays the instructions for using peoplefinder.
+     *
+     * @param bool $adv Show advanced instructions or default instructions.
+     * 
+     * @return void
+     */
+    function displayInstructions($adv=false)
+    {
+        echo '<div style="padding-top:10px;width:270px;" id="instructions">';
+        if ($adv) {
+            echo 'Enter in as much of the first and/or last name you know, ' .
+                 'you can also select a primary affiliation to refine your search.';
+        } else {
+            echo 'Enter in as much of the name as you know, first and/or last '.
+                 'name in any order.<br /><br />Reverse telephone number lookup: '.
+                 'enter last three or more digits.';
+        }
+        echo '</div>';
+    }
+    
+    /**
+     * Display the standard search form.
+     *
+     * @return void
+     */
+    function displayStandardForm()
+    {
+        include 'standardForm.php';
+    }
+
+    /**
+     * Display the advanced form.
+     *
+     * @return void
+     */
+    function displayAdvancedForm()
+    {
+        include 'advancedForm.php';
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Peoplefinder/Renderer/JSON.php b/lib/php/UNL/Peoplefinder/Renderer/JSON.php
new file mode 100644
index 00000000..773e333f
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Renderer/JSON.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Peoplefinder JSON renderer
+ * 
+ * PHP version 5
+ * 
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+
+class UNL_Peoplefinder_Renderer_JSON
+{
+    function __construct(array $options = null)
+    {
+        
+    }
+    
+    /**
+     * Renders a peoplefinder record object
+     *
+     * @param UNL_Peoplefinder_Record $r record to render
+     */
+    public function renderRecord(UNL_Peoplefinder_Record $r)
+    {
+        echo json_encode($r);
+    }
+    
+    public function renderSearchResults(array $records, $start=0, $num_rows=UNL_PF_DISPLAY_LIMIT)
+    {
+        echo json_encode($records);
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Peoplefinder/Renderer/Serialized.php b/lib/php/UNL/Peoplefinder/Renderer/Serialized.php
new file mode 100644
index 00000000..a5e0997a
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Renderer/Serialized.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Peoplefinder serialized renderer
+ * 
+ * PHP version 5
+ * 
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+
+class UNL_Peoplefinder_Renderer_Serialized
+{
+    function __construct(array $options = null)
+    {
+        
+    }
+    
+    /**
+     * Renders a peoplefinder record object
+     *
+     * @param UNL_Peoplefinder_Record $r record to render
+     */
+    public function renderRecord(UNL_Peoplefinder_Record $r)
+    {
+        echo serialize($r);
+    }
+    
+    public function renderSearchResults(array $records, $start=0, $num_rows=UNL_PF_DISPLAY_LIMIT)
+    {
+        echo serialize($records);
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Peoplefinder/Renderer/XML.php b/lib/php/UNL/Peoplefinder/Renderer/XML.php
new file mode 100644
index 00000000..50bcf8fe
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Renderer/XML.php
@@ -0,0 +1,68 @@
+<?php
+class UNL_Peoplefinder_Renderer_XML
+{
+
+    protected $trustedIP = false;
+    protected $displayStudentTelephone = false;
+    
+    protected $sent_headers = false;
+    
+    /**
+     * Sends the headers and XML preamble.
+     *
+     * @return void
+     */
+    function sendHeaders()
+    {
+        if ($this->sent_headers) {
+            return;
+        }
+        header('Content-type: text/xml');
+        echo '<?xml version="1.0" encoding="utf-8"?>
+<unl xmlns="http://wdn.unl.edu/xml">'.PHP_EOL;
+        $this->sent_headers = true;
+    }
+    
+    /**
+     * Render an individual record
+     *
+     * @param UNL_Peoplefinder_Record $r
+     */
+    public function renderRecord(UNL_Peoplefinder_Record $r)
+    {
+        $this->sendHeaders();
+        echo '<person>';
+        foreach (get_object_vars($r) as $key=>$val) {
+            $val = htmlspecialchars($val);
+            echo "<$key>{$val}</$key>\n";
+        }
+        echo '</person>'.PHP_EOL;
+    }
+    
+    public function renderSearchResults(array $records, $start=0, $num_rows=UNL_PF_DISPLAY_LIMIT)
+    {
+        $this->sendHeaders();
+        foreach ($records as $record) {
+            $this->renderRecord($record);
+        }
+    }
+    
+    public function renderError()
+    {
+        $this->sendHeaders();
+        echo '<error>Please enter more information</error>';
+    }
+    
+    function __destruct()
+    {
+        if ($this->sent_headers) {
+            $this->sendFooter();
+        }
+    }
+    
+    function sendFooter()
+    {
+        echo '</unl>';
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Peoplefinder/Renderer/vCard.php b/lib/php/UNL/Peoplefinder/Renderer/vCard.php
new file mode 100644
index 00000000..1afab90c
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/Renderer/vCard.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Peoplefinder vcard renderer
+ * 
+ * PHP version 5
+ * 
+ * @package   UNL_Peoplefinder
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @copyright 2007 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://peoplefinder.unl.edu/
+ */
+
+class UNL_Peoplefinder_Renderer_vCard
+{
+
+    protected $displayStudentTelephone = false;
+    
+    public function renderRecord(UNL_Peoplefinder_Record $r)
+    {
+        header('Content-Type: text/x-vcard');
+        header('Content-Disposition: attachment; filename="'.$r->sn.', '.$r->givenName.'.vcf"');
+        //connect, taking in UID
+        echo "BEGIN:VCARD\n";
+        echo "VERSION:3.0\n";
+        echo "N:".$r->sn.";".$r->givenName.";;;\n";
+        echo "FN:".$r->givenName." ".$r->sn."\n";
+        if(isset($r->unlHRPrimaryDepartment)) echo "ORG:University of Nebraska-Lincoln;".$r->unlHRPrimaryDepartment."\n";
+        if (isset($r->unlEmailAlias)) {
+            if (($r->eduPersonPrimaryAffiliation != 'student') && isset($r->unlEmailAlias)) echo "EMAIL;type=INTERNET;type=WORK;type=pref:".$r->unlEmailAlias."@unl.edu\n";
+        }
+        if ($r->eduPersonPrimaryAffiliation != "student" || $this->displayStudentTelephone==true) echo "TEL;type=WORK;type=pref:".$r->telephoneNumber."\n";
+        //echo "TEL;type=CELL:(402) 555-1111\n";
+        if (isset($r->unlSISLocalPhone)) {
+            echo "TEL;type=HOME:{$r->unlSISLocalPhone}\n";
+        }
+        if (isset($r->unlSISLocalAddr1)) {
+            echo "item1.ADR;type=WORK;type=pref:;;".$r->unlSISLocalAddr1;
+            if (isset($r->unlSISLocalAddr2)) echo "\\n".$r->unlSISLocalAddr2;
+            echo ";".$r->unlSISLocalCity.";".$r->unlSISLocalState.";".$r->unlSISLocalZip.";\n";
+            echo "item1.X-ABLabel:local\n";
+        }
+        if (isset($r->unlSISPermaddr1)) {
+            echo "item2.ADR;type=HOME;type=pref:;;".$r->unlSISPermAddr1;
+            if(isset($r->unlSISPermAddr2)) echo "\\n".$r->unlSISPermAddr2;
+            echo ";".@$r->unlSISPermCity.";".@$r->unlSISPermState.";".@$r->unlSISPermZip.";\n";
+            echo "item2.X-ABLabel:permanent\n";
+        }
+        //echo "item1.X-ABADR:us\n";
+        //echo "item2.X-ABADR:us\n";
+        //echo "URL:http://www.unl.edu/\n";
+        //echo "LOGO;VALUE=uri:http://www.unl.edu/unlpub/2004sharedgraphics/smcolor_wordmark.gif";
+        if (isset($r->title)) {
+            echo "item3.X-ABRELATEDNAMES;type=pref:".$r->title."\n";
+            echo "item3.X-ABLabel:title\n";
+        }
+        echo "END:VCARD\n";
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Peoplefinder/RendererInterface.php b/lib/php/UNL/Peoplefinder/RendererInterface.php
new file mode 100644
index 00000000..aa853202
--- /dev/null
+++ b/lib/php/UNL/Peoplefinder/RendererInterface.php
@@ -0,0 +1,10 @@
+<?php
+interface UNL_Peoplefinder_RendererInterface
+{
+    function renderRecord(UNL_Peoplefinder_Record $r);
+    function renderListRecord(UNL_Peoplefinder_Record $r);
+    function renderSearchResults(array $records, $start=0, $num_rows=UNL_PF_DISPLAY_LIMIT);
+    function renderError($message = null);
+    function displayInstructions();
+}
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Templates.php b/lib/php/UNL/Templates.php
new file mode 100644
index 00000000..3ab6bda5
--- /dev/null
+++ b/lib/php/UNL/Templates.php
@@ -0,0 +1,331 @@
+<?php
+/**
+ * Object oriented interface to create UNL Template based HTML pages.
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+
+/**
+ * Utilizes the UNL_DWT Dreamweaver template class.
+ */
+require_once 'UNL/DWT.php';
+
+/**
+ * Allows you to create UNL Template based HTML pages through an object 
+ * oriented interface.
+ * 
+ * Install on your PHP server with:
+ * pear channel-discover pear.unl.edu
+ * pear install unl/UNL_Templates
+ * 
+ * <code>
+ * <?php
+ * require_once 'UNL/Templates.php';
+ * $page                  = UNL_Templates::factory('Fixed');
+ * $page->titlegraphic    = '<h1>UNL Templates</h1>';
+ * $page->maincontentarea = 'Hello world!';
+ * $page->loadSharedcodeFiles();
+ * echo $page;
+ * </code>
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+class UNL_Templates extends UNL_DWT
+{
+    const VERSION2 = 2;
+    const VERSION3 = 3;
+    
+    /**
+     * Cache object for output caching
+     * 
+     * @var UNL_Templates_CachingService
+     */
+    static protected $cache;
+    
+    static public $options = array(
+        'debug'                  => 0,
+        'sharedcodepath'         => 'sharedcode',
+        'templatedependentspath' => '',
+        'cache'                  => array(),
+        'version'                => self::VERSION2
+    );
+    
+    /**
+     * The version of the templates we're using.
+     * 
+     * @var UNL_Templates_Version
+     */
+    static public $template_version;
+    
+    /**
+     * Construct a UNL_Templates object
+     */
+    public function __construct()
+    {
+        date_default_timezone_set(date_default_timezone_get());
+        self::$options['templatedependentspath'] = $_SERVER['DOCUMENT_ROOT'];
+    }
+    
+    /**
+     * Initialize the configuration for the UNL_DWT class
+     * 
+     * @return void
+     */
+    public static function loadDefaultConfig()
+    {
+        include_once 'UNL/Templates/Version'.self::$options['version'].'.php';
+        $class = 'UNL_Templates_Version'.self::$options['version'];
+        self::$template_version = new $class();
+        UNL_DWT::$options = array_merge(UNL_DWT::$options, self::$template_version->getConfig());
+    }
+    
+    /**
+     * The factory returns a template object for any UNL Template style requested:
+     *  * Fixed
+     *  * Liquid
+     *  * Popup
+     *  * Document
+     *  * Secure
+     *  * Unlaffiliate
+     * 
+     * <code>
+     * $page = UNL_Templates::factory('Fixed');
+     * </code>
+     *
+     * @param string $type     Type of template to get, Fixed, Liquid, Doc, Popup
+     * @param mixed  $coptions Options for the constructor
+     * 
+     * @return UNL_Templates
+     */
+    static function &factory($type, $coptions = false)
+    {
+        UNL_Templates::loadDefaultConfig();
+        return parent::factory($type, $coptions);
+    }
+    
+    /**
+     * Attempts to connect to the template server and grabs the latest cache of the
+     * template (.tpl) file. Set options for Cache_Lite in self::$options['cache']
+     * 
+     * @return string
+     */
+    function getCache()
+    {
+        $cache = self::getCachingService();
+        $cache_key = self::$options['version'].$this->__template;
+        // Test if there is a valid cache for this template
+        if ($data = $cache->get($cache_key)) {
+            // Content is in $data
+            self::debug('Using cached version from '.
+                         date('Y-m-d H:i:s', $cache->lastModified()), 'getCache', 3);
+        } else { // No valid cache found
+            if ($data = self::$template_version->getTemplate($this->__template)) {
+                self::debug('Updating cache.', 'getCache', 3);
+                $data = $this->makeIncludeReplacements($data);
+                $cache->save($data, $cache_key);
+            } else {
+                // Error getting updated version of the templates.
+                self::debug('Could not connect to template server. ' . PHP_EOL .
+                             'Extending life of template cache.', 'getCache', 3);
+                $cache->extendLife();
+                $data = $cache->get($this->__template);
+            }
+        }
+        return $data;
+    }
+    
+    /**
+     * Loads standard customized content (sharedcode) files from the filesystem.
+     * 
+     * @return void
+     */
+    function loadSharedcodeFiles()
+    {    
+        $includes = array(
+                            'footercontent'         => 'footer.html',
+                            'contactinfo'           => 'footerContactInfo.html',
+                            'navlinks'              => 'navigation.html',
+                            'leftcollinks'          => 'relatedLinks.html',
+                            'optionalfooter'        => 'optionalFooter.html',
+                            'collegenavigationlist' => 'unitNavigation.html',
+                            );
+        foreach ($includes as $element=>$filename) {
+            if (file_exists(self::$options['sharedcodepath'].'/'.$filename)) {
+                $this->{$element} = file_get_contents(self::$options['sharedcodepath'].'/'.$filename);
+            }
+        }
+    }
+
+
+    /**
+     * Add a link within the head of the page.
+     * 
+     * @param string $href       URI to the resource
+     * @param string $relation   Relation of this link element (alternate)
+     * @param string $relType    The type of relation (rel)
+     * @param array  $attributes Any additional attribute=>value combinations
+     * 
+     * @return void
+     */
+    function addHeadLink($href, $relation, $relType = 'rel', array $attributes = array())
+    {
+        $attributeString = '';
+        foreach ($attributes as $name=>$value) {
+            $attributeString .= $name.'="'.$value.'" ';
+        }    
+    
+        $this->head .= '<link '.$relType.'="'.$relation.'" href="'.$href.'" '.$attributeString.' />'.PHP_EOL;
+    
+    }
+
+    /**
+     * Add a (java)script to the page.
+     *
+     * @param string $url  URL to the script
+     * @param string $type Type of script text/javascript
+     * 
+     * @return void
+     */
+    function addScript($url, $type = 'text/javascript')
+    {
+        $this->head .= '<script type="'.$type.'" src="'.$url.'"></script>'.PHP_EOL;
+    }
+
+    /**
+     * Adds a script declaration to the page.
+     *
+     * @param string $content The javascript you wish to add.
+     * @param string $type    Type of script tag.
+     * 
+     * @return void
+     */
+    function addScriptDeclaration($content, $type = 'text/javascript')
+    {
+        $this->head .= '<script type="'.$type.'">//<![CDATA['.PHP_EOL.$content.PHP_EOL.'//]]></script>'.PHP_EOL;
+    }
+
+    /**
+     * Add a style declaration to the head of the document.
+     * <code>
+     * $page->addStyleDeclaration('.course {font-size:1.5em}');
+     * </code>
+     *
+     * @param string $content CSS content to add
+     * @param string $type    type attribute for the style element
+     * 
+     * @return void
+     */
+    function addStyleDeclaration($content, $type = 'text/css')
+    {
+        $this->head .= '<style type="'.$type.'">'.$content.'</style>'.PHP_EOL;
+    }
+    
+    /**
+     * Add a link to a stylesheet.
+     *
+     * @param string $url   Address of the stylesheet, absolute or relative
+     * @param string $media Media target (screen/print/projector etc)
+     * 
+     * @return void
+     */
+    function addStyleSheet($url, $media = 'all')
+    {
+        $this->addHeadLink($url, 'stylesheet', 'rel', array('media'=>$media, 'type'=>'text/css'));
+    }
+
+    /**
+     * Returns the page in HTML form.
+     * 
+     * @return string THe full HTML of the page.
+     */
+    function toHtml()
+    {
+        $p       = $this->getCache();
+        $regions = get_object_vars($this);
+        return $this->replaceRegions($p, $regions);
+    }
+    
+    /**
+     * returns this template as a string.
+     *
+     * @return string
+     */
+    function __toString()
+    {
+        return $this->toHtml();
+    }
+    
+    
+    /**
+     * Populates templatedependents files
+     * 
+     * Replaces the template dependent include statements with the corresponding 
+     * files from the /ucomm/templatedependents/ directory. To specify the location
+     * of your templatedependents directory, use something like
+     * $page->options['templatedependentspath'] = '/var/www/';
+     * and set the path to the directory containing /ucomm/templatedependents/
+     *
+     * @param string $p Page to make replacements in
+     * 
+     * @return string
+     */
+    function makeIncludeReplacements($p)
+    {
+        return self::$template_version->makeIncludeReplacements($p);
+    }
+    
+    /**
+     * Debug handler for messages.
+     *
+     * @param string $message Message to send to debug output
+     * @param int    $logtype Which log to send this to
+     * @param int    $level   The threshold to send this message or not.
+     * 
+     * @return void
+     */
+    static function debug($message, $logtype = 0, $level = 1)
+    {
+        UNL_DWT::$options['debug'] = self::$options['debug'];
+        parent::debug($message, $logtype, $level);
+    }
+    
+    /**
+     * Cleans the cache.
+     *
+     * @param mixed $o Pass a cached object to clean it's cache, or a string id.
+     *
+     * @return bool true if cache was successfully cleared.
+     */
+    public function cleanCache($object = null)
+    {
+        return self::getCachingService()->clean($object);
+    }
+    
+    static public function setCachingService(UNL_Templates_CachingService $cache)
+    {
+        self::$cache = $cache;
+    }
+    
+    static public function getCachingService()
+    {
+        if (!isset(self::$cache)) {
+            include_once 'UNL/Templates/CachingService/CacheLite.php';
+            self::$cache = new UNL_Templates_CachingService_CacheLite(self::$options['cache']);
+        }
+        return self::$cache;
+    }
+}
diff --git a/lib/php/UNL/Templates/CachingService.php b/lib/php/UNL/Templates/CachingService.php
new file mode 100644
index 00000000..3dc28c46
--- /dev/null
+++ b/lib/php/UNL/Templates/CachingService.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * An interface for a caching service.
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+interface UNL_Templates_CachingService
+{
+    public function get($key);
+    public function save($data, $key);
+    public function clean($object = null);
+}
\ No newline at end of file
diff --git a/lib/php/UNL/Templates/CachingService/CacheLite.php b/lib/php/UNL/Templates/CachingService/CacheLite.php
new file mode 100644
index 00000000..98853e32
--- /dev/null
+++ b/lib/php/UNL/Templates/CachingService/CacheLite.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * A Cache Service using Cache_Lite
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates/CachingService.php';
+class UNL_Templates_CachingService_CacheLite implements UNL_Templates_CachingService
+{
+    protected $cache;
+    
+    function __construct($options = array())
+    {
+        include_once 'Cache/Lite.php';
+        $options = array_merge(array('lifeTime'=>3600), $options);
+        $this->cache = new Cache_Lite($options);
+    }
+    
+    function get($key)
+    {
+        return $this->cache->get($key, 'UNL_Templates');
+    }
+    
+    function save($data, $key)
+    {
+        return $this->cache->save($data, $key, 'UNL_Templates');
+    }
+    
+    function clean($object = null)
+    {
+        if (isset($object)) {
+            if (is_object($object)
+                && $object instanceof UNL_UCBCN_Cacheable) {
+                $key = $object->getCacheKey();
+                if ($key === false) {
+                    // This is a non-cacheable object.
+                    return true;
+                }
+            } else {
+                $key = (string) $object;
+            }
+            if ($this->cache->get($key) !== false) {
+                // Remove the cache for this individual object.
+                return $this->cache->remove($key, 'UNL_Templates');
+            }
+        } else {
+            return $this->cache->clean('UNL_Templates');
+        }
+        return false;
+    }
+    function __call($method, $params)
+    {
+        return $this->cache->$method($params);
+    }
+
+}
diff --git a/lib/php/UNL/Templates/Scanner.php b/lib/php/UNL/Templates/Scanner.php
new file mode 100644
index 00000000..c8fdf51b
--- /dev/null
+++ b/lib/php/UNL/Templates/Scanner.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * This class will scan a template file for the regions, which you can use to 
+ * analyze and use a rendered template file.
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/DWT/Scanner.php';
+
+
+class UNL_Templates_Scanner extends UNL_DWT_Scanner
+{
+    /**
+     * Construct a remote file.
+     *
+     * @param string $html Contents of the page
+     */
+    function __construct($html)
+    {
+        parent::__construct($html);
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Templates/Version.php b/lib/php/UNL/Templates/Version.php
new file mode 100644
index 00000000..074d6af7
--- /dev/null
+++ b/lib/php/UNL/Templates/Version.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Interface for a version of the template files.
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+interface UNL_Templates_Version
+{ 
+    function getConfig();
+    function getTemplate($template);
+    function makeIncludeReplacements($html);
+}
+?>
\ No newline at end of file
diff --git a/lib/php/UNL/Templates/Version2.php b/lib/php/UNL/Templates/Version2.php
new file mode 100644
index 00000000..e89a38f4
--- /dev/null
+++ b/lib/php/UNL/Templates/Version2.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Base class for version 2 (2006) of the template files.
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates/Version.php';
+
+class UNL_Templates_Version2 implements UNL_Templates_Version
+{ 
+    function getConfig()
+    {
+        return array('class_location' => 'UNL/Templates/Version2/',
+                     'class_prefix'   => 'UNL_Templates_Version2_');
+    }
+    
+    function getTemplate($template)
+    {
+        return file_get_contents('http://pear.unl.edu/UNL/Templates/server.php?template='.$template);
+    }
+    
+    function makeIncludeReplacements($html)
+    {
+        UNL_Templates::debug('Now making template include replacements.',
+                     'makeIncludeReplacements', 3);
+        $includes = array();
+        preg_match_all('<!--#include virtual="(/ucomm/templatedependents/[A-Za-z0-9\.\/]+)" -->',
+                        $html, $includes);
+        UNL_Templates::debug(print_r($includes, true), 'makeIncludeReplacements', 3);
+        foreach ($includes[1] as $include) {
+            UNL_Templates::debug('Replacing '.$include, 'makeIncludeReplacements', 3);
+            $file = UNL_Templates::$options['templatedependentspath'].$include;
+            if (!file_exists($file)) {
+                UNL_Templates::debug('File does not exist:'.$file,
+                             'makeIncludeReplacements', 3);
+                $file = 'http://www.unl.edu'.$include;
+            }
+            $html = str_replace('<!--#include virtual="'.$include.'" -->',
+                                 file_get_contents($file), $html);
+        }
+        return $html;
+    }
+}
diff --git a/lib/php/UNL/Templates/Version2/Document.php b/lib/php/UNL/Templates/Version2/Document.php
new file mode 100644
index 00000000..62e6d3bc
--- /dev/null
+++ b/lib/php/UNL/Templates/Version2/Document.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Template Definition for document.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Document template object.
+ *
+ * @package UNL_Templates
+ */
+class UNL_Templates_Version2_Document extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Document.tpl';                    // template name
+    public $doctitle = "<title>UNL | Document Template</title>";                       // string()  
+    public $head = "<script type=\"text/javascript\"> var navl2Links = 0; //Default navline2 links to display (zero based counting) </script>";                           // string()  
+    public $breadcrumbs = "";                    // string()  
+    public $collegenavigationlist = "";          // string()  
+    public $titlegraphic = "<h1>Department</h1> <h2>Taglines - We Do The Heavy Lifting</h2>";                   // string()  
+    public $maincontentarea = "<p style=\"margin:20px; border:3px solid #CC0000;padding:10px; text-align:center\"> <strong>Delete this box and place your content here.</strong><br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://www.unl.edu/webdevnet/\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Click here to check Validation</a> </p>";                // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version2_Document',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version2/Fixed.php b/lib/php/UNL/Templates/Version2/Fixed.php
new file mode 100644
index 00000000..fa02b800
--- /dev/null
+++ b/lib/php/UNL/Templates/Version2/Fixed.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Template Definition for fixed.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ * 
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Fixed width template object.
+ * 
+ * @package UNL_Templates
+ *
+ */
+class UNL_Templates_Version2_Fixed extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Fixed.tpl';                       // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<script type=\"text/javascript\"> var navl2Links = 0; //Default navline2 links to display (zero based counting) </script>";                           // string()  
+    public $breadcrumbs = "<!-- WDN: see glossary item \'breadcrumbs\' --> <ul> <li class=\"first\"><a href=\"http://www.unl.edu/\">UNL</a></li> <li><a href=\"http://www.unl.edu/\">Department</a></li> <li>New Page</li> </ul>";                    // string()  
+    public $collegenavigationlist = "";          // string()  
+    public $titlegraphic = "<h1>Department</h1> <h2>Taglines - We Do The Heavy Lifting</h2>";                   // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $leftRandomPromo = "<div class=\"image_small_short\" id=\"leftRandomPromo\"> <a href=\"#\" id=\"leftRandomPromoAnchor\"><img id=\"leftRandomPromoImage\" alt=\"\" src=\"/ucomm/templatedependents/templatecss/images/transpixel.gif\" /></a> <script type=\"text/javascript\" src=\"../sharedcode/leftRandomPromo.js\"></script> </div>";                // string()  
+    public $leftcollinks = "<!-- WDN: see glossary item \'sidebar links\' --> <!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $maincontentarea = "<p style=\"margin:20px; border:3px solid #CC0000;padding:10px; text-align:center\"> <strong>Delete this box and place your content here.</strong><br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://www.unl.edu/webdevnet/\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Click here to check Validation</a> </p>";                // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version2_Fixed',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version2/Liquid.php b/lib/php/UNL/Templates/Version2/Liquid.php
new file mode 100644
index 00000000..673bc993
--- /dev/null
+++ b/lib/php/UNL/Templates/Version2/Liquid.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Template Definition for liquid.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ * 
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Liquid width template object
+ * 
+ * @package UNL_Templates
+ *
+ */
+class UNL_Templates_Version2_Liquid extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Liquid.tpl';                      // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<script type=\"text/javascript\"> var navl2Links = 0; //Default navline2 links to display (zero based counting) </script>";                           // string()  
+    public $breadcrumbs = "<!-- WDN: see glossary item \'breadcrumbs\' --> <ul> <li class=\"first\"><a href=\"http://www.unl.edu/\">UNL</a></li> <li><a href=\"http://www.unl.edu/\">Department</a></li> <li>New Page</li> </ul>";                    // string()  
+    public $collegenavigationlist = "";          // string()  
+    public $titlegraphic = "<h1>Department</h1> <h2>Taglines - We Do The Heavy Lifting</h2>";                   // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $leftRandomPromo = "<div class=\"image_small_short\" id=\"leftRandomPromo\"> <a href=\"#\" id=\"leftRandomPromoAnchor\"><img id=\"leftRandomPromoImage\" alt=\"\" src=\"/ucomm/templatedependents/templatecss/images/transpixel.gif\" /></a> <script type=\"text/javascript\" src=\"../sharedcode/leftRandomPromo.js\"></script> </div>";                // string()  
+    public $leftcollinks = "<!-- WDN: see glossary item \'sidebar links\' --> <!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $maincontentarea = "<p style=\"margin:20px; border:3px solid #CC0000;padding:10px; text-align:center\"> <strong>Delete this box and place your content here.</strong><br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://www.unl.edu/webdevnet/\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Click here to check Validation</a> </p>";                // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version2_Liquid',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version2/Popup.php b/lib/php/UNL/Templates/Version2/Popup.php
new file mode 100644
index 00000000..44e5f823
--- /dev/null
+++ b/lib/php/UNL/Templates/Version2/Popup.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Template Definition for popup.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * popup template object
+ * 
+ * @package UNL_Templates
+ *
+ */
+class UNL_Templates_Version2_Popup extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Popup.tpl';                       // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<script type=\"text/javascript\"> var navl2Links = 0; //Default navline2 links to display (zero based counting) </script>";                           // string()  
+    public $collegenavigationlist = "";          // string()  
+    public $titlegraphic = "<h1>Department</h1> <h2>Taglines - We Do The Heavy Lifting</h2>";                   // string()  
+    public $maincontentarea = "<p style=\"margin:20px; border:3px solid #CC0000;padding:10px; text-align:center\"> <strong>Delete this box and place your content here.</strong><br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://www.unl.edu/webdevnet/\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Click here to check Validation</a> </p>";                // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version2_Popup',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version2/Secure.php b/lib/php/UNL/Templates/Version2/Secure.php
new file mode 100644
index 00000000..90ac4755
--- /dev/null
+++ b/lib/php/UNL/Templates/Version2/Secure.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Template Definition for secure.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Secure template object
+ * 
+ * @package UNL_Templates
+ *
+ */
+class UNL_Templates_Version2_Secure extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Secure.tpl';                      // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<script type=\"text/javascript\"> var navl2Links = 0; //Default navline2 links to display (zero based counting) </script>";                           // string()  
+    public $breadcrumbs = "<!-- WDN: see glossary item \'breadcrumbs\' --> <ul> <li class=\"first\"><a href=\"http://www.unl.edu/\">UNL</a></li> <li><a href=\"http://www.unl.edu/\">Department</a></li> <li>New Page</li> </ul> <!--#include virtual=\"/ucomm/templatedependents/templatesharedcode/includes/badges/secure.html\" -->";                    // string()  
+    public $collegenavigationlist = "";          // string()  
+    public $titlegraphic = "<h1>Department</h1> <h2>Taglines - We Do The Heavy Lifting</h2>";                   // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $leftcollinks = "<!-- WDN: see glossary item \'sidebar links\' --> <!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $maincontentarea = "<p style=\"margin:20px; border:3px solid #CC0000;padding:10px; text-align:center\"> <strong>Delete this box and place your content here.</strong><br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://www.unl.edu/webdevnet/\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Click here to check Validation</a> </p>";                // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version2_Secure',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version2/Unlaffiliate.php b/lib/php/UNL/Templates/Version2/Unlaffiliate.php
new file mode 100644
index 00000000..194231ae
--- /dev/null
+++ b/lib/php/UNL/Templates/Version2/Unlaffiliate.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Template Definition for unlaffiliate.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+class UNL_Templates_Version2_Unlaffiliate extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Unlaffiliate.tpl';                // template name
+    public $doctitle = "<title>UNL Redesign</title>";                       // string()  
+    public $head = "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\"/ucomm/templatedependents/templatecss/layouts/affiliate.css\" />";                           // string()  
+    public $siteheader = "<!--#include virtual=\"/ucomm/templatedependents/templatesharedcode/includes/siteheader/affiliate.shtml\" -->";                     // string()  
+    public $breadcrumbs = "<!-- WDN: see glossary item \'breadcrumbs\' --> <ul> <li class=\"first\"><a href=\"http://www.unl.edu/\">UNL</a></li> <li>UNL Framework</li> </ul>";                    // string()  
+    public $shelf = "";                          // string()  
+    public $titlegraphic = "<h1>Affiliate</h1> <h2>Taglines - We Do The Heavy Lifting</h2>";                   // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $leftRandomPromo = "<div class=\"image_small_short\" id=\"leftRandomPromo\"> <a href=\"#\" id=\"leftRandomPromoAnchor\"><img id=\"leftRandomPromoImage\" alt=\"\" src=\"/ucomm/templatedependents/templatecss/images/transpixel.gif\" /></a> <script type=\"text/javascript\" src=\"../sharedcode/leftRandomPromo.js\"></script> </div>";                // string()  
+    public $leftcollinks = "<!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $maincontentarea = "<h2 class=\"sec_main\">This template is only for affiliates of UNL, or units that have been granted a marketing exemption from the university. Confirm your use of this template before using it!</h2> <p style=\"margin:20px; border:3px solid #CC0000;padding:10px; text-align:center\"> <strong>Delete this box and place your content here.</strong><br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://www.unl.edu/webdevnet/\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Click here to check Validation</a> </p> <!--THIS IS THE END OF THE MAIN CONTENT AREA.-->";                // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version2_Unlaffiliate',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version2/Unlframework.php b/lib/php/UNL/Templates/Version2/Unlframework.php
new file mode 100644
index 00000000..47b42616
--- /dev/null
+++ b/lib/php/UNL/Templates/Version2/Unlframework.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Template Definition for unlframework.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Unlframework template object
+ * 
+ * @package UNL_Templates
+ *
+ */
+class UNL_Templates_Version2_Unlframework extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Unlframework.tpl';                // template name
+    public $doctitle = "<title>UNL Redesign</title>";                       // string()  
+    public $head = "<!--#include virtual=\"/ucomm/templatedependents/templatesharedcode/includes/browsersniffers/ie.html\" --> <!--#include virtual=\"/ucomm/templatedependents/templatesharedcode/includes/comments/developersnote.html\" --> <!--#include virtual=\"/ucomm/templatedependents/templatesharedcode/includes/metanfavico/metanfavico.html\" -->";                           // string()  
+    public $siteheader = "<!--#include virtual=\"/ucomm/templatedependents/templatesharedcode/includes/siteheader/siteheader.shtml\" -->";                     // string()  
+    public $breadcrumbs = "<!-- WDN: see glossary item \'breadcrumbs\' --> <ul> <li class=\"first\"><a href=\"http://www.unl.edu/\">UNL</a></li> <li>UNL Framework</li> </ul>";                    // string()  
+    public $shelf = "<!--#include virtual=\"/ucomm/templatedependents/templatesharedcode/includes/shelf/shelf.shtml\" -->";                          // string()  
+    public $collegenavigationlist = "";          // string()  
+    public $titlegraphic = "<h1>Department</h1> <h2>Taglines - We Do The Heavy Lifting</h2>";                   // string()  
+    public $leftcolcontent = "<div id=\"navigation\"> <h4 id=\"sec_nav\">Navigation</h4> <div id=\"navlinks\"> <!--#include virtual=\"../sharedcode/navigation.html\" --> </div> <div id=\"nav_end\"></div> <div class=\"image_small_short\" id=\"leftRandomPromo\"> <a href=\"#\" id=\"leftRandomPromoAnchor\"><img id=\"leftRandomPromoImage\" alt=\"\" src=\"/ucomm/templatedependents/templatecss/images/transpixel.gif\" /></a> <script type=\"text/javascript\" src=\"../sharedcode/leftRandomPromo.js\"></script> </div> <!-- WDN: see glossary item \'sidebar links\' --> <div id=\"leftcollinks\"> <!--#include virtual=\"../sharedcode/relatedLinks.html\" --> </div> </div> <!-- close navigation -->";                 // string()  
+    public $maincolcontent = "<!-- optional main big content image --> <div id=\"maincontent\"> <p style=\"margin:20px; border:3px solid #CC0000;padding:10px; text-align:center\"> <strong>Delete this box and place your content here.</strong><br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://www.unl.edu/webdevnet/\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Click here to check Validation</a> </p> </div> <!-- close right-area -->";                 // string()  
+    public $bigfooter = "<div id=\"footer\"> <div id=\"footer_floater\"> <div id=\"copyright\"> <!--#include virtual=\"../sharedcode/footer.html\" --> <span><a href=\"http://jigsaw.w3.org/css-validator/check/referer\">CSS</a> <a href=\"http://validator.unl.edu/check/referer\">W3C</a> <a href=\"http://www1.unl.edu/feeds/\">RSS</a> </span><a href=\"http://www.unl.edu/\" title=\"UNL Home\"><img src=\"/ucomm/templatedependents/templatecss/images/wordmark.png\" alt=\"UNL\'s wordmark\" id=\"wordmark\" /></a></div> </div> </div>";                      // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version2_Unlframework',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version2/Unlstandardtemplate.php b/lib/php/UNL/Templates/Version2/Unlstandardtemplate.php
new file mode 100644
index 00000000..5aff6955
--- /dev/null
+++ b/lib/php/UNL/Templates/Version2/Unlstandardtemplate.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Template Definition for unlstandardtemplate.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Unlstandardtemplate object
+ * 
+ * @package UNL_Templates
+ *
+ */
+class UNL_Templates_Version2_Unlstandardtemplate extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Unlstandardtemplate.tpl';         // template name
+    public $doctitle = "<title>UNL Redesign</title>";                       // string()  
+    public $head = "";                           // string()  
+    public $siteheader = "<!--#include virtual=\"/ucomm/templatedependents/templatesharedcode/includes/siteheader/siteheader.shtml\" -->";                     // string()  
+    public $breadcrumbs = "<ul> <li class=\"first\"><a href=\"http://www.unl.edu/\">UNL</a></li> <li>UNL Standard Template</li> </ul>";                    // string()  
+    public $shelf = "<!--#include virtual=\"/ucomm/templatedependents/templatesharedcode/includes/shelf/shelf.shtml\" -->";                          // string()  
+    public $collegenavigationlist = "";          // string()  
+    public $titlegraphic = "<h1>Department</h1> <h2>Taglines - We Do The Heavy Lifting</h2>";                   // string()  
+    public $navcontent = "<div id=\"navlinks\"> <!--#include virtual=\"../sharedcode/navigation.html\" --> </div>";                     // string()  
+    public $leftRandomPromo = "<div class=\"image_small_short\" id=\"leftRandomPromo\"> <a href=\"#\" id=\"leftRandomPromoAnchor\"><img id=\"leftRandomPromoImage\" alt=\"\" src=\"/ucomm/templatedependents/templatecss/images/transpixel.gif\" /></a> <script type=\"text/javascript\" src=\"../sharedcode/leftRandomPromo.js\"></script> </div>";                // string()  
+    public $leftcollinks = "<h3>Related Links</h3> <!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $maincontent = "<p style=\"margin:20px; border:3px solid #CC0000;padding:10px; text-align:center\"> <strong>Delete this box and place your content here.</strong><br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://www.unl.edu/webdevnet/\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Click here to check Validation</a> </p>";                    // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version2_Unlstandardtemplate',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version3.php b/lib/php/UNL/Templates/Version3.php
new file mode 100644
index 00000000..b55f6709
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Base class for Version 3 (2009) template files.
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates/Version.php';
+
+/**
+ * Base class for Version 3 (2009) template files.
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @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/
+ */
+class UNL_Templates_Version3 implements UNL_Templates_Version
+{ 
+    function getConfig()
+    {
+        return array('class_location' => 'UNL/Templates/Version3/',
+                     'class_prefix'   => 'UNL_Templates_Version3_');
+    }
+    
+    function getTemplate($template)
+    {
+        if (!file_exists(UNL_Templates::$options['templatedependentspath'].'/wdn/templates_3.0')) {
+            UNL_Templates::debug('ERROR You should have a local copy of wdn/templates_3.0!'
+                                 . ' Overriding your specified template to use absolute references' ,
+                                 'getTemplate', 1);
+            $template = 'Absolute.tpl';
+        }
+        return file_get_contents('http://pear.unl.edu/UNL/Templates/server.php?version=3&template='.$template);
+    }
+    
+    function makeIncludeReplacements($html)
+    {
+        UNL_Templates::debug('Now making template include replacements.',
+                     'makeIncludeReplacements', 3);
+        $includes = array();
+        preg_match_all('<!--#include virtual="(/wdn/templates_3.0/[A-Za-z0-9\.\/]+)" -->',
+                        $html, $includes);
+        UNL_Templates::debug(print_r($includes, true), 'makeIncludeReplacements', 3);
+        foreach ($includes[1] as $include) {
+            UNL_Templates::debug('Replacing '.$include, 'makeIncludeReplacements', 3);
+            $file = UNL_Templates::$options['templatedependentspath'].$include;
+            if (!file_exists($file)) {
+                UNL_Templates::debug('File does not exist:'.$file,
+                             'makeIncludeReplacements', 3);
+                $file = 'http://www.unl.edu'.$include;
+            }
+            $html = str_replace('<!--#include virtual="'.$include.'" -->',
+                                 file_get_contents($file), $html);
+        }
+        return $html;
+    }
+}
diff --git a/lib/php/UNL/Templates/Version3/Absolute.php b/lib/php/UNL/Templates/Version3/Absolute.php
new file mode 100644
index 00000000..3a7f120b
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3/Absolute.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Template Definition for absolute.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Template Definition for absolute.dwt
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @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/
+ */
+class UNL_Templates_Version3_Absolute extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Absolute.tpl';                    // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<!-- Place optional header elements here -->";                           // string()  
+    public $breadcrumbs = "<ul> <li><a href=\"http://www.unl.edu/\" title=\"University of Nebraska&ndash;Lincoln\">UNL</a></li> <li>Department</li> </ul>";                    // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $titlegraphic = "<h1>Department</h1>";                   // string()  
+    public $pagetitle = "";                      // string()  
+    public $maincontentarea = "<p>Place your content here.<br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://wdn.unl.edu//\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Check this page</a> </p>";                // string()  
+    public $leftcollinks = "<!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $contactinfo = "<!--#include virtual=\"../sharedcode/footerContactInfo.html\" -->";                    // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version3_Absolute',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version3/Debug.php b/lib/php/UNL/Templates/Version3/Debug.php
new file mode 100644
index 00000000..2a8e34e5
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3/Debug.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Template Definition for debug.dwt
+ */
+require_once 'UNL/Templates.php';
+
+class UNL_Templates_Version3_Debug extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Debug.tpl';                       // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<!-- Place optional header elements here -->";                           // string()  
+    public $breadcrumbs = "<ul> <li><a href=\"http://www.unl.edu/\" title=\"University of Nebraska&ndash;Lincoln\">UNL</a></li> <li>Department</li> </ul>";                    // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $titlegraphic = "<h1>Department</h1>";                   // string()  
+    public $pagetitle = "";                      // string()  
+    public $maincontentarea = "<p>Place your content here.<br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://wdn.unl.edu//\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Check this page</a> </p>";                // string()  
+    public $leftcollinks = "<!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $contactinfo = "<!--#include virtual=\"../sharedcode/footerContactInfo.html\" -->";                    // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version3_Debug',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version3/Document.php b/lib/php/UNL/Templates/Version3/Document.php
new file mode 100644
index 00000000..efc45819
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3/Document.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Template Definition for document.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Template Definition for document.dwt
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @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/
+ */
+class UNL_Templates_Version3_Document extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Document.tpl';                    // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<!-- Place optional header elements here -->";                           // string()  
+    public $breadcrumbs = "<ul> <li><a href=\"http://www.unl.edu/\" title=\"University of Nebraska&ndash;Lincoln\">UNL</a></li> <li>Department</li> </ul>";                    // string()  
+    public $titlegraphic = "<h1>Department</h1>";                   // string()  
+    public $pagetitle = "";                      // string()  
+    public $maincontentarea = "<p>Place your content here.<br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://wdn.unl.edu//\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Check this page</a> </p>";                // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version3_Document',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version3/Fixed.php b/lib/php/UNL/Templates/Version3/Fixed.php
new file mode 100644
index 00000000..5f7a566d
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3/Fixed.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Template Definition for fixed.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Template Definition for fixed.dwt
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @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/
+ */
+class UNL_Templates_Version3_Fixed extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Fixed.tpl';                       // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<!-- Place optional header elements here -->";                           // string()  
+    public $breadcrumbs = "<ul> <li><a href=\"http://www.unl.edu/\" title=\"University of Nebraska&ndash;Lincoln\">UNL</a></li> <li>Department</li> </ul>";                    // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $titlegraphic = "<h1>Department</h1>";                   // string()  
+    public $pagetitle = "";                      // string()  
+    public $maincontentarea = "<p>Place your content here.<br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://wdn.unl.edu//\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Check this page</a> </p>";                // string()  
+    public $leftcollinks = "<!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $contactinfo = "<!--#include virtual=\"../sharedcode/footerContactInfo.html\" -->";                    // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version3_Fixed',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version3/Liquid.php b/lib/php/UNL/Templates/Version3/Liquid.php
new file mode 100644
index 00000000..065d3fc6
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3/Liquid.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Template Definition for liquid.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Template Definition for liquid.dwt
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @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/
+ */
+class UNL_Templates_Version3_Liquid extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Liquid.tpl';                      // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<!-- Place optional header elements here -->";                           // string()  
+    public $breadcrumbs = "<ul> <li><a href=\"http://www.unl.edu/\" title=\"University of Nebraska&ndash;Lincoln\">UNL</a></li> <li>Department</li> </ul>";                    // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $titlegraphic = "<h1>Department</h1>";                   // string()  
+    public $pagetitle = "";                      // string()  
+    public $maincontentarea = "<p>Place your content here.<br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://wdn.unl.edu//\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Check this page</a> </p>";                // string()  
+    public $leftcollinks = "<!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $contactinfo = "<!--#include virtual=\"../sharedcode/footerContactInfo.html\" -->";                    // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version3_Liquid',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version3/Popup.php b/lib/php/UNL/Templates/Version3/Popup.php
new file mode 100644
index 00000000..f8a9cb83
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3/Popup.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Template Definition for popup.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Template Definition for popup.dwt
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @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/
+ */
+class UNL_Templates_Version3_Popup extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Popup.tpl';                       // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<!-- Place optional header elements here -->";                           // string()  
+    public $titlegraphic = "<h1>Department</h1>";                   // string()  
+    public $pagetitle = "";                      // string()  
+    public $maincontentarea = "<p>Place your content here.<br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://wdn.unl.edu//\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Check this page</a> </p>";                // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version3_Popup',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version3/Secure.php b/lib/php/UNL/Templates/Version3/Secure.php
new file mode 100644
index 00000000..21a45250
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3/Secure.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Template Definition for secure.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Template Definition for secure.dwt
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @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/
+ */
+class UNL_Templates_Version3_Secure extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Secure.tpl';                      // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<!-- Place optional header elements here -->";                           // string()  
+    public $identitymanagement = "<a href=\"https://login.unl.edu/cas/logout\">Logout</a>";             // string()  
+    public $breadcrumbs = "<ul> <li><a href=\"http://www.unl.edu/\" title=\"University of Nebraska&ndash;Lincoln\">UNL</a></li> <li>Department</li> </ul>";                    // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $titlegraphic = "<h1>Department</h1>";                   // string()  
+    public $pagetitle = "";                      // string()  
+    public $maincontentarea = "<p>Place your content here.<br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://wdn.unl.edu//\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Check this page</a> </p>";                // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version3_Secure',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version3/Shared_column_left.php b/lib/php/UNL/Templates/Version3/Shared_column_left.php
new file mode 100644
index 00000000..af770692
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3/Shared_column_left.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Template Definition for shared_column_left.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Template definition for shared_column_left.dwt
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @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/
+ */
+class UNL_Templates_Version3_Shared_column_left extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Shared_column_left.tpl';          // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<!-- Place optional header elements here -->";                           // string()  
+    public $breadcrumbs = "<ul> <li><a href=\"http://www.unl.edu/\" title=\"University of Nebraska&ndash;Lincoln\">UNL</a></li> <li>Department</li> </ul>";                    // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $titlegraphic = "<h1>Department</h1>";                   // string()  
+    public $pagetitle = "";                      // string()  
+    public $sharedcolumn = "<div class=\"col left\"> <!--#include virtual=\"../sharedcode/sharedColumn.html\" --> </div>";                   // string()  
+    public $maincontentarea = "<p>Place your content here.<br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://wdn.unl.edu//\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Check this page</a> </p>";                // string()  
+    public $leftcollinks = "<!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $contactinfo = "<!--#include virtual=\"../sharedcode/footerContactInfo.html\" -->";                    // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version3_Shared_column_left',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/UNL/Templates/Version3/Shared_column_right.php b/lib/php/UNL/Templates/Version3/Shared_column_right.php
new file mode 100644
index 00000000..00247c20
--- /dev/null
+++ b/lib/php/UNL/Templates/Version3/Shared_column_right.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Template Definition for shared_column_right.dwt
+ * 
+ * PHP version 5
+ *  
+ * @category  Templates
+ * @package   UNL_Templates
+ * @author    Brett Bieber <brett.bieber@gmail.com>
+ * @author    Ned Hummel <nhummel2@unl.edu>
+ * @copyright 2009 Regents of the University of Nebraska
+ * @license   http://www1.unl.edu/wdn/wiki/Software_License BSD License
+ * @link      http://pear.unl.edu/
+ */
+require_once 'UNL/Templates.php';
+
+/**
+ * Template Definition for shared_column_right.dwt
+ * 
+ * @category  Templates
+ * @package   UNL_Templates
+ * @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/
+ */
+class UNL_Templates_Version3_Shared_column_right extends UNL_Templates 
+{
+    ###START_AUTOCODE
+    /* the code below is auto generated do not remove the above tag */
+
+    public $__template = 'Shared_column_right.tpl';         // template name
+    public $doctitle = "<title>UNL | Department | New Page</title>";                       // string()  
+    public $head = "<!-- Place optional header elements here -->";                           // string()  
+    public $breadcrumbs = "<ul> <li><a href=\"http://www.unl.edu/\" title=\"University of Nebraska&ndash;Lincoln\">UNL</a></li> <li>Department</li> </ul>";                    // string()  
+    public $navlinks = "<!--#include virtual=\"../sharedcode/navigation.html\" -->";                       // string()  
+    public $titlegraphic = "<h1>Department</h1>";                   // string()  
+    public $pagetitle = "";                      // string()  
+    public $maincontentarea = "<p>Place your content here.<br /> Remember to validate your pages before publishing! Sample layouts are available through the <a href=\"http://wdn.unl.edu//\">Web Developer Network</a>. <br /> <a href=\"http://validator.unl.edu/check/referer\">Check this page</a> </p>";                // string()  
+    public $sharedcolumn = "<div class=\"col right\"> <!--#include virtual=\"../sharedcode/sharedColumn.html\" --> </div>";                   // string()  
+    public $leftcollinks = "<!--#include virtual=\"../sharedcode/relatedLinks.html\" -->";                   // string()  
+    public $contactinfo = "<!--#include virtual=\"../sharedcode/footerContactInfo.html\" -->";                    // string()  
+    public $optionalfooter = "";                 // string()  
+    public $footercontent = "<!--#include virtual=\"../sharedcode/footer.html\" -->";                  // string()  
+
+    /* Static get */
+    function staticGet($k,$v=NULL) { return UNL_DWT::staticGet('UNL_Templates_Version3_Shared_column_right',$k,$v); }
+
+    /* the code above is auto generated do not remove the tag below */
+    ###END_AUTOCODE
+}
diff --git a/lib/php/XML/Util.php b/lib/php/XML/Util.php
new file mode 100644
index 00000000..f5927b16
--- /dev/null
+++ b/lib/php/XML/Util.php
@@ -0,0 +1,911 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * XML_Util
+ *
+ * XML Utilities package
+ * 
+ * PHP versions 4 and 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2003-2008 Stephan Schmidt <schst@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 name of the author 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  XML
+ * @package   XML_Util
+ * @author    Stephan Schmidt <schst@php.net>
+ * @copyright 2003-2008 Stephan Schmidt <schst@php.net>
+ * @license   http://opensource.org/licenses/bsd-license New BSD License
+ * @version   CVS: $Id: Util.php,v 1.38 2008/11/13 00:03:38 ashnazg Exp $
+ * @link      http://pear.php.net/package/XML_Util
+ */
+
+/**
+ * error code for invalid chars in XML name
+ */
+define('XML_UTIL_ERROR_INVALID_CHARS', 51);
+
+/**
+ * error code for invalid chars in XML name
+ */
+define('XML_UTIL_ERROR_INVALID_START', 52);
+
+/**
+ * error code for non-scalar tag content
+ */
+define('XML_UTIL_ERROR_NON_SCALAR_CONTENT', 60);
+
+/**
+ * error code for missing tag name
+ */
+define('XML_UTIL_ERROR_NO_TAG_NAME', 61);
+
+/**
+ * replace XML entities
+ */
+define('XML_UTIL_REPLACE_ENTITIES', 1);
+
+/**
+ * embedd content in a CData Section
+ */
+define('XML_UTIL_CDATA_SECTION', 5);
+
+/**
+ * do not replace entitites
+ */
+define('XML_UTIL_ENTITIES_NONE', 0);
+
+/**
+ * replace all XML entitites
+ * This setting will replace <, >, ", ' and &
+ */
+define('XML_UTIL_ENTITIES_XML', 1);
+
+/**
+ * replace only required XML entitites
+ * This setting will replace <, " and &
+ */
+define('XML_UTIL_ENTITIES_XML_REQUIRED', 2);
+
+/**
+ * replace HTML entitites
+ * @link http://www.php.net/htmlentities
+ */
+define('XML_UTIL_ENTITIES_HTML', 3);
+
+/**
+ * Collapse all empty tags.
+ */
+define('XML_UTIL_COLLAPSE_ALL', 1);
+
+/**
+ * Collapse only empty XHTML tags that have no end tag.
+ */
+define('XML_UTIL_COLLAPSE_XHTML_ONLY', 2);
+
+/**
+ * utility class for working with XML documents
+ *
+
+ * @category  XML
+ * @package   XML_Util
+ * @author    Stephan Schmidt <schst@php.net>
+ * @copyright 2003-2008 Stephan Schmidt <schst@php.net>
+ * @license   http://opensource.org/licenses/bsd-license New BSD License
+ * @version   Release: 1.2.1
+ * @link      http://pear.php.net/package/XML_Util
+ */
+class XML_Util
+{
+    /**
+     * return API version
+     *
+     * @return string $version API version
+     * @access public
+     * @static
+     */
+    function apiVersion()
+    {
+        return '1.1';
+    }
+
+    /**
+     * replace XML entities
+     *
+     * With the optional second parameter, you may select, which
+     * entities should be replaced.
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // replace XML entites:
+     * $string = XML_Util::replaceEntities('This string contains < & >.');
+     * </code>
+     *
+     * With the optional third parameter, you may pass the character encoding
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // replace XML entites in UTF-8:
+     * $string = XML_Util::replaceEntities(
+     *     'This string contains < & > as well as ä, ö, ß, à and ê',
+     *     XML_UTIL_ENTITIES_HTML,
+     *     'UTF-8'
+     * );
+     * </code>
+     *
+     * @param string $string          string where XML special chars 
+     *                                should be replaced
+     * @param int    $replaceEntities setting for entities in attribute values 
+     *                                (one of XML_UTIL_ENTITIES_XML, 
+     *                                XML_UTIL_ENTITIES_XML_REQUIRED, 
+     *                                XML_UTIL_ENTITIES_HTML)
+     * @param string $encoding        encoding value (if any)...
+     *                                must be a valid encoding as determined
+     *                                by the htmlentities() function
+     *
+     * @return string string with replaced chars
+     * @access public
+     * @static
+     * @see reverseEntities()
+     */
+    function replaceEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML,
+        $encoding = 'ISO-8859-1')
+    {
+        switch ($replaceEntities) {
+        case XML_UTIL_ENTITIES_XML:
+            return strtr($string, array(
+                '&'  => '&amp;',
+                '>'  => '&gt;',
+                '<'  => '&lt;',
+                '"'  => '&quot;',
+                '\'' => '&apos;' ));
+            break;
+        case XML_UTIL_ENTITIES_XML_REQUIRED:
+            return strtr($string, array(
+                '&' => '&amp;',
+                '<' => '&lt;',
+                '"' => '&quot;' ));
+            break;
+        case XML_UTIL_ENTITIES_HTML:
+            return htmlentities($string, ENT_COMPAT, $encoding);
+            break;
+        }
+        return $string;
+    }
+
+    /**
+     * reverse XML entities
+     *
+     * With the optional second parameter, you may select, which
+     * entities should be reversed.
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // reverse XML entites:
+     * $string = XML_Util::reverseEntities('This string contains &lt; &amp; &gt;.');
+     * </code>
+     *
+     * With the optional third parameter, you may pass the character encoding
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // reverse XML entites in UTF-8:
+     * $string = XML_Util::reverseEntities(
+     *     'This string contains &lt; &amp; &gt; as well as'
+     *     . ' &auml;, &ouml;, &szlig;, &agrave; and &ecirc;',
+     *     XML_UTIL_ENTITIES_HTML,
+     *     'UTF-8'
+     * );
+     * </code>
+     *
+     * @param string $string          string where XML special chars 
+     *                                should be replaced
+     * @param int    $replaceEntities setting for entities in attribute values 
+     *                                (one of XML_UTIL_ENTITIES_XML, 
+     *                                XML_UTIL_ENTITIES_XML_REQUIRED, 
+     *                                XML_UTIL_ENTITIES_HTML)
+     * @param string $encoding        encoding value (if any)...
+     *                                must be a valid encoding as determined
+     *                                by the html_entity_decode() function
+     *
+     * @return string string with replaced chars
+     * @access public
+     * @static
+     * @see replaceEntities()
+     */
+    function reverseEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML,
+        $encoding = 'ISO-8859-1')
+    {
+        switch ($replaceEntities) {
+        case XML_UTIL_ENTITIES_XML:
+            return strtr($string, array(
+                '&amp;'  => '&',
+                '&gt;'   => '>',
+                '&lt;'   => '<',
+                '&quot;' => '"',
+                '&apos;' => '\'' ));
+            break;
+        case XML_UTIL_ENTITIES_XML_REQUIRED:
+            return strtr($string, array(
+                '&amp;'  => '&',
+                '&lt;'   => '<',
+                '&quot;' => '"' ));
+            break;
+        case XML_UTIL_ENTITIES_HTML:
+            return html_entity_decode($string, ENT_COMPAT, $encoding);
+            break;
+        }
+        return $string;
+    }
+
+    /**
+     * build an xml declaration
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // get an XML declaration:
+     * $xmlDecl = XML_Util::getXMLDeclaration('1.0', 'UTF-8', true);
+     * </code>
+     *
+     * @param string $version    xml version
+     * @param string $encoding   character encoding
+     * @param bool   $standalone document is standalone (or not)
+     *
+     * @return string xml declaration
+     * @access public
+     * @static
+     * @uses attributesToString() to serialize the attributes of the XML declaration
+     */
+    function getXMLDeclaration($version = '1.0', $encoding = null, 
+        $standalone = null)
+    {
+        $attributes = array(
+            'version' => $version,
+        );
+        // add encoding
+        if ($encoding !== null) {
+            $attributes['encoding'] = $encoding;
+        }
+        // add standalone, if specified
+        if ($standalone !== null) {
+            $attributes['standalone'] = $standalone ? 'yes' : 'no';
+        }
+
+        return sprintf('<?xml%s?>', 
+            XML_Util::attributesToString($attributes, false));
+    }
+
+    /**
+     * build a document type declaration
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // get a doctype declaration:
+     * $xmlDecl = XML_Util::getDocTypeDeclaration('rootTag','myDocType.dtd');
+     * </code>
+     *
+     * @param string $root        name of the root tag
+     * @param string $uri         uri of the doctype definition 
+     *                            (or array with uri and public id)
+     * @param string $internalDtd internal dtd entries
+     *
+     * @return string doctype declaration
+     * @access public
+     * @static
+     * @since 0.2
+     */
+    function getDocTypeDeclaration($root, $uri = null, $internalDtd = null)
+    {
+        if (is_array($uri)) {
+            $ref = sprintf(' PUBLIC "%s" "%s"', $uri['id'], $uri['uri']);
+        } elseif (!empty($uri)) {
+            $ref = sprintf(' SYSTEM "%s"', $uri);
+        } else {
+            $ref = '';
+        }
+
+        if (empty($internalDtd)) {
+            return sprintf('<!DOCTYPE %s%s>', $root, $ref);
+        } else {
+            return sprintf("<!DOCTYPE %s%s [\n%s\n]>", $root, $ref, $internalDtd);
+        }
+    }
+
+    /**
+     * create string representation of an attribute list
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // build an attribute string
+     * $att = array(
+     *              'foo'   =>  'bar',
+     *              'argh'  =>  'tomato'
+     *            );
+     *
+     * $attList = XML_Util::attributesToString($att);
+     * </code>
+     *
+     * @param array      $attributes attribute array
+     * @param bool|array $sort       sort attribute list alphabetically, 
+     *                               may also be an assoc array containing 
+     *                               the keys 'sort', 'multiline', 'indent', 
+     *                               'linebreak' and 'entities'
+     * @param bool       $multiline  use linebreaks, if more than 
+     *                               one attribute is given
+     * @param string     $indent     string used for indentation of 
+     *                               multiline attributes
+     * @param string     $linebreak  string used for linebreaks of 
+     *                               multiline attributes
+     * @param int        $entities   setting for entities in attribute values 
+     *                               (one of XML_UTIL_ENTITIES_NONE, 
+     *                               XML_UTIL_ENTITIES_XML, 
+     *                               XML_UTIL_ENTITIES_XML_REQUIRED, 
+     *                               XML_UTIL_ENTITIES_HTML)
+     *
+     * @return string string representation of the attributes
+     * @access public
+     * @static
+     * @uses replaceEntities() to replace XML entities in attribute values
+     * @todo allow sort also to be an options array
+     */
+    function attributesToString($attributes, $sort = true, $multiline = false, 
+        $indent = '    ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML)
+    {
+        /*
+         * second parameter may be an array
+         */
+        if (is_array($sort)) {
+            if (isset($sort['multiline'])) {
+                $multiline = $sort['multiline'];
+            }
+            if (isset($sort['indent'])) {
+                $indent = $sort['indent'];
+            }
+            if (isset($sort['linebreak'])) {
+                $multiline = $sort['linebreak'];
+            }
+            if (isset($sort['entities'])) {
+                $entities = $sort['entities'];
+            }
+            if (isset($sort['sort'])) {
+                $sort = $sort['sort'];
+            } else {
+                $sort = true;
+            }
+        }
+        $string = '';
+        if (is_array($attributes) && !empty($attributes)) {
+            if ($sort) {
+                ksort($attributes);
+            }
+            if ( !$multiline || count($attributes) == 1) {
+                foreach ($attributes as $key => $value) {
+                    if ($entities != XML_UTIL_ENTITIES_NONE) {
+                        if ($entities === XML_UTIL_CDATA_SECTION) {
+                            $entities = XML_UTIL_ENTITIES_XML;
+                        }
+                        $value = XML_Util::replaceEntities($value, $entities);
+                    }
+                    $string .= ' ' . $key . '="' . $value . '"';
+                }
+            } else {
+                $first = true;
+                foreach ($attributes as $key => $value) {
+                    if ($entities != XML_UTIL_ENTITIES_NONE) {
+                        $value = XML_Util::replaceEntities($value, $entities);
+                    }
+                    if ($first) {
+                        $string .= ' ' . $key . '="' . $value . '"';
+                        $first   = false;
+                    } else {
+                        $string .= $linebreak . $indent . $key . '="' . $value . '"';
+                    }
+                }
+            }
+        }
+        return $string;
+    }
+
+    /**
+     * Collapses empty tags.
+     *
+     * @param string $xml  XML
+     * @param int    $mode Whether to collapse all empty tags (XML_UTIL_COLLAPSE_ALL)
+     *                      or only XHTML (XML_UTIL_COLLAPSE_XHTML_ONLY) ones.
+     *
+     * @return string XML
+     * @access public
+     * @static
+     * @todo PEAR CS - unable to avoid "space after open parens" error
+     *       in the IF branch
+     */
+    function collapseEmptyTags($xml, $mode = XML_UTIL_COLLAPSE_ALL) 
+    {
+        if ($mode == XML_UTIL_COLLAPSE_XHTML_ONLY) {
+            return preg_replace(
+                '/<(area|base(?:font)?|br|col|frame|hr|img|input|isindex|link|meta|'
+                . 'param)([^>]*)><\/\\1>/s',
+                '<\\1\\2 />',
+                $xml);
+        } else {
+            return preg_replace('/<(\w+)([^>]*)><\/\\1>/s', '<\\1\\2 />', $xml);
+        }
+    }
+
+    /**
+     * create a tag
+     *
+     * This method will call XML_Util::createTagFromArray(), which
+     * is more flexible.
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // create an XML tag:
+     * $tag = XML_Util::createTag('myNs:myTag', 
+     *     array('foo' => 'bar'), 
+     *     'This is inside the tag', 
+     *     'http://www.w3c.org/myNs#');
+     * </code>
+     *
+     * @param string $qname           qualified tagname (including namespace)
+     * @param array  $attributes      array containg attributes
+     * @param mixed  $content         the content
+     * @param string $namespaceUri    URI of the namespace
+     * @param int    $replaceEntities whether to replace XML special chars in 
+     *                                content, embedd it in a CData section 
+     *                                or none of both
+     * @param bool   $multiline       whether to create a multiline tag where 
+     *                                each attribute gets written to a single line
+     * @param string $indent          string used to indent attributes 
+     *                                (_auto indents attributes so they start 
+     *                                at the same column)
+     * @param string $linebreak       string used for linebreaks
+     * @param bool   $sortAttributes  Whether to sort the attributes or not
+     *
+     * @return string XML tag
+     * @access public
+     * @static
+     * @see createTagFromArray()
+     * @uses createTagFromArray() to create the tag
+     */
+    function createTag($qname, $attributes = array(), $content = null, 
+        $namespaceUri = null, $replaceEntities = XML_UTIL_REPLACE_ENTITIES, 
+        $multiline = false, $indent = '_auto', $linebreak = "\n", 
+        $sortAttributes = true)
+    {
+        $tag = array(
+            'qname'      => $qname,
+            'attributes' => $attributes
+        );
+
+        // add tag content
+        if ($content !== null) {
+            $tag['content'] = $content;
+        }
+
+        // add namespace Uri
+        if ($namespaceUri !== null) {
+            $tag['namespaceUri'] = $namespaceUri;
+        }
+
+        return XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, 
+            $indent, $linebreak, $sortAttributes);
+    }
+
+    /**
+     * create a tag from an array
+     * this method awaits an array in the following format
+     * <pre>
+     * array(
+     *     // qualified name of the tag
+     *     'qname' => $qname        
+     *
+     *     // namespace prefix (optional, if qname is specified or no namespace)
+     *     'namespace' => $namespace    
+     *
+     *     // local part of the tagname (optional, if qname is specified)
+     *     'localpart' => $localpart,   
+     *
+     *     // array containing all attributes (optional)
+     *     'attributes' => array(),      
+     *
+     *     // tag content (optional)
+     *     'content' => $content,     
+     *
+     *     // namespaceUri for the given namespace (optional)
+     *     'namespaceUri' => $namespaceUri 
+     * )
+     * </pre>
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * $tag = array(
+     *     'qname'        => 'foo:bar',
+     *     'namespaceUri' => 'http://foo.com',
+     *     'attributes'   => array('key' => 'value', 'argh' => 'fruit&vegetable'),
+     *     'content'      => 'I\'m inside the tag',
+     * );
+     * // creating a tag with qualified name and namespaceUri
+     * $string = XML_Util::createTagFromArray($tag);
+     * </code>
+     *
+     * @param array  $tag             tag definition
+     * @param int    $replaceEntities whether to replace XML special chars in 
+     *                                content, embedd it in a CData section 
+     *                                or none of both
+     * @param bool   $multiline       whether to create a multiline tag where each 
+     *                                attribute gets written to a single line
+     * @param string $indent          string used to indent attributes 
+     *                                (_auto indents attributes so they start 
+     *                                at the same column)
+     * @param string $linebreak       string used for linebreaks
+     * @param bool   $sortAttributes  Whether to sort the attributes or not
+     *
+     * @return string XML tag
+     * @access public
+     * @static
+     * @see createTag()
+     * @uses attributesToString() to serialize the attributes of the tag
+     * @uses splitQualifiedName() to get local part and namespace of a qualified name
+     * @uses createCDataSection()
+     * @uses raiseError()
+     */
+    function createTagFromArray($tag, $replaceEntities = XML_UTIL_REPLACE_ENTITIES,
+        $multiline = false, $indent = '_auto', $linebreak = "\n", 
+        $sortAttributes = true)
+    {
+        if (isset($tag['content']) && !is_scalar($tag['content'])) {
+            return XML_Util::raiseError('Supplied non-scalar value as tag content',
+            XML_UTIL_ERROR_NON_SCALAR_CONTENT);
+        }
+
+        if (!isset($tag['qname']) && !isset($tag['localPart'])) {
+            return XML_Util::raiseError('You must either supply a qualified name '
+                . '(qname) or local tag name (localPart).', 
+                XML_UTIL_ERROR_NO_TAG_NAME);
+        }
+
+        // if no attributes hav been set, use empty attributes
+        if (!isset($tag['attributes']) || !is_array($tag['attributes'])) {
+            $tag['attributes'] = array();
+        }
+
+        if (isset($tag['namespaces'])) {
+            foreach ($tag['namespaces'] as $ns => $uri) {
+                $tag['attributes']['xmlns:' . $ns] = $uri;
+            }
+        }
+
+        if (!isset($tag['qname'])) {
+            // qualified name is not given
+
+            // check for namespace
+            if (isset($tag['namespace']) && !empty($tag['namespace'])) {
+                $tag['qname'] = $tag['namespace'] . ':' . $tag['localPart'];
+            } else {
+                $tag['qname'] = $tag['localPart'];
+            }
+        } elseif (isset($tag['namespaceUri']) && !isset($tag['namespace'])) {
+            // namespace URI is set, but no namespace
+
+            $parts = XML_Util::splitQualifiedName($tag['qname']);
+
+            $tag['localPart'] = $parts['localPart'];
+            if (isset($parts['namespace'])) {
+                $tag['namespace'] = $parts['namespace'];
+            }
+        }
+
+        if (isset($tag['namespaceUri']) && !empty($tag['namespaceUri'])) {
+            // is a namespace given
+            if (isset($tag['namespace']) && !empty($tag['namespace'])) {
+                $tag['attributes']['xmlns:' . $tag['namespace']] =
+                    $tag['namespaceUri'];
+            } else {
+                // define this Uri as the default namespace
+                $tag['attributes']['xmlns'] = $tag['namespaceUri'];
+            }
+        }
+
+        // check for multiline attributes
+        if ($multiline === true) {
+            if ($indent === '_auto') {
+                $indent = str_repeat(' ', (strlen($tag['qname'])+2));
+            }
+        }
+
+        // create attribute list
+        $attList = XML_Util::attributesToString($tag['attributes'], 
+            $sortAttributes, $multiline, $indent, $linebreak, $replaceEntities);
+        if (!isset($tag['content']) || (string)$tag['content'] == '') {
+            $tag = sprintf('<%s%s />', $tag['qname'], $attList);
+        } else {
+            switch ($replaceEntities) {
+            case XML_UTIL_ENTITIES_NONE:
+                break;
+            case XML_UTIL_CDATA_SECTION:
+                $tag['content'] = XML_Util::createCDataSection($tag['content']);
+                break;
+            default:
+                $tag['content'] = XML_Util::replaceEntities($tag['content'], 
+                    $replaceEntities);
+                break;
+            }
+            $tag = sprintf('<%s%s>%s</%s>', $tag['qname'], $attList, $tag['content'],
+                $tag['qname']);
+        }
+        return $tag;
+    }
+
+    /**
+     * create a start element
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // create an XML start element:
+     * $tag = XML_Util::createStartElement('myNs:myTag', 
+     *     array('foo' => 'bar') ,'http://www.w3c.org/myNs#');
+     * </code>
+     *
+     * @param string $qname          qualified tagname (including namespace)
+     * @param array  $attributes     array containg attributes
+     * @param string $namespaceUri   URI of the namespace
+     * @param bool   $multiline      whether to create a multiline tag where each 
+     *                               attribute gets written to a single line
+     * @param string $indent         string used to indent attributes (_auto indents
+     *                               attributes so they start at the same column)
+     * @param string $linebreak      string used for linebreaks
+     * @param bool   $sortAttributes Whether to sort the attributes or not
+     *
+     * @return string XML start element
+     * @access public
+     * @static
+     * @see createEndElement(), createTag()
+     */
+    function createStartElement($qname, $attributes = array(), $namespaceUri = null,
+        $multiline = false, $indent = '_auto', $linebreak = "\n", 
+        $sortAttributes = true)
+    {
+        // if no attributes hav been set, use empty attributes
+        if (!isset($attributes) || !is_array($attributes)) {
+            $attributes = array();
+        }
+
+        if ($namespaceUri != null) {
+            $parts = XML_Util::splitQualifiedName($qname);
+        }
+
+        // check for multiline attributes
+        if ($multiline === true) {
+            if ($indent === '_auto') {
+                $indent = str_repeat(' ', (strlen($qname)+2));
+            }
+        }
+
+        if ($namespaceUri != null) {
+            // is a namespace given
+            if (isset($parts['namespace']) && !empty($parts['namespace'])) {
+                $attributes['xmlns:' . $parts['namespace']] = $namespaceUri;
+            } else {
+                // define this Uri as the default namespace
+                $attributes['xmlns'] = $namespaceUri;
+            }
+        }
+
+        // create attribute list
+        $attList = XML_Util::attributesToString($attributes, $sortAttributes, 
+            $multiline, $indent, $linebreak);
+        $element = sprintf('<%s%s>', $qname, $attList);
+        return  $element;
+    }
+
+    /**
+     * create an end element
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // create an XML start element:
+     * $tag = XML_Util::createEndElement('myNs:myTag');
+     * </code>
+     *
+     * @param string $qname qualified tagname (including namespace)
+     *
+     * @return string XML end element
+     * @access public
+     * @static
+     * @see createStartElement(), createTag()
+     */
+    function createEndElement($qname)
+    {
+        $element = sprintf('</%s>', $qname);
+        return $element;
+    }
+
+    /**
+     * create an XML comment
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // create an XML start element:
+     * $tag = XML_Util::createComment('I am a comment');
+     * </code>
+     *
+     * @param string $content content of the comment
+     *
+     * @return string XML comment
+     * @access public
+     * @static
+     */
+    function createComment($content)
+    {
+        $comment = sprintf('<!-- %s -->', $content);
+        return $comment;
+    }
+
+    /**
+     * create a CData section
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // create a CData section
+     * $tag = XML_Util::createCDataSection('I am content.');
+     * </code>
+     *
+     * @param string $data data of the CData section
+     *
+     * @return string CData section with content
+     * @access public
+     * @static
+     */
+    function createCDataSection($data)
+    {
+        return sprintf('<![CDATA[%s]]>', 
+            preg_replace('/\]\]>/', ']]]]><![CDATA[>', strval($data)));
+
+    }
+
+    /**
+     * split qualified name and return namespace and local part
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // split qualified tag
+     * $parts = XML_Util::splitQualifiedName('xslt:stylesheet');
+     * </code>
+     * the returned array will contain two elements:
+     * <pre>
+     * array(
+     *     'namespace' => 'xslt',
+     *     'localPart' => 'stylesheet'
+     * );
+     * </pre>
+     *
+     * @param string $qname     qualified tag name
+     * @param string $defaultNs default namespace (optional)
+     *
+     * @return array array containing namespace and local part
+     * @access public
+     * @static
+     */
+    function splitQualifiedName($qname, $defaultNs = null)
+    {
+        if (strstr($qname, ':')) {
+            $tmp = explode(':', $qname);
+            return array(
+                'namespace' => $tmp[0],
+                'localPart' => $tmp[1]
+            );
+        }
+        return array(
+            'namespace' => $defaultNs,
+            'localPart' => $qname
+        );
+    }
+
+    /**
+     * check, whether string is valid XML name
+     *
+     * <p>XML names are used for tagname, attribute names and various
+     * other, lesser known entities.</p>
+     * <p>An XML name may only consist of alphanumeric characters,
+     * dashes, undescores and periods, and has to start with a letter
+     * or an underscore.</p>
+     *
+     * <code>
+     * require_once 'XML/Util.php';
+     *
+     * // verify tag name
+     * $result = XML_Util::isValidName('invalidTag?');
+     * if (is_a($result, 'PEAR_Error')) {
+     *    print 'Invalid XML name: ' . $result->getMessage();
+     * }
+     * </code>
+     *
+     * @param string $string string that should be checked
+     *
+     * @return mixed true, if string is a valid XML name, PEAR error otherwise
+     * @access public
+     * @static
+     * @todo support for other charsets
+     * @todo PEAR CS - unable to avoid 85-char limit on second preg_match
+     */
+    function isValidName($string)
+    {
+        // check for invalid chars
+        if (!preg_match('/^[[:alpha:]_]$/', $string{0})) {
+            return XML_Util::raiseError('XML names may only start with letter '
+                . 'or underscore', XML_UTIL_ERROR_INVALID_START);
+        }
+
+        // check for invalid chars
+        if (!preg_match('/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?[[:alpha:]_]([[:alnum:]\_\-\.]+)?$/',
+            $string)
+        ) {
+            return XML_Util::raiseError('XML names may only contain alphanumeric '
+                . 'chars, period, hyphen, colon and underscores', 
+                XML_UTIL_ERROR_INVALID_CHARS);
+        }
+        // XML name is valid
+        return true;
+    }
+
+    /**
+     * replacement for XML_Util::raiseError
+     *
+     * Avoids the necessity to always require
+     * PEAR.php
+     *
+     * @param string $msg  error message
+     * @param int    $code error code
+     *
+     * @return PEAR_Error
+     * @access public
+     * @static
+     * @todo PEAR CS - should this use include_once instead?
+     */
+    function raiseError($msg, $code)
+    {
+        require_once 'PEAR.php';
+        return PEAR::raiseError($msg, $code);
+    }
+}
+?>
diff --git a/lib/php/pearcmd.php b/lib/php/pearcmd.php
new file mode 100644
index 00000000..a26296ca
--- /dev/null
+++ b/lib/php/pearcmd.php
@@ -0,0 +1,445 @@
+<?php
+/**
+ * PEAR, the PHP Extension and Application Repository
+ *
+ * Command line interface
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: pearcmd.php 286487 2009-07-29 05:57:28Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ */
+
+ob_end_clean();
+if (!defined('PEAR_RUNTYPE')) {
+    // this is defined in peclcmd.php as 'pecl'
+    define('PEAR_RUNTYPE', 'pear');
+}
+define('PEAR_IGNORE_BACKTRACE', 1);
+/**
+ * @nodep Gtk
+ */
+if ('/Users/bbieber/Documents/workspace/UNL_Elgg/lib/php' != '@'.'include_path'.'@') {
+    ini_set('include_path', '/Users/bbieber/Documents/workspace/UNL_Elgg/lib/php');
+    $raw = false;
+} else {
+    // this is a raw, uninstalled pear, either a cvs checkout, or php distro
+    $raw = true;
+}
+@ini_set('allow_url_fopen', true);
+if (!ini_get('safe_mode')) {
+    @set_time_limit(0);
+}
+ob_implicit_flush(true);
+@ini_set('track_errors', true);
+@ini_set('html_errors', false);
+@ini_set('magic_quotes_runtime', false);
+$_PEAR_PHPDIR = '#$%^&*';
+set_error_handler('error_handler');
+
+$pear_package_version = "1.9.0";
+
+require_once 'PEAR.php';
+require_once 'PEAR/Frontend.php';
+require_once 'PEAR/Config.php';
+require_once 'PEAR/Command.php';
+require_once 'Console/Getopt.php';
+
+
+PEAR_Command::setFrontendType('CLI');
+$all_commands = PEAR_Command::getCommands();
+
+// remove this next part when we stop supporting that crap-ass PHP 4.2
+if (!isset($_SERVER['argv']) && !isset($argv) && !isset($HTTP_SERVER_VARS['argv'])) {
+    echo 'ERROR: either use the CLI php executable, or set register_argc_argv=On in php.ini';
+    exit(1);
+}
+
+$argv = Console_Getopt::readPHPArgv();
+// fix CGI sapi oddity - the -- in pear.bat/pear is not removed
+if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') {
+    unset($argv[1]);
+    $argv = array_values($argv);
+}
+$progname = PEAR_RUNTYPE;
+array_shift($argv);
+$options = Console_Getopt::getopt2($argv, "c:C:d:D:Gh?sSqu:vV");
+if (PEAR::isError($options)) {
+    usage($options);
+}
+
+$opts = $options[0];
+
+$fetype = 'CLI';
+if ($progname == 'gpear' || $progname == 'pear-gtk') {
+    $fetype = 'Gtk';
+} else {
+    foreach ($opts as $opt) {
+        if ($opt[0] == 'G') {
+            $fetype = 'Gtk';
+        }
+    }
+}
+//Check if Gtk and PHP >= 5.1.0
+if ($fetype == 'Gtk' && version_compare(phpversion(), '5.1.0', '>=')) {
+    $fetype = 'Gtk2';
+}
+
+$pear_user_config = '';
+$pear_system_config = '';
+$store_user_config = false;
+$store_system_config = false;
+$verbose = 1;
+
+foreach ($opts as $opt) {
+    switch ($opt[0]) {
+        case 'c':
+            $pear_user_config = $opt[1];
+            break;
+        case 'C':
+            $pear_system_config = $opt[1];
+            break;
+    }
+}
+
+PEAR_Command::setFrontendType($fetype);
+$ui = &PEAR_Command::getFrontendObject();
+$config = &PEAR_Config::singleton($pear_user_config, $pear_system_config);
+
+if (PEAR::isError($config)) {
+    $_file = '';
+    if ($pear_user_config !== false) {
+       $_file .= $pear_user_config;
+    }
+    if ($pear_system_config !== false) {
+       $_file .= '/' . $pear_system_config;
+    }
+    if ($_file == '/') {
+        $_file = 'The default config file';
+    }
+    $config->getMessage();
+    $ui->outputData("ERROR: $_file is not a valid config file or is corrupted.");
+    // We stop, we have no idea where we are :)
+    exit(1);
+}
+
+// this is used in the error handler to retrieve a relative path
+$_PEAR_PHPDIR = $config->get('php_dir');
+$ui->setConfig($config);
+PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError"));
+if (ini_get('safe_mode')) {
+    $ui->outputData('WARNING: running in safe mode requires that all files created ' .
+        'be the same uid as the current script.  PHP reports this script is uid: ' .
+        @getmyuid() . ', and current user is: ' . @get_current_user());
+}
+
+$verbose = $config->get("verbose");
+$cmdopts = array();
+
+if ($raw) {
+    if (!$config->isDefinedLayer('user') && !$config->isDefinedLayer('system')) {
+        $found = false;
+        foreach ($opts as $opt) {
+            if ($opt[0] == 'd' || $opt[0] == 'D') {
+                $found = true; // the user knows what they are doing, and are setting config values
+            }
+        }
+        if (!$found) {
+            // no prior runs, try to install PEAR
+            if (strpos(dirname(__FILE__), 'scripts')) {
+                $packagexml = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'package2.xml';
+                $pearbase = dirname(dirname(__FILE__));
+            } else {
+                $packagexml = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'package2.xml';
+                $pearbase = dirname(__FILE__);
+            }
+            if (file_exists($packagexml)) {
+                $options[1] = array(
+                    'install',
+                    $packagexml
+                );
+                $config->set('php_dir', $pearbase . DIRECTORY_SEPARATOR . 'php');
+                $config->set('data_dir', $pearbase . DIRECTORY_SEPARATOR . 'data');
+                $config->set('doc_dir', $pearbase . DIRECTORY_SEPARATOR . 'docs');
+                $config->set('test_dir', $pearbase . DIRECTORY_SEPARATOR . 'tests');
+                $config->set('ext_dir', $pearbase . DIRECTORY_SEPARATOR . 'extensions');
+                $config->set('bin_dir', $pearbase);
+                $config->mergeConfigFile($pearbase . 'pear.ini', false);
+                $config->store();
+                $config->set('auto_discover', 1);
+            }
+        }
+    }
+}
+foreach ($opts as $opt) {
+    $param = !empty($opt[1]) ? $opt[1] : true;
+    switch ($opt[0]) {
+        case 'd':
+            if ($param === true) {
+                die('Invalid usage of "-d" option, expected -d config_value=value, ' .
+                    'received "-d"' . "\n");
+            }
+            $possible = explode('=', $param);
+            if (count($possible) != 2) {
+                die('Invalid usage of "-d" option, expected -d config_value=value, received "' .
+                    $param . '"' . "\n");
+            }
+            list($key, $value) = explode('=', $param);
+            $config->set($key, $value, 'user');
+            break;
+        case 'D':
+            if ($param === true) {
+                die('Invalid usage of "-d" option, expected -d config_value=value, ' .
+                    'received "-d"' . "\n");
+            }
+            $possible = explode('=', $param);
+            if (count($possible) != 2) {
+                die('Invalid usage of "-d" option, expected -d config_value=value, received "' .
+                    $param . '"' . "\n");
+            }
+            list($key, $value) = explode('=', $param);
+            $config->set($key, $value, 'system');
+            break;
+        case 's':
+            $store_user_config = true;
+            break;
+        case 'S':
+            $store_system_config = true;
+            break;
+        case 'u':
+            $config->remove($param, 'user');
+            break;
+        case 'v':
+            $config->set('verbose', $config->get('verbose') + 1);
+            break;
+        case 'q':
+            $config->set('verbose', $config->get('verbose') - 1);
+            break;
+        case 'V':
+            usage(null, 'version');
+        case 'c':
+        case 'C':
+            break;
+        default:
+            // all non pear params goes to the command
+            $cmdopts[$opt[0]] = $param;
+            break;
+    }
+}
+
+if ($store_system_config) {
+    $config->store('system');
+}
+
+if ($store_user_config) {
+    $config->store('user');
+}
+
+$command = (isset($options[1][0])) ? $options[1][0] : null;
+if (empty($command) && ($store_user_config || $store_system_config)) {
+    exit;
+}
+
+if ($fetype == 'Gtk' || $fetype == 'Gtk2') {
+    if (!$config->validConfiguration()) {
+        PEAR::raiseError('CRITICAL ERROR: no existing valid configuration files found in files ' .
+            "'$pear_user_config' or '$pear_system_config', please copy an existing configuration" .
+            'file to one of these locations, or use the -c and -s options to create one');
+    }
+    Gtk::main();
+} else do {
+    if ($command == 'help') {
+        usage(null, @$options[1][1]);
+    }
+
+    if (!$config->validConfiguration()) {
+        PEAR::raiseError('CRITICAL ERROR: no existing valid configuration files found in files ' .
+            "'$pear_user_config' or '$pear_system_config', please copy an existing configuration" .
+            'file to one of these locations, or use the -c and -s options to create one');
+    }
+
+    PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
+    $cmd = PEAR_Command::factory($command, $config);
+    PEAR::popErrorHandling();
+    if (PEAR::isError($cmd)) {
+        usage(null, @$options[1][0]);
+    }
+
+    $short_args = $long_args = null;
+    PEAR_Command::getGetoptArgs($command, $short_args, $long_args);
+    array_shift($options[1]);
+    $tmp = Console_Getopt::getopt2($options[1], $short_args, $long_args);
+
+    if (PEAR::isError($tmp)) {
+        break;
+    }
+
+    list($tmpopt, $params) = $tmp;
+    $opts = array();
+    foreach ($tmpopt as $foo => $tmp2) {
+        list($opt, $value) = $tmp2;
+        if ($value === null) {
+            $value = true; // options without args
+        }
+
+        if (strlen($opt) == 1) {
+            $cmdoptions = $cmd->getOptions($command);
+            foreach ($cmdoptions as $o => $d) {
+                if (isset($d['shortopt']) && $d['shortopt'] == $opt) {
+                    $opts[$o] = $value;
+                }
+            }
+        } else {
+            if (substr($opt, 0, 2) == '--') {
+                $opts[substr($opt, 2)] = $value;
+            }
+        }
+    }
+
+    $ok = $cmd->run($command, $opts, $params);
+    if ($ok === false) {
+        PEAR::raiseError("unknown command `$command'");
+    }
+
+    if (PEAR::isError($ok)) {
+        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError"));
+        PEAR::raiseError($ok);
+    }
+} while (false);
+
+// {{{ usage()
+
+function usage($error = null, $helpsubject = null)
+{
+    global $progname, $all_commands;
+    $stderr = fopen('php://stderr', 'w');
+    if (PEAR::isError($error)) {
+        fputs($stderr, $error->getMessage() . "\n");
+    } elseif ($error !== null) {
+        fputs($stderr, "$error\n");
+    }
+
+    if ($helpsubject != null) {
+        $put = cmdHelp($helpsubject);
+    } else {
+        $put =
+            "Commands:\n";
+        $maxlen = max(array_map("strlen", $all_commands));
+        $formatstr = "%-{$maxlen}s  %s\n";
+        ksort($all_commands);
+        foreach ($all_commands as $cmd => $class) {
+            $put .= sprintf($formatstr, $cmd, PEAR_Command::getDescription($cmd));
+        }
+        $put .=
+            "Usage: $progname [options] command [command-options] <parameters>\n".
+            "Type \"$progname help options\" to list all options.\n".
+            "Type \"$progname help shortcuts\" to list all command shortcuts.\n".
+            "Type \"$progname help <command>\" to get the help for the specified command.";
+    }
+    fputs($stderr, "$put\n");
+    fclose($stderr);
+    exit(1);
+}
+
+function cmdHelp($command)
+{
+    global $progname, $all_commands, $config;
+    if ($command == "options") {
+        return
+        "Options:\n".
+        "     -v         increase verbosity level (default 1)\n".
+        "     -q         be quiet, decrease verbosity level\n".
+        "     -c file    find user configuration in `file'\n".
+        "     -C file    find system configuration in `file'\n".
+        "     -d foo=bar set user config variable `foo' to `bar'\n".
+        "     -D foo=bar set system config variable `foo' to `bar'\n".
+        "     -G         start in graphical (Gtk) mode\n".
+        "     -s         store user configuration\n".
+        "     -S         store system configuration\n".
+        "     -u foo     unset `foo' in the user configuration\n".
+        "     -h, -?     display help/usage (this message)\n".
+        "     -V         version information\n";
+    } elseif ($command == "shortcuts") {
+        $sc = PEAR_Command::getShortcuts();
+        $ret = "Shortcuts:\n";
+        foreach ($sc as $s => $c) {
+            $ret .= sprintf("     %-8s %s\n", $s, $c);
+        }
+        return $ret;
+
+    } elseif ($command == "version") {
+        return "PEAR Version: ".$GLOBALS['pear_package_version'].
+               "\nPHP Version: ".phpversion().
+               "\nZend Engine Version: ".zend_version().
+               "\nRunning on: ".php_uname();
+
+    } elseif ($help = PEAR_Command::getHelp($command)) {
+        if (is_string($help)) {
+            return "$progname $command [options] $help\n";
+        }
+
+        if ($help[1] === null) {
+            return "$progname $command $help[0]";
+        }
+
+        return "$progname $command [options] $help[0]\n$help[1]";
+    }
+
+    return "Command '$command' is not valid, try '$progname help'";
+}
+
+// }}}
+
+function error_handler($errno, $errmsg, $file, $line, $vars) {
+    if ((defined('E_STRICT') && $errno & E_STRICT) || (defined('E_DEPRECATED') &&
+          $errno & E_DEPRECATED) || !error_reporting()) {
+        if (defined('E_STRICT') && $errno & E_STRICT) {
+            return; // E_STRICT
+        }
+        if (defined('E_DEPRECATED') && $errno & E_DEPRECATED) {
+            return; // E_DEPRECATED
+        }
+        if ($GLOBALS['config']->get('verbose') < 4) {
+            return false; // @silenced error, show all if debug is high enough
+        }
+    }
+    $errortype = array (
+        E_ERROR   =>  "Error",
+        E_WARNING   =>  "Warning",
+        E_PARSE   =>  "Parsing Error",
+        E_NOTICE   =>  "Notice",
+        E_CORE_ERROR  =>  "Core Error",
+        E_CORE_WARNING  =>  "Core Warning",
+        E_COMPILE_ERROR  =>  "Compile Error",
+        E_COMPILE_WARNING =>  "Compile Warning",
+        E_USER_ERROR =>  "User Error",
+        E_USER_WARNING =>  "User Warning",
+        E_USER_NOTICE =>  "User Notice"
+    );
+    $prefix = $errortype[$errno];
+    global $_PEAR_PHPDIR;
+    if (stristr($file, $_PEAR_PHPDIR)) {
+        $file = substr($file, strlen($_PEAR_PHPDIR) + 1);
+    } else {
+        $file = basename($file);
+    }
+    print "\n$prefix: $errmsg in $file on line $line\n";
+    return false;
+}
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * mode: php
+ * End:
+ */
+// vim600:syn=php
\ No newline at end of file
diff --git a/lib/php/peclcmd.php b/lib/php/peclcmd.php
new file mode 100644
index 00000000..f4887985
--- /dev/null
+++ b/lib/php/peclcmd.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * PEAR, the PHP Extension and Application Repository
+ *
+ * Command line interface
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   pear
+ * @package    PEAR
+ * @author     Stig Bakken <ssb@php.net>
+ * @author     Tomas V.V.Cox <cox@idecnet.com>
+ * @copyright  1997-2009 The Authors
+ * @license    http://opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: peclcmd.php 276392 2009-02-25 00:06:23Z dufuz $
+ * @link       http://pear.php.net/package/PEAR
+ */
+
+/**
+ * @nodep Gtk
+ */
+if ('/Users/bbieber/Documents/workspace/UNL_Elgg/lib/php' != '@'.'include_path'.'@') {
+    ini_set('include_path', '/Users/bbieber/Documents/workspace/UNL_Elgg/lib/php');
+    $raw = false;
+} else {
+    // this is a raw, uninstalled pear, either a cvs checkout, or php distro
+    $raw = true;
+}
+define('PEAR_RUNTYPE', 'pecl');
+require_once 'pearcmd.php';
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * mode: php
+ * End:
+ */
+// vim600:syn=php
+
+?>
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_File_classical.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_File_classical.phpt
new file mode 100644
index 00000000..f5a6191c
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_File_classical.phpt
@@ -0,0 +1,89 @@
+--TEST--
+Cache_Lite::Cache_Lite_File (classical)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_file_base.inc');
+
+$master = tmpDir() . '/' . 'foobar.masterfile';
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'masterFile' => $master
+);
+
+$f = fopen($master, 'w');
+fwrite($f, 'foobar');
+fclose($f);
+sleep(1);
+
+$Cache_Lite = new Cache_Lite_File($options);
+multipleCallCache('string');
+multipleCallCache3_1('string');
+
+echo "==> We touch masterFile\n";
+touch($master);
+sleep(1);
+clearstatcache();
+echo "\nDone !\n\n";
+$Cache_Lite = new Cache_Lite_File($options);
+sleep(1);
+multipleCallCache3_2('string');
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Second call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Third call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
+==> #6 call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> #7 call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We touch masterFile
+
+Done !
+
+==> #8 call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_classical.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_classical.phpt
new file mode 100644
index 00000000..415d5024
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_classical.phpt
@@ -0,0 +1,99 @@
+--TEST--
+Cache_Lite::Cache_Lite_Function (classical)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_function_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60
+);
+
+$cache = new Cache_Lite_Function($options);
+
+$data = $cache->call('function_to_bench', 23, 66);
+echo($data);
+$data = $cache->call('function_to_bench', 23, 66);
+echo($data);
+$cache->call('function_to_bench', 23, 66);
+
+$object = new bench();
+$object->test = 666;
+$data = $cache->call('object->method_to_bench', 23, 66);
+echo($data);
+$data = $cache->call('object->method_to_bench', 23, 66);
+echo($data);
+$cache->call('object->method_to_bench', 23, 66);
+
+$data = $cache->call('bench::static_method_to_bench', 23, 66);
+echo($data);
+$data = $cache->call('bench::static_method_to_bench', 23, 66);
+echo($data);
+$cache->call('bench::static_method_to_bench', 23, 66);
+
+$object = new test($options);
+
+$cache->clean();
+
+function function_to_bench($arg1, $arg2) 
+{
+    echo "This is the output of the function function_to_bench($arg1, $arg2) !\n";
+    return "This is the result of the function function_to_bench($arg1, $arg2) !\n";
+}
+
+class bench
+{
+    var $test;
+
+    function method_to_bench($arg1, $arg2)
+    {
+        echo "\$obj->test = $this->test and this is the output of the method \$obj->method_to_bench($arg1, $arg2) !\n";
+        return "\$obj->test = $this->test and this is the result of the method \$obj->method_to_bench($arg1, $arg2) !\n";        
+    }
+    
+    function static_method_to_bench($arg1, $arg2) {
+        echo "This is the output of the function static_method_to_bench($arg1, $arg2) !\n";
+        return "This is the result of the function static_method_to_bench($arg1, $arg2) !\n";
+    }
+
+}
+
+class test
+{
+    function test($options) {
+        $this->foo = 'bar';
+        $cache = new Cache_Lite_Function($options);
+        echo($cache->call(array($this, 'method_to_bench'), 'foo', 'bar'));
+    }   
+    
+    function method_to_bench($arg1, $arg2)
+    {
+        echo "output : *** $arg1 *** $arg2 *** " . $this->foo . " ***\n";
+        return "result : *** $arg1 *** $arg2 *** " . $this->foo . " ***\n";     
+    }
+}
+
+?>
+--GET--
+--POST--
+--EXPECT--
+This is the output of the function function_to_bench(23, 66) !
+This is the result of the function function_to_bench(23, 66) !
+This is the output of the function function_to_bench(23, 66) !
+This is the result of the function function_to_bench(23, 66) !
+This is the output of the function function_to_bench(23, 66) !
+$obj->test = 666 and this is the output of the method $obj->method_to_bench(23, 66) !
+$obj->test = 666 and this is the result of the method $obj->method_to_bench(23, 66) !
+$obj->test = 666 and this is the output of the method $obj->method_to_bench(23, 66) !
+$obj->test = 666 and this is the result of the method $obj->method_to_bench(23, 66) !
+$obj->test = 666 and this is the output of the method $obj->method_to_bench(23, 66) !
+This is the output of the function static_method_to_bench(23, 66) !
+This is the result of the function static_method_to_bench(23, 66) !
+This is the output of the function static_method_to_bench(23, 66) !
+This is the result of the function static_method_to_bench(23, 66) !
+This is the output of the function static_method_to_bench(23, 66) !
+output : *** foo *** bar *** bar ***
+result : *** foo *** bar *** bar ***
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_dontcache.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_dontcache.phpt
new file mode 100644
index 00000000..28ee24a0
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_dontcache.phpt
@@ -0,0 +1,128 @@
+--TEST--
+Cache_Lite::Cache_Lite_Function (dont cache)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_function_base.inc');
+
+// Classical
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'debugCacheLiteFunction' => true
+);
+$cache = new Cache_Lite_Function($options);
+$data = $cache->call('function_test', 23, 66);
+echo($data);
+$data = $cache->call('function_test', 23, 66);
+echo($data);
+$cache->clean();
+
+// Don't Cache if output contains NOCACHE
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'debugCacheLiteFunction' => true,
+    'dontCacheWhenTheOutputContainsNOCACHE' => true
+);
+$cache = new Cache_Lite_Function($options);
+$data = $cache->call('function_test2', 23, 66);
+echo($data);
+$data = $cache->call('function_test2', 23, 66);
+echo($data);
+$data = $cache->call('function_test2', 0, 66);
+echo($data);
+$data = $cache->call('function_test2', 0, 66);
+echo($data);
+$cache->clean();
+
+// Don't cache if result if false
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'debugCacheLiteFunction' => true,
+    'dontCacheWhenTheResultIsFalse' => true
+);
+$cache = new Cache_Lite_Function($options);
+$data = $cache->call('function_test', 23, 66);
+echo($data);
+$data = $cache->call('function_test', 23, 66);
+echo($data);
+$data = $cache->call('function_test', 0, 66);
+echo($data);
+$data = $cache->call('function_test', 0, 66);
+echo($data);
+$cache->clean();
+
+// Don't cache if result if null
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'debugCacheLiteFunction' => true,
+    'dontCacheWhenTheResultIsNull' => true
+);
+$cache = new Cache_Lite_Function($options);
+$data = $cache->call('function_test', 23, 66);
+echo($data);
+$data = $cache->call('function_test', 23, 66);
+echo($data);
+$data = $cache->call('function_test', 1, 66);
+echo($data);
+$data = $cache->call('function_test', 1, 66);
+echo($data);
+$cache->clean();
+
+function function_test($arg1, $arg2) 
+{
+    echo "This is the output of the function function_test($arg1, $arg2) !\n";
+    if ($arg1==0) {
+        return false;
+    }
+    if ($arg1==1) {
+        return null;
+    }
+    return '';
+}
+
+function function_test2($arg1, $arg2) 
+{
+    if ($arg1==0) {
+        echo "NOCACHE";
+    }
+    return "This is the result of the function function_test2($arg1, $arg2) !\n";
+}
+
+?>
+--GET--
+--POST--
+--EXPECT--
+Cache missed !
+This is the output of the function function_test(23, 66) !
+Cache hit !
+This is the output of the function function_test(23, 66) !
+Cache missed !
+This is the result of the function function_test2(23, 66) !
+Cache hit !
+This is the result of the function function_test2(23, 66) !
+Cache missed !
+This is the result of the function function_test2(0, 66) !
+Cache missed !
+This is the result of the function function_test2(0, 66) !
+Cache missed !
+This is the output of the function function_test(23, 66) !
+Cache hit !
+This is the output of the function function_test(23, 66) !
+Cache missed !
+This is the output of the function function_test(0, 66) !
+Cache missed !
+This is the output of the function function_test(0, 66) !
+Cache missed !
+This is the output of the function function_test(23, 66) !
+Cache hit !
+This is the output of the function function_test(23, 66) !
+Cache missed !
+This is the output of the function function_test(1, 66) !
+Cache missed !
+This is the output of the function function_test(1, 66) !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_drop.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_drop.phpt
new file mode 100644
index 00000000..3e7b600f
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Function_drop.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Cache_Lite::Cache_Lite_Function (drop() method)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_function_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60
+);
+$foo = 10;
+
+$cache = new Cache_Lite_Function($options);
+
+$data = $cache->call('function_to_bench', 23, 66);
+echo($data."\n");
+$data = $cache->call('function_to_bench', 23, 66);
+echo($data."\n");
+$cache->drop('function_to_bench', 23, 66);
+$data = $cache->call('function_to_bench', 23, 66);
+echo($data."\n");
+$data = $cache->call('function_to_bench', 23, 66);
+echo($data."\n");
+$cache->clean();
+
+function function_to_bench($arg1, $arg2) 
+{
+    global $foo;
+    $foo = $foo + 1;
+    echo "hello !\n";
+    return($foo + $arg1 + $arg2);
+}
+
+?>
+--GET--
+--POST--
+--EXPECT--
+hello !
+100
+hello !
+100
+hello !
+101
+hello !
+101
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Output_classical.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Output_classical.phpt
new file mode 100644
index 00000000..1e3712be
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_Output_classical.phpt
@@ -0,0 +1,51 @@
+--TEST--
+Cache_Lite::Cache_Lite_Output (classical)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_output_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60
+);
+
+$Cache_Lite_Output = new Cache_Lite_Output($options);
+multipleCallCache2();
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789Cache Missed !
+
+Done !
+
+==> Second call (cache should be hit)
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789Cache Hit !
+
+Done !
+
+==> Third call (cache should be hit)
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789Cache Hit !
+
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789Cache Missed !
+
+Done !
+
+==> #5 Call with another id (cache should be missed)
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789Cache Missed !
+
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_automaticCleaning.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_automaticCleaning.phpt
new file mode 100644
index 00000000..cdb6bc58
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_automaticCleaning.phpt
@@ -0,0 +1,54 @@
+--TEST--
+Cache_Lite::Cache_Lite (automaticCleaning)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 2,
+    'automaticCleaningFactor' => 1
+);
+
+$Cache_Lite = new Cache_Lite($options);
+callCache('31415926');
+echo("\n");
+callCache('31415926');
+echo("\n");
+callCache('31415926bis');
+echo("\n");
+callCache('31415926bis');
+echo("\n");
+sleep(4);
+callCache('31415926'); // '31415926bis' will be cleaned
+echo "\n";
+$dh = opendir(tmpDir());
+while ($file = readdir($dh)) {
+    if (($file != '.') && ($file != '..')) {
+        if (substr($file, 0, 6)=='cache_') {  
+            echo "$file\n"; 
+        }
+    }
+}
+
+$Cache_Lite->remove('31415926');
+$Cache_Lite->remove('31415926bis');
+
+?>
+--GET--
+--POST--
+--EXPECT--
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+cache_c21f969b5f03d33d43e04f8f136e7682_e9982ec5ca981bd365603623cf4b2277
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_classical.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_classical.phpt
new file mode 100644
index 00000000..237c30d3
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_classical.phpt
@@ -0,0 +1,51 @@
+--TEST--
+Cache_Lite::Cache_Lite (classical)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache();
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Second call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Third call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error.phpt
new file mode 100644
index 00000000..da4ff094
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error.phpt
@@ -0,0 +1,61 @@
+--TEST--
+Cache_Lite::Cache_Lite (error)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '31451992gjhgjh'. '/', # I hope there will be no directory with that silly name
+    'lifeTime' => 60
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache();
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Error when saving cache !
+
+Done !
+
+==> Second call (cache should be hit)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Error when saving cache !
+
+Done !
+
+==> Third call (cache should be hit)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Error when saving cache !
+
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Error when saving cache !
+
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Error when saving cache !
+
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error2.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error2.phpt
new file mode 100644
index 00000000..e561036d
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error2.phpt
@@ -0,0 +1,62 @@
+--TEST--
+Cache_Lite::Cache_Lite (error2)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '31451992gjhgjh'. '/', # I hope there will be no directory with that silly name
+    'lifeTime' => 60,
+    'errorHandlingAPIBreak' => true
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache();
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+PEAR_ERROR : Cache_Lite : Unable to write cache file : /tmp31451992gjhgjh/cache_c21f969b5f03d33d43e04f8f136e7682_e9982ec5ca981bd365603623cf4b2277 (#-1)
+
+Done !
+
+==> Second call (cache should be hit)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+PEAR_ERROR : Cache_Lite : Unable to write cache file : /tmp31451992gjhgjh/cache_c21f969b5f03d33d43e04f8f136e7682_e9982ec5ca981bd365603623cf4b2277 (#-1)
+
+Done !
+
+==> Third call (cache should be hit)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+PEAR_ERROR : Cache_Lite : Unable to write cache file : /tmp31451992gjhgjh/cache_c21f969b5f03d33d43e04f8f136e7682_e9982ec5ca981bd365603623cf4b2277 (#-1)
+
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+PEAR_ERROR : Cache_Lite : Unable to write cache file : /tmp31451992gjhgjh/cache_c21f969b5f03d33d43e04f8f136e7682_e9982ec5ca981bd365603623cf4b2277 (#-1)
+
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+PEAR_ERROR : Cache_Lite : Unable to write cache file : /tmp31451992gjhgjh/cache_c21f969b5f03d33d43e04f8f136e7682_07eeaa82211be6c3335603523dbea0a3 (#-1)
+
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error3.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error3.phpt
new file mode 100644
index 00000000..ab4a7221
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_error3.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Cache_Lite::Cache_Lite (error3)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '31451992gjhgjh'. '/', # I hope there will be no directory with that silly name
+    'lifeTime' => 60,
+    'pearErrorMode' => CACHE_LITE_ERROR_DIE
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache();
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789Cache_Lite : Unable to write cache file : /tmp31451992gjhgjh/cache_c21f969b5f03d33d43e04f8f136e7682_e9982ec5ca981bd365603623cf4b2277
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_eternal.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_eternal.phpt
new file mode 100644
index 00000000..0084e997
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_eternal.phpt
@@ -0,0 +1,51 @@
+--TEST--
+Cache_Lite::Cache_Lite (eternal)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => null
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache();
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Second call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Third call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_fatest.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_fatest.phpt
new file mode 100644
index 00000000..e0770265
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_fatest.phpt
@@ -0,0 +1,55 @@
+--TEST--
+Cache_Lite::Cache_Lite (fatest, no control, no lock)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'fileLocking' => false,
+    'writeControl' => false,
+    'readControl' => false,
+    'fileNameProtection' => false
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache();
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Second call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Third call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_hashed.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_hashed.phpt
new file mode 100644
index 00000000..03f7122d
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_hashed.phpt
@@ -0,0 +1,96 @@
+--TEST--
+Cache_Lite::Cache_Lite (hashed level 2)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'hashedDirectoryLevel' => 2
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache();
+
+// Hack to clean cache directory structure
+/**
+ * rm() -- Vigorously erase files and directories.
+ *
+ * @param $fileglob mixed If string, must be a file name (foo.txt), glob pattern (*.txt), or directory name.
+ *                        If array, must be an array of file names, glob patterns, or directories.
+ */
+function rm($fileglob)
+{
+   if (is_string($fileglob)) {
+       if (is_file($fileglob)) {
+           return unlink($fileglob);
+       } else if (is_dir($fileglob)) {
+           $ok = rm("$fileglob/*");
+           if (! $ok) {
+               return false;
+           }
+           return rmdir($fileglob);
+       } else {
+           $matching = glob($fileglob);
+           if ($matching === false) {
+               trigger_error(sprintf('No files match supplied glob %s', $fileglob), E_USER_WARNING);
+               return false;
+           }     
+           $rcs = array_map('rm', $matching);
+           if (in_array(false, $rcs)) {
+               return false;
+           }
+       }     
+   } else if (is_array($fileglob)) {
+       $rcs = array_map('rm', $fileglob);
+       if (in_array(false, $rcs)) {
+           return false;
+       }
+   } else {
+       trigger_error('Param #1 must be filename or glob pattern, or array of filenames or glob patterns', E_USER_ERROR);
+       return false;
+   }
+
+   return true;
+}
+
+rm(tmpDir() . '/cache_*');
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Second call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Third call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_lifetime.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_lifetime.phpt
new file mode 100644
index 00000000..3e74eca9
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_lifetime.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Cache_Lite::Cache_Lite (lifetime)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 2
+);
+
+$Cache_Lite = new Cache_Lite($options);
+callCache('31415926');
+echo("\n");
+callCache('31415926');
+echo("\n");
+sleep(4);
+callCache('31415926');
+echo("\n");
+sleep(4);
+$Cache_Lite->extendLife();
+callCache('31415926');
+echo("\n");
+$Cache_Lite->remove('31415926');
+
+?>
+--GET--
+--POST--
+--EXPECT--
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_memorycache.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_memorycache.phpt
new file mode 100644
index 00000000..71c95f01
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_memorycache.phpt
@@ -0,0 +1,52 @@
+--TEST--
+Cache_Lite::Cache_Lite (memory cache on)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'memoryCaching' => false
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache();
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Second call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Third call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_serialization.phpt b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_serialization.phpt
new file mode 100644
index 00000000..4885b28d
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/Cache_Lite_serialization.phpt
@@ -0,0 +1,52 @@
+--TEST--
+Cache_Lite::Cache_Lite (automatic serialization on)
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'automaticSerialization' => true
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache('array');
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+a:4:{i:0;a:2:{i:0;s:3:"foo";i:1;s:3:"bar";}i:1;i:1;i:2;s:3:"foo";i:3;s:3:"bar";}
+Done !
+
+==> Second call (cache should be hit)
+Cache Hit !
+a:4:{i:0;a:2:{i:0;s:3:"foo";i:1;s:3:"bar";}i:1;i:1;i:2;s:3:"foo";i:3;s:3:"bar";}
+Done !
+
+==> Third call (cache should be hit)
+Cache Hit !
+a:4:{i:0;a:2:{i:0;s:3:"foo";i:1;s:3:"bar";}i:1;i:1;i:2;s:3:"foo";i:3;s:3:"bar";}
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+a:4:{i:0;a:2:{i:0;s:3:"foo";i:1;s:3:"bar";}i:1;i:1;i:2;s:3:"foo";i:3;s:3:"bar";}
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+a:4:{i:0;a:2:{i:0;s:3:"foo";i:1;s:3:"bar";}i:1;i:1;i:2;s:3:"foo";i:3;s:3:"bar";}
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/bench.php b/lib/tests/Cache_Lite/Cache/tests/bench.php
new file mode 100644
index 00000000..8839b9c1
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/bench.php
@@ -0,0 +1,27 @@
+<?php
+
+// Bench script of Cache_Lite
+// $Id: bench.php,v 1.6 2002/09/28 18:05:29 fab Exp $
+
+require_once('Cache/Lite.php');
+
+$options = array(
+    'caching' => true,
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 10
+);
+
+$Cache_Lite = new Cache_Lite($options);
+
+if ($data = $Cache_Lite->get('123')) {
+    echo($data);
+} else {
+    $data = '';
+    for($i=0;$i<1000;$i++) {
+        $data .= '0123456789';
+    }
+    echo($data);
+    $Cache_Lite->save($data);
+}
+
+?>
\ No newline at end of file
diff --git a/lib/tests/Cache_Lite/Cache/tests/bench2.php b/lib/tests/Cache_Lite/Cache/tests/bench2.php
new file mode 100644
index 00000000..f029ebb2
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/bench2.php
@@ -0,0 +1,24 @@
+<?php
+
+// Bench script of Cache_Lite_Output
+// $Id: bench2.php,v 1.4 2002/09/28 18:05:29 fab Exp $
+
+require_once('Cache/Lite/Output.php');
+
+$options = array(
+    'caching' => true,
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 10
+);
+
+$cache = new Cache_Lite_Output($options);
+
+if (!($cache->start('123'))) {
+    // Cache missed...
+    for($i=0;$i<1000;$i++) { // Making of the page...
+        echo('0123456789');
+    }
+    $cache->end();
+}
+
+?>
\ No newline at end of file
diff --git a/lib/tests/Cache_Lite/Cache/tests/bench3.php b/lib/tests/Cache_Lite/Cache/tests/bench3.php
new file mode 100644
index 00000000..a7e586c5
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/bench3.php
@@ -0,0 +1,60 @@
+<?php
+
+// Bench script of Cache_Lite_Function
+// $Id: bench3.php,v 1.4 2005/12/04 16:03:55 fab Exp $
+
+require_once('Cache/Lite/Function.php');
+
+$options = array(
+    'caching' => true,
+    'cacheDir' => '/tmp/',
+    'lifeTime' => 10
+);
+
+$cache = new Cache_Lite_Function($options);
+
+$data = $cache->call('function_to_bench', 23, 66);
+echo($data);
+
+$object = new bench();
+$object->test = 666;
+$data = $cache->call('object->method_to_bench', 23, 66);
+echo($data);
+
+$data = $cache->call('bench::static_method_to_bench', 23, 66);
+echo($data);
+
+function function_to_bench($arg1, $arg2) 
+{
+    for($i=0;$i<10000;$i++) {
+        $tmp = md5(md5(md5('Loosing time...')));
+    }
+    echo "This is the output of the function function_to_bench($arg1, $arg2) !<br>";
+    return "This is the result of the function function_to_bench($arg1, $arg2) !<br>";
+}
+
+class bench
+{
+    var $test;
+
+    function method_to_bench($arg1, $arg2)
+    {
+        for($i=0;$i<10000;$i++) {
+            $tmp = md5(md5(md5('Loosing time...')));
+        }
+        echo "\$obj->test = $this->test and this is the output of the method \$obj->method_to_bench($arg1, $arg2) !<br>";
+        return "\$obj->test = $this->test and this is the result of the method \$obj->method_to_bench($arg1, $arg2) !<br>";        
+    }
+    
+    function static_method_to_bench($arg1, $arg2) 
+    {
+        for($i=0;$i<10000;$i++) {
+            $tmp = md5(md5(md5('Loosing time...')));
+        }
+        echo "This is the output of the function static_method_to_bench($arg1, $arg2) !<br>";
+        return "This is the result of the function static_method_to_bench($arg1, $arg2) !<br>";
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/lib/tests/Cache_Lite/Cache/tests/cache_lite_base.inc b/lib/tests/Cache_Lite/Cache/tests/cache_lite_base.inc
new file mode 100644
index 00000000..3e8aa73e
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/cache_lite_base.inc
@@ -0,0 +1,6 @@
+<?php
+
+error_reporting(E_ALL);
+require_once('Cache/Lite.php');
+
+?>
diff --git a/lib/tests/Cache_Lite/Cache/tests/cache_lite_file_base.inc b/lib/tests/Cache_Lite/Cache/tests/cache_lite_file_base.inc
new file mode 100644
index 00000000..24f6f951
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/cache_lite_file_base.inc
@@ -0,0 +1,6 @@
+<?php
+
+error_reporting(E_ALL);
+require_once('Cache/Lite/File.php');
+
+?>
diff --git a/lib/tests/Cache_Lite/Cache/tests/cache_lite_function_base.inc b/lib/tests/Cache_Lite/Cache/tests/cache_lite_function_base.inc
new file mode 100644
index 00000000..448ca0d1
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/cache_lite_function_base.inc
@@ -0,0 +1,6 @@
+<?php
+
+error_reporting(E_ALL);
+require_once('Cache/Lite/Function.php');
+
+?>
diff --git a/lib/tests/Cache_Lite/Cache/tests/cache_lite_output_base.inc b/lib/tests/Cache_Lite/Cache/tests/cache_lite_output_base.inc
new file mode 100644
index 00000000..2a9a3dec
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/cache_lite_output_base.inc
@@ -0,0 +1,6 @@
+<?php
+
+error_reporting(E_ALL);
+require_once('Cache/Lite/Output.php');
+
+?>
diff --git a/lib/tests/Cache_Lite/Cache/tests/callcache.inc b/lib/tests/Cache_Lite/Cache/tests/callcache.inc
new file mode 100644
index 00000000..03d23ac2
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/callcache.inc
@@ -0,0 +1,149 @@
+<?php
+
+function callCache($id, $type = 'string') {
+    global $Cache_Lite;
+    if ($data = $Cache_Lite->get($id)) {
+        echo("Cache Hit !\n");
+        if ($type=='string') {
+            echo($data);
+        }
+        if ($type=='array') {
+            echo(serialize($data));
+        }
+    } else {
+        echo("Cache Missed !\n");
+        if ($type=='string') {
+            $data = '';
+            for($i=0;$i<10;$i++) {
+                $data .= '0123456789';
+            }
+            echo($data);
+        }
+        if ($type=='array') {
+            $data = array(array('foo', 'bar'), 1, 'foo', 'bar');
+            echo(serialize($data));
+        }
+        $res = $Cache_Lite->save($data);
+        if (is_object($res)) {
+            echo "\nPEAR_ERROR : " . $res->getMessage() . " (#" . $res->getCode() . ")\n";
+        } else {
+	        if (!($res)) {
+	            echo "\nError when saving cache !\n";
+	        }
+        }
+    }
+}
+    
+function multipleCallCache($type = 'string') {
+    global $Cache_Lite;
+    
+    echo "==> First call (cache should be missed)\n";
+    callCache('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> Second call (cache should be hit)\n";
+    callCache('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> Third call (cache should be hit)\n";
+    callCache('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> We remove cache\n";
+    $Cache_Lite->remove('31415926');
+    echo "Done !\n\n";
+    
+    echo "==> Fourth call (cache should be missed)\n";
+    callCache('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> #5 Call with another id (cache should be missed)\n";
+    callCache('3141592653', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> We remove cache\n";
+    $Cache_Lite->remove('31415926');
+    $Cache_Lite->remove('3141592653');
+    echo "Done !\n";
+}
+
+function callCache2($id, $type = 'string') {
+    global $Cache_Lite_Output;
+    if (!($Cache_Lite_Output->start($id))) {
+        if ($type=='string') {
+            $data = '';
+            for($i=0;$i<10;$i++) {
+                $data .= '0123456789';
+            }
+            echo($data);
+        }
+        if ($type=='array') {
+            $data = array(array('foo', 'bar'), 1, 'foo', 'bar');
+            echo(serialize($data));
+        }
+        $Cache_Lite_Output->end();
+        echo("Cache Missed !\n");
+    } else {
+        echo("Cache Hit !\n");
+    }
+}
+
+function multipleCallCache2($type = 'string') {
+    global $Cache_Lite_Output;
+    
+    echo "==> First call (cache should be missed)\n";
+    callCache2('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> Second call (cache should be hit)\n";
+    callCache2('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> Third call (cache should be hit)\n";
+    callCache2('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> We remove cache\n";
+    $Cache_Lite_Output->remove('31415926');
+    echo "Done !\n\n";
+    
+    echo "==> Fourth call (cache should be missed)\n";
+    callCache2('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> #5 Call with another id (cache should be missed)\n";
+    callCache2('3141592653', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> We remove cache\n";
+    $Cache_Lite_Output->remove('31415926');
+    $Cache_Lite_Output->remove('3141592653');
+    echo "Done !\n";
+}
+
+function multipleCallCache3_1($type = 'string') {
+    global $Cache_Lite;
+       
+    echo "==> #6 call (cache should be missed)\n";
+    callCache('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> #7 call (cache should be hit)\n";
+    callCache('31415926', $type);
+    echo "\nDone !\n\n";
+}
+
+function multipleCallCache3_2($type = 'string') {
+    global $Cache_Lite;
+      
+    echo "==> #8 call (cache should be missed)\n";
+    callCache('31415926', $type);
+    echo "\nDone !\n\n";
+    
+    echo "==> We remove cache\n";
+    $Cache_Lite->remove('31415926');
+    echo "Done !\n";
+    
+}
+
+?>
diff --git a/lib/tests/Cache_Lite/Cache/tests/pearbug13693.phpt b/lib/tests/Cache_Lite/Cache/tests/pearbug13693.phpt
new file mode 100644
index 00000000..0272adf8
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/pearbug13693.phpt
@@ -0,0 +1,31 @@
+--TEST--
+pearbug13693
+--FILE--
+<?php
+
+    require_once 'Cache/Lite.php';
+    
+    // Create temp dir
+    $dir = dirname( __FILE__ ) . '/' . uniqid();
+    mkdir( $dir );
+    
+    $options = array(
+        'cacheDir' => $dir,
+        'lifeTime' => 60,
+    );
+    $id = '#13693';
+    $cache = new Cache_Lite($options);
+    $cache->save('stuff', $id);
+    // Must be true
+    echo ( $cache->remove($id) === true ) ? "OK\n" : "ERROR\n";
+    // Will return a PEAR Error
+    echo ( $cache->remove($id) instanceof PEAR_Error ) ? "OK\n" : "ERROR\n";
+    // Will return true
+    echo ( $cache->remove($id, 'default', true) === true ) ? "OK\n" : "ERROR\n";
+    
+    // Remove temp dir
+    rmdir( $dir );
+--EXPECT--
+OK
+OK
+OK
\ No newline at end of file
diff --git a/lib/tests/Cache_Lite/Cache/tests/pearbug513.phpt b/lib/tests/Cache_Lite/Cache/tests/pearbug513.phpt
new file mode 100644
index 00000000..d16e7a49
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/pearbug513.phpt
@@ -0,0 +1,52 @@
+--TEST--
+pearbug513
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'automaticSerialization' => true
+);
+
+$Cache_Lite = new Cache_Lite($options);
+multipleCallCache();
+
+?>
+--GET--
+--POST--
+--EXPECT--
+==> First call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Second call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> Third call (cache should be hit)
+Cache Hit !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
+
+==> Fourth call (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> #5 Call with another id (cache should be missed)
+Cache Missed !
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+Done !
+
+==> We remove cache
+Done !
diff --git a/lib/tests/Cache_Lite/Cache/tests/pearbug7618.phpt b/lib/tests/Cache_Lite/Cache/tests/pearbug7618.phpt
new file mode 100644
index 00000000..58c158d3
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/pearbug7618.phpt
@@ -0,0 +1,39 @@
+--TEST--
+pearbug7618
+--FILE--
+<?php
+
+require_once('callcache.inc');
+require_once('tmpdir.inc');
+require_once('cache_lite_base.inc');
+
+$options = array(
+    'cacheDir' => tmpDir() . '/',
+    'lifeTime' => 60,
+    'automaticSerialization' => true
+);
+
+$cache = new Cache_Lite($options);
+$cacheid = "testid";
+$tmpar = array();
+for ($i=0; $i<2; $i++) {
+    $ar[] = 'foo';
+    if ($cache->save($ar,$cacheid)) {
+        echo "TRUE\n";
+    } else {
+        echo "FALSE\n";
+    }
+    if ($data = $cache->get($cacheid)) {
+        echo($data[0] . "\n");
+    } else {
+        echo "FALSE\n";
+    }
+}
+$cache->remove('testid');
+
+?>
+--EXPECT--
+TRUE
+foo
+TRUE
+foo
\ No newline at end of file
diff --git a/lib/tests/Cache_Lite/Cache/tests/tmpdir.inc b/lib/tests/Cache_Lite/Cache/tests/tmpdir.inc
new file mode 100644
index 00000000..70b2c7bf
--- /dev/null
+++ b/lib/tests/Cache_Lite/Cache/tests/tmpdir.inc
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This code is taken from PEAR/File from Michael Wallner <mike@php.net>
+ * to avoid an extra dependency for a single function.
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ */
+ 
+require_once('PEAR.php');
+define('FILE_WIN32', defined('OS_WINDOWS') ? OS_WINDOWS : !strncasecmp(PHP_OS, 'win', 3));   
+
+/**
+ * Returns the temp directory according to either the TMP, TMPDIR, or
+ * TEMP env variables. If these are not set it will also check for the
+ * existence of /tmp, %WINDIR%\temp
+ *
+ * @static
+ * @access  public
+ * @return  string  The system tmp directory
+ */
+function tmpDir()
+{
+    if (FILE_WIN32) {
+        if (isset($_ENV['TEMP'])) {
+            return $_ENV['TEMP'];
+        }
+        if (isset($_ENV['TMP'])) {
+            return $_ENV['TMP'];
+        }
+        if (isset($_ENV['windir'])) {
+            return $_ENV['windir'] . '\\temp';
+        }
+        if (isset($_ENV['SystemRoot'])) {
+            return $_ENV['SystemRoot'] . '\\temp';
+        }
+        if (isset($_SERVER['TEMP'])) {
+            return $_SERVER['TEMP'];
+        }
+        if (isset($_SERVER['TMP'])) {
+            return $_SERVER['TMP'];
+        }
+        if (isset($_SERVER['windir'])) {
+            return $_SERVER['windir'] . '\\temp';
+        }
+        if (isset($_SERVER['SystemRoot'])) {
+            return $_SERVER['SystemRoot'] . '\\temp';
+        }
+        return '\temp';
+    }
+    if (isset($_ENV['TMPDIR'])) {
+        return $_ENV['TMPDIR'];
+    }
+    if (isset($_SERVER['TMPDIR'])) {
+        return $_SERVER['TMPDIR'];
+    }
+    return '/tmp';
+}
+
+?>
diff --git a/lib/tests/HTTP_Request2/HTTP/tests/AllTests.php b/lib/tests/HTTP_Request2/HTTP/tests/AllTests.php
new file mode 100644
index 00000000..7e84bead
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/AllTests.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290192 2009-11-03 21:29:32Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'HTTP_Request2_AllTests::main');
+}
+
+require_once 'PHPUnit/Framework.php';
+require_once 'PHPUnit/TextUI/TestRunner.php';
+
+chdir(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR);
+
+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()
+    {
+        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/tests/ObserverTest.php b/lib/tests/HTTP_Request2/HTTP/tests/ObserverTest.php
new file mode 100644
index 00000000..b5578d65
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/ObserverTest.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290192 2009-11-03 21:29:32Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP request
+ */
+require_once 'HTTP/Request2.php';
+
+/**
+ * PHPUnit Test Case
+ */
+require_once 'PHPUnit/Framework/TestCase.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/tests/Request2/Adapter/AllTests.php b/lib/tests/HTTP_Request2/HTTP/tests/Request2/Adapter/AllTests.php
new file mode 100644
index 00000000..05f9f876
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/Request2/Adapter/AllTests.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290192 2009-11-03 21:29:32Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'Request2_Adapter_AllTests::main');
+}
+
+require_once 'PHPUnit/Framework.php';
+require_once 'PHPUnit/TextUI/TestRunner.php';
+
+require_once dirname(__FILE__) . '/MockTest.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');
+
+        return $suite;
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'Request2_Adapter_AllTests::main') {
+    Request2_Adapter_AllTests::main();
+}
+?>
diff --git a/lib/tests/HTTP_Request2/HTTP/tests/Request2/Adapter/MockTest.php b/lib/tests/HTTP_Request2/HTTP/tests/Request2/Adapter/MockTest.php
new file mode 100644
index 00000000..b07036fb
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/Request2/Adapter/MockTest.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290192 2009-11-03 21:29:32Z 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';
+
+/**
+ * PHPUnit Test Case
+ */
+require_once 'PHPUnit/Framework/TestCase.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/tests/Request2/AllTests.php b/lib/tests/HTTP_Request2/HTTP/tests/Request2/AllTests.php
new file mode 100644
index 00000000..826b77d4
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/Request2/AllTests.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290192 2009-11-03 21:29:32Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'Request2_AllTests::main');
+}
+
+require_once 'PHPUnit/Framework.php';
+require_once 'PHPUnit/TextUI/TestRunner.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()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('HTTP_Request2 package - Request2');
+
+        $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/tests/Request2/MultipartBodyTest.php b/lib/tests/HTTP_Request2/HTTP/tests/Request2/MultipartBodyTest.php
new file mode 100644
index 00000000..9fd5d64a
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/Request2/MultipartBodyTest.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290192 2009-11-03 21:29:32Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP request
+ */
+require_once 'HTTP/Request2.php';
+
+/**
+ * PHPUnit Test Case
+ */
+require_once 'PHPUnit/Framework/TestCase.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);
+    }
+
+    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(dirname(dirname(__FILE__)) . '/_files/empty.gif', '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/tests/Request2/ResponseTest.php b/lib/tests/HTTP_Request2/HTTP/tests/Request2/ResponseTest.php
new file mode 100644
index 00000000..b605e066
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/Request2/ResponseTest.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290192 2009-11-03 21:29:32Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP response
+ */
+require_once 'HTTP/Request2/Response.php';
+
+/**
+ * PHPUnit Test Case
+ */
+require_once 'PHPUnit/Framework/TestCase.php';
+
+/**
+ * Unit test for HTTP_Request2_Response class
+ */
+class HTTP_Request2_ResponseTest extends PHPUnit_Framework_TestCase
+{
+    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());
+
+        try {
+            $response3 = new HTTP_Request2_Response('Invalid status line');
+        } catch (HTTP_Request2_Exception $e) {
+            return;
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+
+    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);
+        }
+    }
+
+    public function testGzipEncoding()
+    {
+        $response = $this->readResponseFromFile('response_gzip');
+        $this->assertEquals('0e964e9273c606c46afbd311b5ad4d77', md5($response->getBody()));
+
+        try {
+            $response = $this->readResponseFromFile('response_gzip_broken');
+            $body = $response->getBody();
+        } catch (HTTP_Request2_Exception $e) {
+            return;
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+
+    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()));
+    }
+
+    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/tests/Request2Test.php b/lib/tests/HTTP_Request2/HTTP/tests/Request2Test.php
new file mode 100644
index 00000000..34d30a53
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/Request2Test.php
@@ -0,0 +1,297 @@
+<?php
+/**
+ * Unit tests for HTTP_Request2 package
+ *
+ * PHP version 5
+ *
+ * LICENSE:
+ *
+ * Copyright (c) 2008, 2009, 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 290921 2009-11-18 17:31:58Z avb $
+ * @link       http://pear.php.net/package/HTTP_Request2
+ */
+
+/**
+ * Class representing a HTTP request
+ */
+require_once 'HTTP/Request2.php';
+
+/**
+ * PHPUnit Test Case
+ */
+require_once 'PHPUnit/Framework/TestCase.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'));
+    }
+
+    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());
+
+        try {
+            $req3 = new HTTP_Request2();
+            $req3->setUrl(array('This will cause an error'));
+        } catch (HTTP_Request2_Exception $e) {
+            return;
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+
+    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()
+        );
+    }
+
+    public function testSetMethod()
+    {
+        $req = new HTTP_Request2();
+        $req->setMethod(HTTP_Request2::METHOD_PUT);
+        $this->assertEquals(HTTP_Request2::METHOD_PUT, $req->getMethod());
+        try {
+            $req->setMethod('Invalid method');
+        } catch (HTTP_Request2_Exception $e) {
+            return;
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+
+    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'));
+        } catch (HTTP_Request2_Exception $e) {
+            try {
+                $req->getConfig('bar');
+            } catch (HTTP_Request2_Exception $e) {
+                return;
+            }
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+
+    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()
+        );
+
+        try {
+            $req->setHeader('Invalid header', 'value');
+        } catch (HTTP_Request2_Exception $e) {
+            return;
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+
+    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 testCookies()
+    {
+        $req = new HTTP_Request2();
+        $req->addCookie('name', 'value');
+        $req->addCookie('foo', 'bar');
+        $headers = $req->getHeaders();
+        $this->assertEquals('name=value; foo=bar', $headers['cookie']);
+
+        try {
+            $req->addCookie('invalid cookie', 'value');
+        } catch (HTTP_Request2_Exception $e) {
+            return;
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+
+    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->assertContains(
+            $headers['content-type'],
+            array('text/plain', 'application/octet-stream')
+        );
+        $this->assertEquals('This is a test.', fread($req->getBody(), 1024));
+
+        try {
+            $req->setBody('missing file', true);
+        } catch (HTTP_Request2_Exception $e) {
+            return;
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+
+    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());
+    }
+
+    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']);
+
+        try {
+            $req->addUpload('upload_2', 'missing file');
+        } catch (HTTP_Request2_Exception $e) {
+            return;
+        }
+        $this->fail('Expected HTTP_Request2_Exception was not thrown');
+    }
+
+    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()
+    {
+        $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());
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/tests/_files/bug_15305 b/lib/tests/HTTP_Request2/HTTP/tests/_files/bug_15305
new file mode 100644
index 0000000000000000000000000000000000000000..bbf6c70006b8062fd656063ee9cbbff16edf7f04
GIT binary patch
literal 16338
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
UqXW}M?@J}%n;dIGhvOgrAChp<KmY&$

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/tests/_files/empty.gif b/lib/tests/HTTP_Request2/HTTP/tests/_files/empty.gif
new file mode 100644
index 0000000000000000000000000000000000000000..1d11fa9ada9e93505b3d736acb204083f45d5fbf
GIT binary patch
literal 43
scmZ?wbhEHbWMp7uX!y@?;J^U}1_s5SEQ~;kK?g*DWEhy3To@Uw0n;G|I{*Lx

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/tests/_files/plaintext.txt b/lib/tests/HTTP_Request2/HTTP/tests/_files/plaintext.txt
new file mode 100644
index 00000000..273c1a9f
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/_files/plaintext.txt
@@ -0,0 +1 @@
+This is a test.
\ No newline at end of file
diff --git a/lib/tests/HTTP_Request2/HTTP/tests/_files/response_cookies b/lib/tests/HTTP_Request2/HTTP/tests/_files/response_cookies
new file mode 100644
index 00000000..8f0ab6b6
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/_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/tests/_files/response_deflate b/lib/tests/HTTP_Request2/HTTP/tests/_files/response_deflate
new file mode 100644
index 0000000000000000000000000000000000000000..e4e8adfd0d46af40addef96b0e95dad6243e6232
GIT binary patch
literal 1654
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
A`v3p{

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/tests/_files/response_gzip b/lib/tests/HTTP_Request2/HTTP/tests/_files/response_gzip
new file mode 100644
index 0000000000000000000000000000000000000000..79ad3b6eaac6737c9ae4a577347cb52e26ea5209
GIT binary patch
literal 1672
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
S;6Y|eWcmj?o~>Y#3;+OD2L>Ae

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/tests/_files/response_gzip_broken b/lib/tests/HTTP_Request2/HTTP/tests/_files/response_gzip_broken
new file mode 100644
index 0000000000000000000000000000000000000000..0df0d1522f8a377ac905b20db95eb29dc1428493
GIT binary patch
literal 221
zcmYL?%}N6?6h;efN+8eRT~;ueWJaY%T=?6flnywGJBjI~4V0T9bJ1yi1fR$Eb8zGK
zJBRblo2D+Twon=a%SS10J)?vB9FM_Rc<?k3YrvGwRL-2hY|%*Zg!u!rgR9nu4HlI)
zLt*kvu|JaHRn_SeGp^M2&Otq|i!)v7Qi_{IjKr$hwZjEt&qcfSkuD%?eD07hW0%x)
zdU~$xzkNp`ts<=*toO0~+X(~5L=M6>btr`thu`Dz*ZY1pI;h@^)!g&w=VkE=MxZ~{

literal 0
HcmV?d00001

diff --git a/lib/tests/HTTP_Request2/HTTP/tests/_files/response_headers b/lib/tests/HTTP_Request2/HTTP/tests/_files/response_headers
new file mode 100644
index 00000000..f60787bd
--- /dev/null
+++ b/lib/tests/HTTP_Request2/HTTP/tests/_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/Structures_Graph/tests/README b/lib/tests/Structures_Graph/tests/README
new file mode 100644
index 00000000..e69de29b
diff --git a/lib/tests/Structures_Graph/tests/all-tests.php b/lib/tests/Structures_Graph/tests/all-tests.php
new file mode 100644
index 00000000..7790ecd4
--- /dev/null
+++ b/lib/tests/Structures_Graph/tests/all-tests.php
@@ -0,0 +1,39 @@
+#!/usr/bin/php
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+// +-----------------------------------------------------------------------------+
+// | Copyright (c) 2003 S�rgio Gon�alves Carvalho                                |
+// +-----------------------------------------------------------------------------+
+// | This file is part of Structures_Graph.                                      |
+// |                                                                             |
+// | Structures_Graph is free software; you can redistribute it and/or modify    |
+// | it under the terms of the GNU Lesser General Public License as published by |
+// | the Free Software Foundation; either version 2.1 of the License, or         |
+// | (at your option) any later version.                                         |
+// |                                                                             |
+// | Structures_Graph is distributed in the hope that it will be useful,         |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
+// | GNU Lesser General Public License for more details.                         |
+// |                                                                             |
+// | You should have received a copy of the GNU Lesser General Public License    |
+// | along with Structures_Graph; if not, write to the Free Software             |
+// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                    |
+// | 02111-1307 USA                                                              |
+// +-----------------------------------------------------------------------------+
+// | Author: S�rgio Carvalho <sergio.carvalho@portugalmail.com>                  |
+// +-----------------------------------------------------------------------------+
+//
+
+// Place development Structures_Graph ahead in the include_path
+ini_set('include_path', realpath(dirname(__FILE__) . "/..") . ":.:" . ini_get('include_path'));
+
+require_once 'testCase/BasicGraph.php';
+require_once 'PHPUnit.php';
+
+$suite  = new PHPUnit_TestSuite();
+$suite->addTest(new PHPUnit_TestSuite('BasicGraph'));
+$result = PHPUnit::run($suite);
+
+echo $result->toString();
+?>
diff --git a/lib/tests/Structures_Graph/tests/testCase/BasicGraph.php b/lib/tests/Structures_Graph/tests/testCase/BasicGraph.php
new file mode 100644
index 00000000..6678587d
--- /dev/null
+++ b/lib/tests/Structures_Graph/tests/testCase/BasicGraph.php
@@ -0,0 +1,182 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+// +-----------------------------------------------------------------------------+
+// | Copyright (c) 2003 S�rgio Gon�alves Carvalho                                |
+// +-----------------------------------------------------------------------------+
+// | This file is part of Structures_Graph.                                      |
+// |                                                                             |
+// | Structures_Graph is free software; you can redistribute it and/or modify    |
+// | it under the terms of the GNU Lesser General Public License as published by |
+// | the Free Software Foundation; either version 2.1 of the License, or         |
+// | (at your option) any later version.                                         |
+// |                                                                             |
+// | Structures_Graph is distributed in the hope that it will be useful,         |
+// | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
+// | GNU Lesser General Public License for more details.                         |
+// |                                                                             |
+// | You should have received a copy of the GNU Lesser General Public License    |
+// | along with Structures_Graph; if not, write to the Free Software             |
+// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                    |
+// | 02111-1307 USA                                                              |
+// +-----------------------------------------------------------------------------+
+// | Author: S�rgio Carvalho <sergio.carvalho@portugalmail.com>                  |
+// +-----------------------------------------------------------------------------+
+//
+
+require_once 'Structures/Graph.php';
+require_once 'PHPUnit.php';
+
+/**
+ * @access private
+ */
+class BasicGraph extends PHPUnit_TestCase
+{
+    var $_graph = null;
+
+    // constructor of the test suite
+    function StringTest($name) {
+       $this->PHPUnit_TestCase($name);
+    }
+
+    function setUp() {
+    }
+
+    function tearDown() {
+    }
+
+    function test_create_graph() {
+        $this->_graph = new Structures_Graph();
+        $this->assertTrue(is_a($this->_graph, 'Structures_Graph')); 
+    }
+
+    function test_add_node() {
+        $this->_graph = new Structures_Graph();
+        $data = 1;
+        $node = new Structures_Graph_Node($data);
+        $this->_graph->addNode($node);
+        $node = new Structures_Graph_Node($data);
+        $this->_graph->addNode($node);
+        $node = new Structures_Graph_Node($data);
+        $this->_graph->addNode($node);
+    }
+
+    function test_connect_node() {
+        $this->_graph = new Structures_Graph();
+        $data = 1;
+        $node1 = new Structures_Graph_Node($data);
+        $node2 = new Structures_Graph_Node($data);
+        $this->_graph->addNode($node1);
+        $this->_graph->addNode($node2);
+        $node1->connectTo($node2);
+
+        $node =& $this->_graph->getNodes();
+        $node =& $node[0];
+        $node = $node->getNeighbours();
+        $node =& $node[0];
+        /* 
+         ZE1 == and === operators fail on $node,$node2 because of the recursion introduced
+         by the _graph field in the Node object. So, we'll use the stupid method for reference
+         testing
+        */
+        $node = true;
+        $this->assertTrue($node2);
+        $node = false;
+        $this->assertFalse($node2);
+    }
+
+    function test_data_references() {
+        $this->_graph = new Structures_Graph();
+        $data = 1;
+        $node = new Structures_Graph_Node();
+        $node->setData(&$data);
+        $this->_graph->addNode($node);
+        $data = 2;
+        $dataInNode =& $this->_graph->getNodes();
+        $dataInNode =& $dataInNode[0];
+        $dataInNode =& $dataInNode->getData();
+        $this->assertTrue($data === $dataInNode);
+    }
+
+    function test_metadata_references() {
+        $this->_graph = new Structures_Graph();
+        $data = 1;
+        $node = new Structures_Graph_Node();
+        $node->setMetadata('5', &$data);
+        $data = 2;
+        $dataInNode =& $node->getMetadata('5');
+        $this->assertTrue($data === $dataInNode);
+    }
+   
+    function test_metadata_key_exists() {
+        $this->_graph = new Structures_Graph();
+        $data = 1;
+        $node = new Structures_Graph_Node();
+        $node->setMetadata('5', $data);
+        $this->assertTrue($node->metadataKeyExists('5'));
+        $this->assertFalse($node->metadataKeyExists('1'));
+    }
+
+    function test_directed_degree() {
+        $this->_graph = new Structures_Graph(true);
+        $node = array();
+        $node[] = new Structures_Graph_Node();
+        $node[] = new Structures_Graph_Node();
+        $node[] = new Structures_Graph_Node();
+        $this->_graph->addNode($node[0]);
+        $this->_graph->addNode($node[1]);
+        $this->_graph->addNode($node[2]);
+        $this->assertEquals(0, $node[0]->inDegree(), 'inDegree test failed for node 0 with 0 arcs');
+        $this->assertEquals(0, $node[1]->inDegree(), 'inDegree test failed for node 1 with 0 arcs');
+        $this->assertEquals(0, $node[2]->inDegree(), 'inDegree test failed for node 2 with 0 arcs');
+        $this->assertEquals(0, $node[0]->outDegree(), 'outDegree test failed for node 0 with 0 arcs');
+        $this->assertEquals(0, $node[1]->outDegree(), 'outDegree test failed for node 1 with 0 arcs');
+        $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 0 arcs');
+        $node[0]->connectTo($node[1]);
+        $this->assertEquals(0, $node[0]->inDegree(), 'inDegree test failed for node 0 with 1 arc');
+        $this->assertEquals(1, $node[1]->inDegree(), 'inDegree test failed for node 1 with 1 arc');
+        $this->assertEquals(0, $node[2]->inDegree(), 'inDegree test failed for node 2 with 1 arc');
+        $this->assertEquals(1, $node[0]->outDegree(), 'outDegree test failed for node 0 with 1 arc');
+        $this->assertEquals(0, $node[1]->outDegree(), 'outDegree test failed for node 1 with 1 arc');
+        $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 1 arc');
+        $node[0]->connectTo($node[2]);
+        $this->assertEquals(0, $node[0]->inDegree(), 'inDegree test failed for node 0 with 2 arcs');
+        $this->assertEquals(1, $node[1]->inDegree(), 'inDegree test failed for node 1 with 2 arcs');
+        $this->assertEquals(1, $node[2]->inDegree(), 'inDegree test failed for node 2 with 2 arcs');
+        $this->assertEquals(2, $node[0]->outDegree(), 'outDegree test failed for node 0 with 2 arcs');
+        $this->assertEquals(0, $node[1]->outDegree(), 'outDegree test failed for node 1 with 2 arcs');
+        $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 2 arcs');
+    }
+
+    function test_undirected_degree() {
+        $this->_graph = new Structures_Graph(false);
+        $node = array();
+        $node[] = new Structures_Graph_Node();
+        $node[] = new Structures_Graph_Node();
+        $node[] = new Structures_Graph_Node();
+        $this->_graph->addNode($node[0]);
+        $this->_graph->addNode($node[1]);
+        $this->_graph->addNode($node[2]);
+        $this->assertEquals(0, $node[0]->inDegree(), 'inDegree test failed for node 0 with 0 arcs');
+        $this->assertEquals(0, $node[1]->inDegree(), 'inDegree test failed for node 1 with 0 arcs');
+        $this->assertEquals(0, $node[2]->inDegree(), 'inDegree test failed for node 2 with 0 arcs');
+        $this->assertEquals(0, $node[0]->outDegree(), 'outDegree test failed for node 0 with 0 arcs');
+        $this->assertEquals(0, $node[1]->outDegree(), 'outDegree test failed for node 1 with 0 arcs');
+        $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 0 arcs');
+        $node[0]->connectTo($node[1]);
+        $this->assertEquals(1, $node[0]->inDegree(), 'inDegree test failed for node 0 with 1 arc');
+        $this->assertEquals(1, $node[1]->inDegree(), 'inDegree test failed for node 1 with 1 arc');
+        $this->assertEquals(0, $node[2]->inDegree(), 'inDegree test failed for node 2 with 1 arc');
+        $this->assertEquals(1, $node[0]->outDegree(), 'outDegree test failed for node 0 with 1 arc');
+        $this->assertEquals(1, $node[1]->outDegree(), 'outDegree test failed for node 1 with 1 arc');
+        $this->assertEquals(0, $node[2]->outDegree(), 'outDegree test failed for node 2 with 1 arc');
+        $node[0]->connectTo($node[2]);
+        $this->assertEquals(2, $node[0]->inDegree(), 'inDegree test failed for node 0 with 2 arcs');
+        $this->assertEquals(1, $node[1]->inDegree(), 'inDegree test failed for node 1 with 2 arcs');
+        $this->assertEquals(1, $node[2]->inDegree(), 'inDegree test failed for node 2 with 2 arcs');
+        $this->assertEquals(2, $node[0]->outDegree(), 'outDegree test failed for node 0 with 2 arcs');
+        $this->assertEquals(1, $node[1]->outDegree(), 'outDegree test failed for node 1 with 2 arcs');
+        $this->assertEquals(1, $node[2]->outDegree(), 'outDegree test failed for node 2 with 2 arcs');
+    }
+}
+?>
diff --git a/lib/tests/UNL_Peoplefinder/pear.unl.edu/BrowserTest.php b/lib/tests/UNL_Peoplefinder/pear.unl.edu/BrowserTest.php
new file mode 100644
index 00000000..f7a8ce9c
--- /dev/null
+++ b/lib/tests/UNL_Peoplefinder/pear.unl.edu/BrowserTest.php
@@ -0,0 +1,46 @@
+<?php
+
+require_once 'Testing/Selenium.php';
+require_once 'PHPUnit/Framework/TestCase.php';
+
+class BrowserTest extends PHPUnit_Framework_TestCase
+{
+    function setUp()
+    {
+        $this->verificationErrors = array();
+        $this->selenium = new Testing_Selenium("*firefox", "http://peoplefinder.unl.edu/");
+        $result = $this->selenium->start();
+    }
+
+    function tearDown()
+    {
+        $this->selenium->stop();
+    }
+
+    function testBasicQuery()
+    {
+        $this->selenium->open("/");
+        $this->selenium->type("q", "Harvey Perlman");
+        $this->selenium->click("submitbutton");
+        $this->selenium->waitForPageToLoad("30000");
+        try {
+            $this->assertTrue($this->selenium->isTextPresent("Perlman, Harvey"));
+        } catch (PHPUnit_Framework_AssertionFailedError $e) {
+            array_push($this->verificationErrors, $e->toString());
+        }
+        $this->selenium->click("link=Perlman, Harvey");
+        $this->selenium->waitForPageToLoad("30000");
+        try {
+            $this->assertTrue($this->selenium->isTextPresent("Chancellor"));
+        } catch (PHPUnit_Framework_AssertionFailedError $e) {
+            array_push($this->verificationErrors, $e->toString());
+        }
+        try {
+            $this->assertTrue($this->selenium->isElementPresent("link=hperlman1@unl.edu"));
+        } catch (PHPUnit_Framework_AssertionFailedError $e) {
+            array_push($this->verificationErrors, $e->toString());
+        }
+
+    }
+}
+?>
\ No newline at end of file
diff --git a/lib/tests/UNL_Peoplefinder/pear.unl.edu/OUTest.php b/lib/tests/UNL_Peoplefinder/pear.unl.edu/OUTest.php
new file mode 100644
index 00000000..15c5adc7
--- /dev/null
+++ b/lib/tests/UNL_Peoplefinder/pear.unl.edu/OUTest.php
@@ -0,0 +1,3 @@
+<?php
+
+?>
\ No newline at end of file
diff --git a/lib/tests/UNL_Peoplefinder/pear.unl.edu/PeoplefinderTest.php b/lib/tests/UNL_Peoplefinder/pear.unl.edu/PeoplefinderTest.php
new file mode 100644
index 00000000..11f81305
--- /dev/null
+++ b/lib/tests/UNL_Peoplefinder/pear.unl.edu/PeoplefinderTest.php
@@ -0,0 +1,232 @@
+<?php
+// Call PeoplefinderTest::main() if this source file is executed directly.
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'PeoplefinderTest::main');
+}
+
+require_once 'PHPUnit/Framework.php';
+chdir(dirname(__FILE__).'/../');
+require_once 'config.inc.php';
+require_once 'UNL/Peoplefinder.php';
+
+/**
+ * Test class for Peoplefinder.
+ * Generated by PHPUnit on 2007-11-14 at 08:59:54.
+ */
+class PeoplefinderTest extends PHPUnit_Framework_TestCase {
+    /**
+     * Runs the test methods of this class.
+     *
+     * @access public
+     * @static
+     */
+    public static function main() {
+        require_once 'PHPUnit/TextUI/TestRunner.php';
+
+        $suite  = new PHPUnit_Framework_TestSuite('PeoplefinderTest');
+        require_once dirname(__FILE__).'/BrowserTest.php';
+        $suite->addTest(new BrowserTest());
+        $result = PHPUnit_TextUI_TestRunner::run($suite);
+    }
+
+    /**
+     * Sets up the fixture, for example, opens a network connection.
+     * This method is called before a test is executed.
+     *
+     * @access protected
+     */
+    protected function setUp() {
+    }
+
+    /**
+     * Tears down the fixture, for example, closes a network connection.
+     * This method is called after a test is executed.
+     *
+     * @access protected
+     */
+    protected function tearDown() {
+    }
+
+    /**
+     * Tests binding to the LDAP directory.
+     */
+    public function testBind() {
+        $p = new UNL_Peoplefinder();
+        $this->assertEquals(true, $p->bind(), 'Cannot connect to the LDAP directory.');
+    }
+
+    /**
+     * @todo Implement testQuery().
+     */
+    public function testQuery() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * Tests unbinding from the LDAP directory.
+     */
+    public function testUnbind() {
+        $p = new UNL_Peoplefinder();
+        $this->assertEquals(true, $p->bind());
+        $this->assertEquals(true, $p->unbind());
+    }
+
+    /**
+     * Tests searching for exact matches to a query.
+     */
+    public function testGetExactMatches() {
+        $p = new UNL_Peoplefinder();
+        $r = $p->getExactMatches('Harvey Perlman');
+        $this->assertTrue(is_array($r), 'An array of results was not returned.');
+        $this->assertEquals(1, count($r), 'The size of the result set is not what was expected.');
+        $this->assertEquals('Harvey', $r[0]->givenName);
+    }
+    
+    /**
+     * Makes sure that no results are returned for someone that does not exist.
+     *
+     */
+    public function testGetExactMatches2() {
+        $p = new UNL_Peoplefinder();
+        $r = $p->getExactMatches('ThisPerson DoesNotExist');
+        $this->assertTrue(is_array($r), 'An array of results was not returned.');
+        $this->assertEquals(0, count($r), 'The size of the result set is not what was expected.');
+    }
+
+    /**
+     * Test an advanced query.
+     */
+    public function testGetAdvancedSearchMatches() {
+        $p = new UNL_Peoplefinder();
+        $r = $p->getAdvancedSearchMatches('Perlman', 'Harvey', 'staff');
+        $this->assertTrue(is_array($r), 'An array of results was not returned.');
+        $this->assertEquals(1, count($r), 'The size of the result set is not what was expected.');
+        
+        $r = $p->getAdvancedSearchMatches('Perlman', 'Harvey', 'student');
+        $this->assertTrue(is_array($r), 'An array of results was not returned.');
+        $this->assertEquals(0, count($r), 'The size of the result set is not what was expected.');
+    }
+
+    /**
+     * Get matches using a little fuzzy logic.
+     */
+    public function testGetLikeMatches() {
+        $p = new UNL_Peoplefinder();
+        $r = $p->getLikeMatches('bieber');
+        $this->assertEquals(7, sizeof($r));
+        $r = $p->getLikeMatches('bieber', array($r[0]), 'Testing exclusion of records did not work.');
+        $this->assertEquals(5, sizeof($r));
+        $r = $p->getLikeMatches('bieber', $r, 'Testing exclusion of records did not work.');
+        $this->assertEquals(1, sizeof($r));
+    }
+
+    /**
+     * Tests that matches are returned by phone number query.
+     */
+    public function testGetPhoneMatches() {
+        $p = new UNL_Peoplefinder();
+        $r = $p->getPhoneMatches('1598');
+        $this->assertEquals($r[0]->telephoneNumber, '(402)472-1598');
+        $r = $p->getPhoneMatches('472-1598');
+        $this->assertEquals($r[0]->telephoneNumber, '(402)472-1598');
+    }
+
+    /**
+     * Test grabbing an individual record.
+     */
+    public function testGetUID() {
+        $p = new UNL_Peoplefinder();
+        $r = $p->getUID('bbieber2');
+        $this->assertEquals('UNL_Peoplefinder_Record', get_class($r));
+        $this->assertEquals('Brett', $r->givenName);
+    }
+    
+    /**
+     * Tests that an exception is thrown when an invalid uid is queried for.
+     * @expectedException Exception
+     */
+    public function testGetUID2() {
+        $p = new UNL_Peoplefinder();
+        $this->setExpectedException('Exception');
+        $r = $p->getUID('thispersondoesnotexist');
+    }
+
+    /**
+     * @todo Implement testArray_csort().
+     */
+    public function testArray_csort() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testBuildStandardFilter().
+     */
+    public function testBuildStandardFilter() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testBuildAdvancedFilter().
+     */
+    public function testBuildAdvancedFilter() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testBuildFilter().
+     */
+    public function testBuildFilter() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+    
+    public function testFormatAddress() {
+        $r = unserialize('O:23:"UNL_Peoplefinder_Record":27:{s:2:"cn";s:12:"Brett Bieber";s:17:"eduPersonNickname";N;s:27:"eduPersonPrimaryAffiliation";s:5:"staff";s:9:"givenName";s:5:"Brett";s:11:"displayName";s:14:"Brett T Bieber";s:4:"mail";s:24:"bbieber@unlnotes.unl.edu";s:13:"postalAddress";s:26:"326D ADMN  UNL  68588-0424";s:2:"sn";s:6:"Bieber";s:15:"telephoneNumber";s:13:"(402)472-1598";s:5:"title";s:22:"Web Programmer/Analyst";s:3:"uid";s:8:"bbieber2";s:22:"unlHRPrimaryDepartment";s:25:"Office of University Comm";s:12:"unlHRAddress";s:26:"326D ADMN  UNL  68588-0424";s:16:"unlSISClassLevel";N;s:13:"unlSISCollege";N;s:16:"unlSISLocalAddr1";N;s:16:"unlSISLocalAddr2";N;s:15:"unlSISLocalCity";N;s:16:"unlSISLocalState";N;s:14:"unlSISLocalZip";N;s:15:"unlSISPermAddr1";N;s:15:"unlSISPermAddr2";N;s:14:"unlSISPermCity";N;s:15:"unlSISPermState";N;s:13:"unlSISPermZip";N;s:11:"unlSISMajor";N;s:13:"unlEmailAlias";s:8:"bbieber2";}');
+        $address = $r->formatPostalAddress();
+        $this->assertEquals('a:4:{s:6:"region";s:2:"NE";s:14:"street-address";s:9:"326D ADMN";s:11:"postal-code";s:10:"68588-0424";s:8:"locality";s:7:"Lincoln";}',
+                            serialize($address));
+
+        $r = unserialize('O:23:"UNL_Peoplefinder_Record":27:{s:2:"cn";s:10:"Ivy Miller";s:17:"eduPersonNickname";N;s:27:"eduPersonPrimaryAffiliation";s:5:"staff";s:9:"givenName";s:3:"Ivy";s:11:"displayName";s:12:"Ivy E Miller";s:4:"mail";s:24:"imiller@mail.unomaha.edu";s:13:"postalAddress";s:25:"103C PKI  UNO  68182-0681";s:2:"sn";s:6:"Miller";s:15:"telephoneNumber";s:13:"(402)554-3856";s:5:"title";s:25:"Administrative Technician";s:3:"uid";s:8:"imiller2";s:22:"unlHRPrimaryDepartment";s:25:"Architectural Engineering";s:12:"unlHRAddress";s:25:"103C PKI  UNO  68182-0681";s:16:"unlSISClassLevel";N;s:13:"unlSISCollege";N;s:16:"unlSISLocalAddr1";N;s:16:"unlSISLocalAddr2";N;s:15:"unlSISLocalCity";N;s:16:"unlSISLocalState";N;s:14:"unlSISLocalZip";N;s:15:"unlSISPermAddr1";N;s:15:"unlSISPermAddr2";N;s:14:"unlSISPermCity";N;s:15:"unlSISPermState";N;s:13:"unlSISPermZip";N;s:11:"unlSISMajor";N;s:13:"unlEmailAlias";s:8:"imiller2";}');
+        $address = $r->formatPostalAddress();
+        $this->assertEquals('a:4:{s:6:"region";s:2:"NE";s:14:"street-address";s:8:"103C PKI";s:11:"postal-code";s:10:"68182-0681";s:8:"locality";s:5:"Omaha";}',
+                            serialize($address));
+                            
+    }
+    
+    /**
+     * Tests rendering a student record with no local address.
+     *
+     */
+    public function testStudentWithNoLocalAddress()
+    {
+        $r = unserialize('O:23:"UNL_Peoplefinder_Record":27:{s:2:"cn";s:21:"Chandra Brandenburger";s:17:"eduPersonNickname";N;s:27:"eduPersonPrimaryAffiliation";s:7:"student";s:9:"givenName";s:7:"Chandra";s:11:"displayName";s:29:"Chandra Rachael Brandenburger";s:4:"mail";N;s:13:"postalAddress";N;s:2:"sn";s:13:"Brandenburger";s:15:"telephoneNumber";N;s:5:"title";N;s:3:"uid";s:10:"s-cbrande6";s:22:"unlHRPrimaryDepartment";N;s:12:"unlHRAddress";N;s:16:"unlSISClassLevel";s:2:"FR";s:13:"unlSISCollege";s:3:"ARH";s:16:"unlSISLocalAddr1";N;s:16:"unlSISLocalAddr2";N;s:15:"unlSISLocalCity";N;s:16:"unlSISLocalState";N;s:14:"unlSISLocalZip";N;s:15:"unlSISPermAddr1";s:13:"1121 N 9th St";s:15:"unlSISPermAddr2";N;s:14:"unlSISPermCity";s:7:"Norfolk";s:15:"unlSISPermState";s:2:"NE";s:13:"unlSISPermZip";s:5:"68701";s:11:"unlSISMajor";s:4:"PARC";s:13:"unlEmailAlias";N;}');
+        require_once 'UNL/Peoplefinder/Renderer/HTML.php';
+        $renderer = new UNL_Peoplefinder_Renderer_HTML();
+        ob_start();
+        $renderer->renderRecord($r);
+        $h = ob_get_clean();
+        //file_put_contents(dirname(__FILE__).'/testStudentWithNoLocalAddress.html', $h);
+        $this->assertEquals(file_get_contents(dirname(__FILE__).'/testStudentWithNoLocalAddress.html'), $h);
+    }
+
+}
+
+// Call PeoplefinderTest::main() if this source file is executed directly.
+if (PHPUnit_MAIN_METHOD == 'PeoplefinderTest::main') {
+    PeoplefinderTest::main();
+}
+?>
diff --git a/lib/tests/UNL_Peoplefinder/pear.unl.edu/testStudentWithNoLocalAddress.html b/lib/tests/UNL_Peoplefinder/pear.unl.edu/testStudentWithNoLocalAddress.html
new file mode 100644
index 00000000..e0cc4d33
--- /dev/null
+++ b/lib/tests/UNL_Peoplefinder/pear.unl.edu/testStudentWithNoLocalAddress.html
@@ -0,0 +1,18 @@
+<div class='vcard'>
+<span class="fn">Chandra Rachael Brandenburger</span>
+<span class="eppa">(student)</span>
+<div class="vcardInfo">
+<span class="title">Freshman, PARC&ndash;ARH</span>
+        <div id="homeAdr" class="adr">
+         <span class="type">Home</span>
+         <span class="street-address">1121 N 9th St</span>
+         <span class="locality">Norfolk</span>
+         <span class="region">NE</span>
+         <span class="postal-code">68701</span></div><span class='title'></span>
+<span class='org'>
+	<span class='organization-name'>University of Nebraska-Lincoln</span>
+	<span class='organization-unit'></span>
+</span>
+<a href="http://peoplefinder.unl.edu/vcards/s-cbrande6" title="Download V-Card for Chandra Brandenburger"><img src="http://www.unl.edu/unlpub/2004sharedgraphics/icon_vcard.gif" alt="V-Card" />
+</a></div>
+</div>
diff --git a/lib/tests/UNL_Templates/tests/UNL_TemplatesTest.php b/lib/tests/UNL_Templates/tests/UNL_TemplatesTest.php
new file mode 100644
index 00000000..d8a41641
--- /dev/null
+++ b/lib/tests/UNL_Templates/tests/UNL_TemplatesTest.php
@@ -0,0 +1,172 @@
+<?php
+// Call UNL_TemplatesTest::main() if this source file is executed directly.
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'UNL_TemplatesTest::main');
+}
+
+require_once 'PHPUnit/Framework.php';
+
+require_once 'UNL/Templates.php';
+
+/**
+ * Test class for UNL_Templates.
+ * Generated by PHPUnit on 2007-11-29 at 16:07:45.
+ */
+class UNL_TemplatesTest extends PHPUnit_Framework_TestCase {
+    /**
+     * Runs the test methods of this class.
+     *
+     * @access public
+     * @static
+     */
+    public static function main() {
+        require_once 'PHPUnit/TextUI/TestRunner.php';
+
+        $suite  = new PHPUnit_Framework_TestSuite('UNL_TemplatesTest');
+        $result = PHPUnit_TextUI_TestRunner::run($suite);
+    }
+
+    /**
+     * Sets up the fixture, for example, opens a network connection.
+     * This method is called before a test is executed.
+     *
+     * @access protected
+     */
+    protected function setUp() {
+    }
+
+    /**
+     * Tears down the fixture, for example, closes a network connection.
+     * This method is called after a test is executed.
+     *
+     * @access protected
+     */
+    protected function tearDown() {
+    }
+
+    /**
+     * @todo Implement test__constructor().
+     */
+    public function test__constructor() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testLoadDefaultConfig().
+     */
+    public function testLoadDefaultConfig() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testFactory().
+     */
+    public function testFactory() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testGetCache().
+     */
+    public function testGetCache() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testLoadSharedcodeFiles().
+     */
+    public function testLoadSharedcodeFiles() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testAddHeadLink().
+     */
+    public function testAddHeadLink() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testAddScript().
+     */
+    public function testAddScript() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testAddScriptDeclaration().
+     */
+    public function testAddScriptDeclaration() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testAddStyleDeclaration().
+     */
+    public function testAddStyleDeclaration() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testAddStyleSheet().
+     */
+    public function testAddStyleSheet() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testToHtml().
+     */
+    public function testToHtml() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+
+    /**
+     * @todo Implement testMakeIncludeReplacements().
+     */
+    public function testMakeIncludeReplacements() {
+        // Remove the following lines when you implement this test.
+        $this->markTestIncomplete(
+          'This test has not been implemented yet.'
+        );
+    }
+}
+
+// Call UNL_TemplatesTest::main() if this source file is executed directly.
+if (PHPUnit_MAIN_METHOD == 'UNL_TemplatesTest::main') {
+    UNL_TemplatesTest::main();
+}
+?>
diff --git a/lib/tests/XML_Util/XML/tests/AllTests.php b/lib/tests/XML_Util/XML/tests/AllTests.php
new file mode 100644
index 00000000..7a21a842
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/AllTests.php
@@ -0,0 +1,132 @@
+<?php
+
+/**
+ * Master Unit Test Suite file for XML_Util
+ * 
+ * This top-level test suite file organizes 
+ * all class test suite files, 
+ * so that the full suite can be run 
+ * by PhpUnit or via "pear run-tests -u". 
+ *
+ * PHP version 5
+ *
+ * @category   XML
+ * @package    XML_Util
+ * @subpackage UnitTesting
+ * @author     Chuck Burgess <ashnazg@php.net>
+ * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version    CVS: $Id: AllTests.php,v 1.5 2008/05/30 11:53:09 ashnazg Exp $
+ * @link       http://pear.php.net/package/XML_Util
+ * @since      1.2.0a1
+ */
+
+
+/**
+ * Check PHP version... PhpUnit v3+ requires at least PHP v5.1.4
+ */
+if (version_compare(PHP_VERSION, "5.1.4") < 0) {
+    // Cannnot run test suites
+    echo 'Cannot run test suite via PhpUnit... requires at least PHP v5.1.4.' . PHP_EOL;
+    echo 'Use "pear run-tests -p xml_util" to run the PHPT tests directly.' . PHP_EOL
+;
+    exit(1);
+}
+
+
+/**
+ * Derive the "main" method name
+ * @internal PhpUnit would have to rename PHPUnit_MAIN_METHOD to PHPUNIT_MAIN_METHOD
+ *           to make this usage meet the PEAR CS... we cannot rename it here.
+ */
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'XML_Util_AllTests::main');
+}
+
+
+/*
+ * Files needed by PhpUnit
+ */
+require_once 'PHPUnit/Framework.php';
+require_once 'PHPUnit/TextUI/TestRunner.php';
+require_once 'PHPUnit/Extensions/PhptTestSuite.php';
+
+/*
+ * You must add each additional class-level test suite file here
+ */
+// there are no PhpUnit test files... only PHPTs.. so nothing is listed here
+
+/**
+ * directory where PHPT tests are located
+ */
+define('XML_UTIL_DIR_PHPT', dirname(__FILE__));
+
+/**
+ * Master Unit Test Suite class for XML_Util
+ * 
+ * This top-level test suite class organizes 
+ * all class test suite files, 
+ * so that the full suite can be run 
+ * by PhpUnit or via "pear run-tests -up xml_util". 
+ *
+ * @category   XML
+ * @package    XML_Util
+ * @subpackage UnitTesting
+ * @author     Chuck Burgess <ashnazg@php.net>
+ * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version    Release: @package_version@
+ * @link       http://pear.php.net/package/XML_Util
+ * @since      1.2.0a1
+ */
+class XML_Util_AllTests
+{
+
+    /**
+     * Launches the TextUI test runner
+     *
+     * @return void
+     * @uses PHPUnit_TextUI_TestRunner
+     */
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+
+    /**
+     * Adds all class test suites into the master suite
+     *
+     * @return PHPUnit_Framework_TestSuite a master test suite
+     *                                     containing all class test suites
+     * @uses PHPUnit_Framework_TestSuite
+     */ 
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite(
+            'XML_Util Full Suite of Unit Tests');
+
+        /*
+         * You must add each additional class-level test suite name here
+         */
+        // there are no PhpUnit test files... only PHPTs.. so nothing is listed here
+
+        /*
+         * add PHPT tests
+         */
+        $phpt = new PHPUnit_Extensions_PhptTestSuite(XML_UTIL_DIR_PHPT);
+        $suite->addTestSuite($phpt);
+
+        return $suite;
+    }
+}
+
+/**
+ * Call the main method if this file is executed directly
+ * @internal PhpUnit would have to rename PHPUnit_MAIN_METHOD to PHPUNIT_MAIN_METHOD
+ *           to make this usage meet the PEAR CS... we cannot rename it here.
+ */
+if (PHPUnit_MAIN_METHOD == 'XML_Util_AllTests::main') {
+    XML_Util_AllTests::main();
+}
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+?>
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_apiVersion.phpt b/lib/tests/XML_Util/XML/tests/testBasic_apiVersion.phpt
new file mode 100644
index 00000000..649e290e
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_apiVersion.phpt
@@ -0,0 +1,18 @@
+--TEST--
+XML_Util::apiVersion() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::apiVersion() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic apiVersion() call" . PHP_EOL;
+echo XML_Util::apiVersion() . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::apiVersion() basic tests=====
+
+TEST:  basic apiVersion() call
+1.1
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_attributesToString.phpt b/lib/tests/XML_Util/XML/tests/testBasic_attributesToString.phpt
new file mode 100644
index 00000000..51c81d30
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_attributesToString.phpt
@@ -0,0 +1,118 @@
+--TEST--
+XML_Util::attributesToString() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::attributesToString() basic tests=====' . PHP_EOL . PHP_EOL;
+
+$att = array("foo" => "bar", "boo" => "baz");
+$sort1 = array(
+    'multiline' => true, 
+    'indent'    => '----', 
+    'linebreak' => "^", 
+    'entities'  => XML_UTIL_ENTITIES_XML, 
+    'sort'      => true
+);
+$sort2 = array(
+    'multiline' => true, 
+    'indent'    => '----', 
+    'linebreak' => "^", 
+    'entities'  => XML_UTIL_ENTITIES_XML, 
+);
+
+echo "TEST:  basic usage" . PHP_EOL;
+echo XML_Util::attributesToString($att) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  explicit \$sort = true" . PHP_EOL;
+echo XML_Util::attributesToString($att, true) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  explicit \$sort = false" . PHP_EOL;
+echo XML_Util::attributesToString($att, false) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  explicit \$multiline = false" . PHP_EOL;
+echo XML_Util::attributesToString($att, true, false) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  explicit \$multiline = true" . PHP_EOL;
+echo XML_Util::attributesToString($att, true, true) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  explicit \$indent = '        ' (8 spaces)" . PHP_EOL;
+echo XML_Util::attributesToString($att, true, true, '        ') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  explicit \$linebreak = '^' (some dummy char)" . PHP_EOL;
+echo XML_Util::attributesToString($att, true, true, '^') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  passing \$sort array of options that includes 'sort'" . PHP_EOL;
+echo XML_Util::attributesToString($att, $sort1) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  passing \$sort array of options that doesn't include 'sort'" . PHP_EOL;
+echo XML_Util::attributesToString($att, $sort2) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  do not replace entities" . PHP_EOL;
+$arr = array("foo" => "b@&r", "boo" => "b><z");
+echo XML_Util::attributesToString($arr, true, false, '    ', PHP_EOL, 
+    XML_UTIL_ENTITIES_NONE) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  replace all XML entities" . PHP_EOL;
+$arr = array("foo" => "b@&r", "boo" => "b><z");
+echo XML_Util::attributesToString($arr, true, false, '    ', PHP_EOL, 
+    XML_UTIL_ENTITIES_XML) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  replace only required XML entities" . PHP_EOL;
+$arr = array("foo" => "b@&r", "boo" => "b><z");
+echo XML_Util::attributesToString($arr, true, false, '    ', PHP_EOL, 
+    XML_UTIL_ENTITIES_XML_REQUIRED) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  replace HTML entities" . PHP_EOL;
+$arr = array("foo" => "b@&r", "boo" => "b><z");
+echo XML_Util::attributesToString($arr, true, false, '    ', PHP_EOL, 
+    XML_UTIL_ENTITIES_HTML) . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::attributesToString() basic tests=====
+
+TEST:  basic usage
+ boo="baz" foo="bar"
+
+TEST:  explicit $sort = true
+ boo="baz" foo="bar"
+
+TEST:  explicit $sort = false
+ foo="bar" boo="baz"
+
+TEST:  explicit $multiline = false
+ boo="baz" foo="bar"
+
+TEST:  explicit $multiline = true
+ boo="baz"
+    foo="bar"
+
+TEST:  explicit $indent = '        ' (8 spaces)
+ boo="baz"
+        foo="bar"
+
+TEST:  explicit $linebreak = '^' (some dummy char)
+ boo="baz"
+^foo="bar"
+
+TEST:  passing $sort array of options that includes 'sort'
+ boo="baz"
+----foo="bar"
+
+TEST:  passing $sort array of options that doesn't include 'sort'
+ boo="baz"
+----foo="bar"
+
+TEST:  do not replace entities
+ boo="b><z" foo="b@&r"
+
+TEST:  replace all XML entities
+ boo="b&gt;&lt;z" foo="b@&amp;r"
+
+TEST:  replace only required XML entities
+ boo="b>&lt;z" foo="b@&amp;r"
+
+TEST:  replace HTML entities
+ boo="b&gt;&lt;z" foo="b@&amp;r"
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_collapseEmptyTags.phpt b/lib/tests/XML_Util/XML/tests/testBasic_collapseEmptyTags.phpt
new file mode 100644
index 00000000..dcc1c4f4
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_collapseEmptyTags.phpt
@@ -0,0 +1,52 @@
+--TEST--
+XML_Util::collapseEmptyTags() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::collapseEmptyTags() basic tests=====' . PHP_EOL . PHP_EOL;
+
+$emptyTag = "<foo></foo>";
+$otherTag = "<bar>baz</bar>";
+$xhtmlTag = "<b></b>";
+
+echo "TEST:  basic usage" . PHP_EOL;
+echo XML_Util::collapseEmptyTags($emptyTag) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage alongside non-empty tag" . PHP_EOL;
+echo XML_Util::collapseEmptyTags($emptyTag . $otherTag) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  one empty tag, with COLLAPSE_ALL set" . PHP_EOL;
+echo XML_Util::collapseEmptyTags($emptyTag, XML_UTIL_COLLAPSE_ALL) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  one empty tag alongside non-empty tag, with COLLAPSE_ALL set" . PHP_EOL;
+echo XML_Util::collapseEmptyTags($emptyTag . $otherTag, XML_UTIL_COLLAPSE_ALL) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  one empty tag, with COLLAPSE_XHTML_ONLY set" . PHP_EOL;
+echo XML_Util::collapseEmptyTags($emptyTag, XML_UTIL_COLLAPSE_XHTML_ONLY) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  one empty tag alongside non-empty tag, with COLLAPSE_XHTML_ONLY set" . PHP_EOL;
+echo XML_Util::collapseEmptyTags($emptyTag . $xhtmlTag . $otherTag, XML_UTIL_COLLAPSE_XHTML_ONLY) . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::collapseEmptyTags() basic tests=====
+
+TEST:  basic usage
+<foo />
+
+TEST:  basic usage alongside non-empty tag
+<foo /><bar>baz</bar>
+
+TEST:  one empty tag, with COLLAPSE_ALL set
+<foo />
+
+TEST:  one empty tag alongside non-empty tag, with COLLAPSE_ALL set
+<foo /><bar>baz</bar>
+
+TEST:  one empty tag, with COLLAPSE_XHTML_ONLY set
+<foo></foo>
+
+TEST:  one empty tag alongside non-empty tag, with COLLAPSE_XHTML_ONLY set
+<foo></foo><b></b><bar>baz</bar>
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_createCDataSection.phpt b/lib/tests/XML_Util/XML/tests/testBasic_createCDataSection.phpt
new file mode 100644
index 00000000..8616ce5f
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_createCDataSection.phpt
@@ -0,0 +1,18 @@
+--TEST--
+XML_Util::createCDataSection() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::createCDataSection() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage" . PHP_EOL;
+echo XML_Util::createCDataSection("I am content.") . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::createCDataSection() basic tests=====
+
+TEST:  basic usage
+<![CDATA[I am content.]]>
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_createComment.phpt b/lib/tests/XML_Util/XML/tests/testBasic_createComment.phpt
new file mode 100644
index 00000000..94e56c84
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_createComment.phpt
@@ -0,0 +1,18 @@
+--TEST--
+XML_Util::createComment() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::createComment() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage" . PHP_EOL;
+echo XML_Util::createComment("I am comment.") . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::createComment() basic tests=====
+
+TEST:  basic usage
+<!-- I am comment. -->
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_createEndElement.phpt b/lib/tests/XML_Util/XML/tests/testBasic_createEndElement.phpt
new file mode 100644
index 00000000..cde66fd9
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_createEndElement.phpt
@@ -0,0 +1,24 @@
+--TEST--
+XML_Util::createEndElement() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::createEndElement() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage (myTag)" . PHP_EOL;
+echo XML_Util::createEndElement("myTag") . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a namespaced tag (myNs:myTag)" . PHP_EOL;
+echo XML_Util::createEndElement("myNs:myTag") . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::createEndElement() basic tests=====
+
+TEST:  basic usage (myTag)
+</myTag>
+
+TEST:  basic usage with a namespaced tag (myNs:myTag)
+</myNs:myTag>
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_createStartElement.phpt b/lib/tests/XML_Util/XML/tests/testBasic_createStartElement.phpt
new file mode 100644
index 00000000..8587bbf1
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_createStartElement.phpt
@@ -0,0 +1,124 @@
+--TEST--
+XML_Util::createStartElement() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::createStartElement() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag only" . PHP_EOL;
+echo XML_Util::createStartElement(
+    "myNs:myTag"
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attributes" . PHP_EOL;
+echo XML_Util::createStartElement(
+    "myNs:myTag", 
+    array("foo" => "bar")
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag only, passing '' as attribute arg" . PHP_EOL;
+echo XML_Util::createStartElement(
+    'myNs:myTag',
+    ''
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attributes and namespace" . PHP_EOL;
+echo XML_Util::createStartElement(
+    "myNs:myTag", 
+    array("foo" => "bar"),
+    "http://www.w3c.org/myNs#"
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with empty attributes, whose namespaceUri is not a full namespace" . PHP_EOL;
+echo XML_Util::createStartElement(
+    'myTag',
+    '',
+    'foo'
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attributes, namespace, and multiline = true" . PHP_EOL;
+echo XML_Util::createStartElement(
+    "myNs:myTag", 
+    array("foo" => "bar"),
+    "http://www.w3c.org/myNs#",
+    true
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attributes, namespace, multiline = true, and indent = (2 spaces only)" . PHP_EOL;
+echo XML_Util::createStartElement(
+    "myNs:myTag", 
+    array("foo" => "bar"),
+    "http://www.w3c.org/myNs#",
+    true,
+    '  '
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attributes, namespace, multiline = true, indent = (2 spaces only), and linebreak = '^'" . PHP_EOL;
+echo XML_Util::createStartElement(
+    "myNs:myTag", 
+    array("foo" => "bar"),
+    "http://www.w3c.org/myNs#",
+    true,
+    '  ',
+    '^'
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attributes, namespace, multiline = true, indent = (2 spaces only), linebreak = '^', and sortAttributes = true" . PHP_EOL;
+echo XML_Util::createStartElement(
+    "myNs:myTag", 
+    array("foo" => "bar", "boo" => "baz"),
+    "http://www.w3c.org/myNs#",
+    true,
+    '  ',
+    '^',
+    true
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attributes, namespace, multiline = true, indent = (2 spaces only), linebreak = '^', and sortAttributes = false" . PHP_EOL;
+echo XML_Util::createStartElement(
+    "myNs:myTag", 
+    array("foo" => "bar", "boo" => "baz"),
+    "http://www.w3c.org/myNs#",
+    true,
+    '  ',
+    '^',
+    false
+) . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::createStartElement() basic tests=====
+
+TEST:  tag only
+<myNs:myTag>
+
+TEST:  tag with attributes
+<myNs:myTag foo="bar">
+
+TEST:  tag only, passing '' as attribute arg
+<myNs:myTag>
+
+TEST:  tag with attributes and namespace
+<myNs:myTag foo="bar" xmlns:myNs="http://www.w3c.org/myNs#">
+
+TEST:  tag with empty attributes, whose namespaceUri is not a full namespace
+<myTag xmlns="foo">
+
+TEST:  tag with attributes, namespace, and multiline = true
+<myNs:myTag foo="bar"
+            xmlns:myNs="http://www.w3c.org/myNs#">
+
+TEST:  tag with attributes, namespace, multiline = true, and indent = (2 spaces only)
+<myNs:myTag foo="bar"
+  xmlns:myNs="http://www.w3c.org/myNs#">
+
+TEST:  tag with attributes, namespace, multiline = true, indent = (2 spaces only), and linebreak = '^'
+<myNs:myTag foo="bar"^  xmlns:myNs="http://www.w3c.org/myNs#">
+
+TEST:  tag with attributes, namespace, multiline = true, indent = (2 spaces only), linebreak = '^', and sortAttributes = true
+<myNs:myTag boo="baz"^  foo="bar"^  xmlns:myNs="http://www.w3c.org/myNs#">
+
+TEST:  tag with attributes, namespace, multiline = true, indent = (2 spaces only), linebreak = '^', and sortAttributes = false
+<myNs:myTag foo="bar"^  boo="baz"^  xmlns:myNs="http://www.w3c.org/myNs#">
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_createTag.phpt b/lib/tests/XML_Util/XML/tests/testBasic_createTag.phpt
new file mode 100644
index 00000000..6a114e92
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_createTag.phpt
@@ -0,0 +1,155 @@
+--TEST--
+XML_Util::createTag() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::createTag() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar")
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute and content" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar"), 
+    "This is inside the tag"
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute, content, and namespace" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar"), 
+    "This is inside the tag",
+    "http://www.w3c.org/myNs#"
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute, content, namespace, and REPLACE_ENTITIES" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar"), 
+    "This is inside the tag and has < & @ > in it",
+    "http://www.w3c.org/myNs#",
+    XML_UTIL_REPLACE_ENTITIES
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute, content, namespace, and CDATA_SECTION" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar"), 
+    "This is inside the tag and has < & @ > in it",
+    "http://www.w3c.org/myNs#",
+    XML_UTIL_CDATA_SECTION
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, and multiline = false" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar"), 
+    "This is inside the tag and has < & @ > in it",
+    "http://www.w3c.org/myNs#",
+    XML_UTIL_REPLACE_ENTITIES,
+    false
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, and multiline = true" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar"), 
+    "This is inside the tag and has < & @ > in it",
+    "http://www.w3c.org/myNs#",
+    XML_UTIL_REPLACE_ENTITIES,
+    true
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, multiline = true, and indent = (2 spaces)" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar"), 
+    "This is inside the tag and has < & @ > in it",
+    "http://www.w3c.org/myNs#",
+    XML_UTIL_REPLACE_ENTITIES,
+    true,
+    '  '
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, multiline = true, indent = (2 spaces), and linebreak = '^'" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar"), 
+    "This is inside the tag and has < & @ > in it",
+    "http://www.w3c.org/myNs#",
+    XML_UTIL_REPLACE_ENTITIES,
+    true,
+    '  ',
+    '^'
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, multiline = true, indent = (2 spaces), linebreak = '^', and sortAttributes = true" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar", "boo" => "baz"), 
+    "This is inside the tag and has < & @ > in it",
+    "http://www.w3c.org/myNs#",
+    XML_UTIL_REPLACE_ENTITIES,
+    true,
+    '  ',
+    '^',
+    true
+) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, multiline = true, indent = (2 spaces), linebreak = '^', and sortAttributes = false" . PHP_EOL;
+echo XML_Util::createTag(
+    "myNs:myTag", 
+    array("foo" => "bar", "boo" => "baz"), 
+    "This is inside the tag and has < & @ > in it",
+    "http://www.w3c.org/myNs#",
+    XML_UTIL_REPLACE_ENTITIES,
+    true,
+    '  ',
+    '^',
+    false
+) . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::createTag() basic tests=====
+
+TEST:  tag with attribute
+<myNs:myTag foo="bar" />
+
+TEST:  tag with attribute and content
+<myNs:myTag foo="bar">This is inside the tag</myNs:myTag>
+
+TEST:  tag with attribute, content, and namespace
+<myNs:myTag foo="bar" xmlns:myNs="http://www.w3c.org/myNs#">This is inside the tag</myNs:myTag>
+
+TEST:  tag with attribute, content, namespace, and REPLACE_ENTITIES
+<myNs:myTag foo="bar" xmlns:myNs="http://www.w3c.org/myNs#">This is inside the tag and has &lt; &amp; @ &gt; in it</myNs:myTag>
+
+TEST:  tag with attribute, content, namespace, and CDATA_SECTION
+<myNs:myTag foo="bar" xmlns:myNs="http://www.w3c.org/myNs#"><![CDATA[This is inside the tag and has < & @ > in it]]></myNs:myTag>
+
+TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, and multiline = false
+<myNs:myTag foo="bar" xmlns:myNs="http://www.w3c.org/myNs#">This is inside the tag and has &lt; &amp; @ &gt; in it</myNs:myTag>
+
+TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, and multiline = true
+<myNs:myTag foo="bar"
+            xmlns:myNs="http://www.w3c.org/myNs#">This is inside the tag and has &lt; &amp; @ &gt; in it</myNs:myTag>
+
+TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, multiline = true, and indent = (2 spaces)
+<myNs:myTag foo="bar"
+  xmlns:myNs="http://www.w3c.org/myNs#">This is inside the tag and has &lt; &amp; @ &gt; in it</myNs:myTag>
+
+TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, multiline = true, indent = (2 spaces), and linebreak = '^'
+<myNs:myTag foo="bar"^  xmlns:myNs="http://www.w3c.org/myNs#">This is inside the tag and has &lt; &amp; @ &gt; in it</myNs:myTag>
+
+TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, multiline = true, indent = (2 spaces), linebreak = '^', and sortAttributes = true
+<myNs:myTag boo="baz"^  foo="bar"^  xmlns:myNs="http://www.w3c.org/myNs#">This is inside the tag and has &lt; &amp; @ &gt; in it</myNs:myTag>
+
+TEST:  tag with attribute, content, namespace, REPLACE_ENTITIES, multiline = true, indent = (2 spaces), linebreak = '^', and sortAttributes = false
+<myNs:myTag foo="bar"^  boo="baz"^  xmlns:myNs="http://www.w3c.org/myNs#">This is inside the tag and has &lt; &amp; @ &gt; in it</myNs:myTag>
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_createTagFromArray.phpt b/lib/tests/XML_Util/XML/tests/testBasic_createTagFromArray.phpt
new file mode 100644
index 00000000..9b8887a1
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_createTagFromArray.phpt
@@ -0,0 +1,203 @@
+--TEST--
+XML_Util::createTagFromArray() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::createTagFromArray() basic tests=====' . PHP_EOL . PHP_EOL;
+
+$bad = array(
+    "foo" => "bar",
+);
+$tag1 = array(
+    "qname"        => "foo:bar",
+);
+$tag2 = array(
+    "qname"        => "foo:bar",
+    "namespaceUri" => "http://foo.com",
+);
+$tag3 = array(
+    "qname"        => "foo:bar",
+    "namespaceUri" => "http://foo.com",
+    "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
+);
+$tag4 = array(
+    "qname"        => "foo:bar",
+    "namespaceUri" => "http://foo.com",
+    "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
+    "content"      => "I'm inside the tag",
+);
+$tag5 = array(
+    "qname"        => "foo:bar",
+    "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
+    "content"      => "I'm inside the tag",
+);
+$tag6 = array(
+    "qname"        => "foo:bar",
+    "namespaceUri" => "http://foo.com",
+    "content"      => "I'm inside the tag",
+);
+$tag7 = array(
+    "namespaceUri" => "http://foo.com",
+    "attributes"   => array( "key" => "value", "argh" => "fruit&vegetable" ),
+    "content"      => "I'm inside the tag",
+);
+
+$tag8 = array(
+    'content'      => array('foo', 'bar')
+);
+
+$tag9 = array(
+    'qname'        => 'foo:bar',
+    'namespaces'   => array('ns1' => 'uri1', 'ns2' => 'uri2')
+);
+
+$tag10 = array(
+    'namespace'    => 'http://foo.org',
+    'localPart'    => 'bar'
+);
+
+$tag11 = array(
+    'namespace'    => '',
+    'localPart'    => 'bar'
+);
+
+$tag12 = array(
+    'localPart'    => 'foo',
+    'namespaceUri' => 'http://bar.org'
+);
+
+echo "TEST:  basic usage with an invalid array" . PHP_EOL;
+echo XML_Util::createTagFromArray($bad) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname only)" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag1) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname and namespaceUri)" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag2) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, and attributes)" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag3) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content)" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag4) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, attributes, and content)" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag5) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, and content)" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag6) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (namespaceUri, attributes, and content)" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag7) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), plus REPLACE_ENTITIES" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag4, XML_UTIL_REPLACE_ENTITIES) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), plus ENTITIES_NONE" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag4, XML_UTIL_ENTITIES_NONE) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, and multiline = false" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag4, XML_UTIL_REPLACE_ENTITIES, false) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, and multiline = true" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag4, XML_UTIL_REPLACE_ENTITIES, true) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, multiline = true, and indent = (2 spaces)" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag4, XML_UTIL_REPLACE_ENTITIES, true, '  ') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, multiline = true, indent = (2 spaces), and linebreak = '^'" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag4, XML_UTIL_REPLACE_ENTITIES, true, '  ', '^') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, multiline = true, indent = (2 spaces), linebreak = '^', and sortAttributes = true" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag4, XML_UTIL_REPLACE_ENTITIES, true, '  ', '^', true) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, multiline = true, indent = (2 spaces), linebreak = '^', and sortAttributes = false" . PHP_EOL;
+echo XML_Util::createTagFromArray($tag4, XML_UTIL_REPLACE_ENTITIES, true, '  ', '^', false) . PHP_EOL . PHP_EOL;
+
+echo 'TEST:  cause a non-scalar error on the content tag' . PHP_EOL;
+echo XML_Util::createTagFromArray($tag8) . PHP_EOL . PHP_EOL;
+
+echo 'TEST:  handle an array of namespaces being passed' . PHP_EOL;
+echo XML_Util::createTagFromArray($tag9) . PHP_EOL . PHP_EOL;
+
+echo 'TEST:  qname is derived from namespace + localPart' . PHP_EOL;
+echo XML_Util::createTagFromArray($tag10) . PHP_EOL . PHP_EOL;
+
+echo 'TEST:  qname is derived from localPart only' . PHP_EOL;
+echo XML_Util::createTagFromArray($tag11) . PHP_EOL . PHP_EOL;
+
+echo 'TEST:  namespaceUri is given, but namespace is not' . PHP_EOL;
+echo XML_Util::createTagFromArray($tag12) . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::createTagFromArray() basic tests=====
+
+TEST:  basic usage with an invalid array
+You must either supply a qualified name (qname) or local tag name (localPart).
+
+TEST:  basic usage with a valid array (qname only)
+<foo:bar />
+
+TEST:  basic usage with a valid array (qname and namespaceUri)
+<foo:bar xmlns:foo="http://foo.com" />
+
+TEST:  basic usage with a valid array (qname, namespaceUri, and attributes)
+<foo:bar argh="fruit&amp;vegetable" key="value" xmlns:foo="http://foo.com" />
+
+TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content)
+<foo:bar argh="fruit&amp;vegetable" key="value" xmlns:foo="http://foo.com">I&apos;m inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (qname, attributes, and content)
+<foo:bar argh="fruit&amp;vegetable" key="value">I&apos;m inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (qname, namespaceUri, and content)
+<foo:bar xmlns:foo="http://foo.com">I&apos;m inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (namespaceUri, attributes, and content)
+You must either supply a qualified name (qname) or local tag name (localPart).
+
+TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), plus REPLACE_ENTITIES
+<foo:bar argh="fruit&amp;vegetable" key="value" xmlns:foo="http://foo.com">I&apos;m inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), plus ENTITIES_NONE
+<foo:bar argh="fruit&vegetable" key="value" xmlns:foo="http://foo.com">I'm inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, and multiline = false
+<foo:bar argh="fruit&amp;vegetable" key="value" xmlns:foo="http://foo.com">I&apos;m inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, and multiline = true
+<foo:bar argh="fruit&amp;vegetable"
+         key="value"
+         xmlns:foo="http://foo.com">I&apos;m inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, multiline = true, and indent = (2 spaces)
+<foo:bar argh="fruit&amp;vegetable"
+  key="value"
+  xmlns:foo="http://foo.com">I&apos;m inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, multiline = true, indent = (2 spaces), and linebreak = '^'
+<foo:bar argh="fruit&amp;vegetable"^  key="value"^  xmlns:foo="http://foo.com">I&apos;m inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, multiline = true, indent = (2 spaces), linebreak = '^', and sortAttributes = true
+<foo:bar argh="fruit&amp;vegetable"^  key="value"^  xmlns:foo="http://foo.com">I&apos;m inside the tag</foo:bar>
+
+TEST:  basic usage with a valid array (qname, namespaceUri, attributes, and content), REPLACE_ENTITIES, multiline = true, indent = (2 spaces), linebreak = '^', and sortAttributes = false
+<foo:bar key="value"^  argh="fruit&amp;vegetable"^  xmlns:foo="http://foo.com">I&apos;m inside the tag</foo:bar>
+
+TEST:  cause a non-scalar error on the content tag
+Supplied non-scalar value as tag content
+
+TEST:  handle an array of namespaces being passed
+<foo:bar xmlns:ns1="uri1" xmlns:ns2="uri2" />
+
+TEST:  qname is derived from namespace + localPart
+<http://foo.org:bar />
+
+TEST:  qname is derived from localPart only
+<bar />
+
+TEST:  namespaceUri is given, but namespace is not
+<foo xmlns="http://bar.org" />
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_getDocTypeDeclaration.phpt b/lib/tests/XML_Util/XML/tests/testBasic_getDocTypeDeclaration.phpt
new file mode 100644
index 00000000..f623dc97
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_getDocTypeDeclaration.phpt
@@ -0,0 +1,44 @@
+--TEST--
+XML_Util::getDocTypeDeclaration() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::getDocTypeDeclaration() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  using root only" . PHP_EOL;
+echo XML_Util::getDocTypeDeclaration("rootTag") . PHP_EOL . PHP_EOL;
+
+echo "TEST:  using root and a string URI" . PHP_EOL;
+echo XML_Util::getDocTypeDeclaration("rootTag", "myDocType.dtd") . PHP_EOL . PHP_EOL;
+
+$uri = array(
+    'uri' => 'http://pear.php.net/dtd/package-1.0',
+    'id' => '-//PHP//PEAR/DTD PACKAGE 0.1'
+);
+$dtdEntry = '<!ELEMENT additionalInfo (#PCDATA)>';
+
+echo "TEST:  using root and an array URI" . PHP_EOL;
+echo XML_Util::getDocTypeDeclaration("rootTag", $uri) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  using root and an array URI and an internal DTD entry" . PHP_EOL;
+echo XML_Util::getDocTypeDeclaration("rootTag", $uri, $dtdEntry) . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::getDocTypeDeclaration() basic tests=====
+
+TEST:  using root only
+<!DOCTYPE rootTag>
+
+TEST:  using root and a string URI
+<!DOCTYPE rootTag SYSTEM "myDocType.dtd">
+
+TEST:  using root and an array URI
+<!DOCTYPE rootTag PUBLIC "-//PHP//PEAR/DTD PACKAGE 0.1" "http://pear.php.net/dtd/package-1.0">
+
+TEST:  using root and an array URI and an internal DTD entry
+<!DOCTYPE rootTag PUBLIC "-//PHP//PEAR/DTD PACKAGE 0.1" "http://pear.php.net/dtd/package-1.0" [
+<!ELEMENT additionalInfo (#PCDATA)>
+]>
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_getXmlDeclaration.phpt b/lib/tests/XML_Util/XML/tests/testBasic_getXmlDeclaration.phpt
new file mode 100644
index 00000000..93e3842b
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_getXmlDeclaration.phpt
@@ -0,0 +1,36 @@
+--TEST--
+XML_Util::getXmlDeclaration() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::getXmlDeclaration() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  using version only" . PHP_EOL;
+echo XML_Util::getXMLDeclaration("1.0") . PHP_EOL . PHP_EOL;
+
+echo "TEST:  using version and encoding" . PHP_EOL;
+echo XML_Util::getXMLDeclaration("1.0", "UTF-8") . PHP_EOL . PHP_EOL;
+
+echo "TEST:  using version, encoding, and standalone flag" . PHP_EOL;
+echo XML_Util::getXMLDeclaration("1.0", "UTF-8", true) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  using version and standalone flag" . PHP_EOL;
+echo XML_Util::getXMLDeclaration("1.0", null, true) . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::getXmlDeclaration() basic tests=====
+
+TEST:  using version only
+<?xml version="1.0"?>
+
+TEST:  using version and encoding
+<?xml version="1.0" encoding="UTF-8"?>
+
+TEST:  using version, encoding, and standalone flag
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+TEST:  using version and standalone flag
+<?xml version="1.0" standalone="yes"?>
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_isValidName.phpt b/lib/tests/XML_Util/XML/tests/testBasic_isValidName.phpt
new file mode 100644
index 00000000..2abd2e74
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_isValidName.phpt
@@ -0,0 +1,46 @@
+--TEST--
+XML_Util::isValidName() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::isValidName() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  valid tag" . PHP_EOL;
+$result = XML_Util::isValidName("alpha-x_y_z.123");
+if (is_a($result, 'PEAR_Error')) {
+    print "Invalid XML name: " . $result->getMessage() . PHP_EOL . PHP_EOL;
+} else {
+    print "Valid XML name." . PHP_EOL . PHP_EOL;
+}
+
+echo "TEST:  invalid tag" . PHP_EOL;
+$result = XML_Util::isValidName("invalidTag?");
+if (is_a($result, 'PEAR_Error')) {
+    print "Invalid XML name: " . $result->getMessage() . PHP_EOL . PHP_EOL;
+} else {
+    print "Valid XML name." . PHP_EOL . PHP_EOL;
+}
+
+echo "TEST:  invalid tag that doesn't start with a letter" . PHP_EOL;
+$result = XML_Util::isValidName("1234five");
+if (is_a($result, 'PEAR_Error')) {
+    print "Invalid XML name: " . $result->getMessage() . PHP_EOL . PHP_EOL;
+} else {
+    print "Valid XML name." . PHP_EOL . PHP_EOL;
+}
+
+?>
+--EXPECT--
+=====XML_Util::isValidName() basic tests=====
+
+TEST:  valid tag
+Valid XML name.
+
+TEST:  invalid tag
+Invalid XML name: XML names may only contain alphanumeric chars, period, hyphen, colon and underscores
+
+TEST:  invalid tag that doesn't start with a letter
+Invalid XML name: XML names may only start with letter or underscore
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_raiseError.phpt b/lib/tests/XML_Util/XML/tests/testBasic_raiseError.phpt
new file mode 100644
index 00000000..84f6b186
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_raiseError.phpt
@@ -0,0 +1,19 @@
+--TEST--
+XML_Util::raiseError() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::raiseError() basic tests=====' . PHP_EOL . PHP_EOL;
+
+$error = XML_Util::raiseError("I am an error", 12345);
+if (is_a($error, 'PEAR_Error')) {
+    print "PEAR Error: " . $error->getMessage() . PHP_EOL;
+}
+?>
+--EXPECT--
+=====XML_Util::raiseError() basic tests=====
+
+PEAR Error: I am an error
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_replaceEntities.phpt b/lib/tests/XML_Util/XML/tests/testBasic_replaceEntities.phpt
new file mode 100644
index 00000000..17fc2854
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_replaceEntities.phpt
@@ -0,0 +1,82 @@
+--TEST--
+XML_Util::replaceEntities() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::replaceEntities() basic tests=====' . PHP_EOL . PHP_EOL;
+
+$data = 'This string contains < & >.';
+$utf8 = 'This data contains special chars like <, >, & and " as well as ä, ö, ß, à and ê';
+
+echo "TEST:  basic usage" . PHP_EOL;
+echo XML_Util::replaceEntities($data) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage but with bogus \$replaceEntities arg" . PHP_EOL;
+echo XML_Util::replaceEntities($data, 'I_AM_BOGUS') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_XML" . PHP_EOL;
+echo XML_Util::replaceEntities($data, XML_UTIL_ENTITIES_XML) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_XML and UTF-8" . PHP_EOL;
+echo XML_Util::replaceEntities($data, XML_UTIL_ENTITIES_XML, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  utf8 usage with ENTITIES_XML and UTF-8" . PHP_EOL;
+echo XML_Util::replaceEntities($utf8, XML_UTIL_ENTITIES_XML, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_XML_REQUIRED" . PHP_EOL;
+echo XML_Util::replaceEntities($data, XML_UTIL_ENTITIES_XML_REQUIRED) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_XML_REQUIRED and UTF-8" . PHP_EOL;
+echo XML_Util::replaceEntities($data, XML_UTIL_ENTITIES_XML_REQUIRED, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  utf8 usage with ENTITIES_XML_REQUIRED and UTF-8" . PHP_EOL;
+echo XML_Util::replaceEntities($utf8, XML_UTIL_ENTITIES_XML_REQUIRED, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_HTML" . PHP_EOL;
+echo XML_Util::replaceEntities($data, XML_UTIL_ENTITIES_HTML) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_HTML and UTF-8" . PHP_EOL;
+echo XML_Util::replaceEntities($data, XML_UTIL_ENTITIES_HTML, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  utf8 usage with ENTITIES_HTML and UTF-8" . PHP_EOL;
+echo XML_Util::replaceEntities($utf8, XML_UTIL_ENTITIES_HTML, 'UTF-8') . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::replaceEntities() basic tests=====
+
+TEST:  basic usage
+This string contains &lt; &amp; &gt;.
+
+TEST:  basic usage but with bogus $replaceEntities arg
+This string contains < & >.
+
+TEST:  basic usage with ENTITIES_XML
+This string contains &lt; &amp; &gt;.
+
+TEST:  basic usage with ENTITIES_XML and UTF-8
+This string contains &lt; &amp; &gt;.
+
+TEST:  utf8 usage with ENTITIES_XML and UTF-8
+This data contains special chars like &lt;, &gt;, &amp; and &quot; as well as ä, ö, ß, à and ê
+
+TEST:  basic usage with ENTITIES_XML_REQUIRED
+This string contains &lt; &amp; >.
+
+TEST:  basic usage with ENTITIES_XML_REQUIRED and UTF-8
+This string contains &lt; &amp; >.
+
+TEST:  utf8 usage with ENTITIES_XML_REQUIRED and UTF-8
+This data contains special chars like &lt;, >, &amp; and &quot; as well as ä, ö, ß, à and ê
+
+TEST:  basic usage with ENTITIES_HTML
+This string contains &lt; &amp; &gt;.
+
+TEST:  basic usage with ENTITIES_HTML and UTF-8
+This string contains &lt; &amp; &gt;.
+
+TEST:  utf8 usage with ENTITIES_HTML and UTF-8
+This data contains special chars like &lt;, &gt;, &amp; and &quot; as well as &auml;, &ouml;, &szlig;, &agrave; and &ecirc;
+
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_reverseEntities.phpt b/lib/tests/XML_Util/XML/tests/testBasic_reverseEntities.phpt
new file mode 100644
index 00000000..16717167
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_reverseEntities.phpt
@@ -0,0 +1,81 @@
+--TEST--
+XML_Util::reverseEntities() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::reverseEntities() basic tests=====' . PHP_EOL . PHP_EOL;
+
+$data = 'This string contains &lt; &amp; &gt;.';
+$utf8 = 'This data contains special chars like &lt;, &gt;, &amp; and &quot; as well as &auml;, &ouml;, &szlig;, &agrave; and &ecirc;';
+
+echo "TEST:  basic usage" . PHP_EOL;
+echo XML_Util::reverseEntities($data) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage but with bogus \$replaceEntities arg" . PHP_EOL;
+echo XML_Util::reverseEntities($data, 'I_AM_BOGUS') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_XML" . PHP_EOL;
+echo XML_Util::reverseEntities($data, XML_UTIL_ENTITIES_XML) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_XML and UTF-8" . PHP_EOL;
+echo XML_Util::reverseEntities($data, XML_UTIL_ENTITIES_XML, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  utf8 usage with ENTITIES_XML and UTF-8" . PHP_EOL;
+echo XML_Util::reverseEntities($utf8, XML_UTIL_ENTITIES_XML, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_XML_REQUIRED" . PHP_EOL;
+echo XML_Util::reverseEntities($data, XML_UTIL_ENTITIES_XML_REQUIRED) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_XML_REQUIRED and UTF-8" . PHP_EOL;
+echo XML_Util::reverseEntities($data, XML_UTIL_ENTITIES_XML_REQUIRED, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  utf8 usage with ENTITIES_XML_REQUIRED and UTF-8" . PHP_EOL;
+echo XML_Util::reverseEntities($utf8, XML_UTIL_ENTITIES_XML_REQUIRED, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_HTML" . PHP_EOL;
+echo XML_Util::reverseEntities($data, XML_UTIL_ENTITIES_HTML) . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage with ENTITIES_HTML and UTF-8" . PHP_EOL;
+echo XML_Util::reverseEntities($data, XML_UTIL_ENTITIES_HTML, 'UTF-8') . PHP_EOL . PHP_EOL;
+
+echo "TEST:  utf8 usage with ENTITIES_HTML and UTF-8" . PHP_EOL;
+echo XML_Util::reverseEntities($utf8, XML_UTIL_ENTITIES_HTML, 'UTF-8') . PHP_EOL . PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::reverseEntities() basic tests=====
+
+TEST:  basic usage
+This string contains < & >.
+
+TEST:  basic usage but with bogus $replaceEntities arg
+This string contains &lt; &amp; &gt;.
+
+TEST:  basic usage with ENTITIES_XML
+This string contains < & >.
+
+TEST:  basic usage with ENTITIES_XML and UTF-8
+This string contains < & >.
+
+TEST:  utf8 usage with ENTITIES_XML and UTF-8
+This data contains special chars like <, >, & and " as well as &auml;, &ouml;, &szlig;, &agrave; and &ecirc;
+
+TEST:  basic usage with ENTITIES_XML_REQUIRED
+This string contains < & &gt;.
+
+TEST:  basic usage with ENTITIES_XML_REQUIRED and UTF-8
+This string contains < & &gt;.
+
+TEST:  utf8 usage with ENTITIES_XML_REQUIRED and UTF-8
+This data contains special chars like <, &gt;, & and " as well as &auml;, &ouml;, &szlig;, &agrave; and &ecirc;
+
+TEST:  basic usage with ENTITIES_HTML
+This string contains < & >.
+
+TEST:  basic usage with ENTITIES_HTML and UTF-8
+This string contains < & >.
+
+TEST:  utf8 usage with ENTITIES_HTML and UTF-8
+This data contains special chars like <, >, & and " as well as ä, ö, ß, à and ê
diff --git a/lib/tests/XML_Util/XML/tests/testBasic_splitQualifiedName.phpt b/lib/tests/XML_Util/XML/tests/testBasic_splitQualifiedName.phpt
new file mode 100644
index 00000000..0008f726
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBasic_splitQualifiedName.phpt
@@ -0,0 +1,32 @@
+--TEST--
+XML_Util::splitQualifiedName() basic tests
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util::splitQualifiedName() basic tests=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  basic usage without namespace" . PHP_EOL;
+$return = XML_Util::splitQualifiedName("xslt:stylesheet");
+echo "namespace => " . $return['namespace'] . PHP_EOL;
+echo "localPart => " . $return['localPart'] . PHP_EOL;
+echo PHP_EOL;
+
+echo "TEST:  basic usage with namespace" . PHP_EOL;
+$return = XML_Util::splitQualifiedName("stylesheet", "myNs");
+echo "namespace => " . $return['namespace'] . PHP_EOL;
+echo "localPart => " . $return['localPart'] . PHP_EOL;
+echo PHP_EOL;
+?>
+--EXPECT--
+=====XML_Util::splitQualifiedName() basic tests=====
+
+TEST:  basic usage without namespace
+namespace => xslt
+localPart => stylesheet
+
+TEST:  basic usage with namespace
+namespace => myNs
+localPart => stylesheet
diff --git a/lib/tests/XML_Util/XML/tests/testBug_4950.phpt b/lib/tests/XML_Util/XML/tests/testBug_4950.phpt
new file mode 100644
index 00000000..049e51ab
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBug_4950.phpt
@@ -0,0 +1,21 @@
+--TEST--
+XML_Util tests for Bug #4950 "Incorrect CDATA serializing"
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util tests for Bug #4950 "Incorrect CDATA serializing"=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  test case provided in bug report" . PHP_EOL;
+echo XML_Util::createTag("test", array(), "Content ]]></test> here!",
+    null, XML_UTIL_CDATA_SECTION) . PHP_EOL;
+
+?>
+--EXPECT--
+=====XML_Util tests for Bug #4950 "Incorrect CDATA serializing"=====
+
+TEST:  test case provided in bug report
+<test><![CDATA[Content ]]]]><![CDATA[></test> here!]]></test>
+
diff --git a/lib/tests/XML_Util/XML/tests/testBug_5392.phpt b/lib/tests/XML_Util/XML/tests/testBug_5392.phpt
new file mode 100644
index 00000000..47b2270f
--- /dev/null
+++ b/lib/tests/XML_Util/XML/tests/testBug_5392.phpt
@@ -0,0 +1,27 @@
+--TEST--
+XML_Util tests for Bug #5392 "encoding of ISO-8859-1 is the only supported encoding"
+--CREDITS--
+Chuck Burgess <ashnazg@php.net>
+# created for v1.2.0a1 2008-05-04
+--FILE--
+<?php
+require_once 'XML' . DIRECTORY_SEPARATOR . 'Util.php';
+echo '=====XML_Util tests for Bug #5392 "encoding of ISO-8859-1 is the only supported encoding"=====' . PHP_EOL . PHP_EOL;
+
+echo "TEST:  test case provided in bug report" . PHP_EOL;
+$data = 'This data contains special chars like <, >, & and " as well as ä, ö, ß, à and ê';
+
+$replaced = XML_Util::replaceEntities($data, XML_UTIL_ENTITIES_HTML, 'UTF-8');
+
+$reversed = XML_Util::reverseEntities($replaced, XML_UTIL_ENTITIES_HTML, 'UTF-8');
+
+echo $replaced . PHP_EOL;
+echo $reversed . PHP_EOL;
+
+?>
+--EXPECT--
+=====XML_Util tests for Bug #5392 "encoding of ISO-8859-1 is the only supported encoding"=====
+
+TEST:  test case provided in bug report
+This data contains special chars like &lt;, &gt;, &amp; and &quot; as well as &auml;, &ouml;, &szlig;, &agrave; and &ecirc;
+This data contains special chars like <, >, & and " as well as ä, ö, ß, à and ê
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/README b/lib/www/UNL_Peoplefinder/pear.unl.edu/README
new file mode 100644
index 00000000..93776137
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/README
@@ -0,0 +1,19 @@
+This code runs the website at http://peoplefinder.unl.edu/
+
+REQUIREMENTS:
+PHP 5
+To query the LDAP, you'll need connection credentials - contact John Thiltges.
+Otherwise, use the UNL_Peoplefinder_Driver_WebService
+
+SETUP:
+To use, copy the config-sample.inc.php to config.inc.php and provide your LDAP
+username and password. Then browse to http://localhost/peoplefinder/ and try it out.
+
+TODO:
+Move LDAP connection into a singleton class UNL_LDAP
+Change renderers to work like Savant/Zend_View
+Change UNL_Peoplefinder_Record to use overloading with __get/__set for all attributes
+
+LICENSE
+This code is covered by a BSD style license.
+http://www1.unl.edu/wdn/wiki/Software_License
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/advancedForm.php b/lib/www/UNL_Peoplefinder/pear.unl.edu/advancedForm.php
new file mode 100644
index 00000000..c599c875
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/advancedForm.php
@@ -0,0 +1,19 @@
+<form method="get" id="form1" action="<?php echo htmlentities(str_replace('index.php', '', $_SERVER['PHP_SELF']), ENT_QUOTES); ?>">
+	<label for="sn">Last Name: </label>
+	<input type="text" name="sn" value="<?php echo htmlentities(@$_GET['sn'], ENT_QUOTES); ?>" id="sn" />
+	<br />
+	<label for="cn">First Name: </label>
+	<input type="text" name="cn" value="<?php echo htmlentities(@$_GET['cn'], ENT_QUOTES); ?>" id="cn" />
+	<?php if (isset($_GET['chooser'])) {
+		echo '<input type="hidden" name="chooser" value="true" />';
+	} ?>
+	<input type="hidden" name="adv" value="y" />
+	<br />
+	<label for="eppa">Affiliation: </label>
+	<select id="eppa" name="eppa">
+		<option value="any" <?php if(@$_GET['eppa'] == 'any') echo "selected='selected'"; ?>>Any</option>
+		<option value="fs" <?php if(@$_GET['eppa'] == 'fs') echo "selected='selected'"; ?>>Faculty/Staff</option>
+		<option value="stu" <?php if(@$_GET['eppa'] == 'stu') echo "selected='selected'"; ?>>Student</option>
+	</select>
+	<input style="margin-bottom:-7px;" name="submitbutton" type="image" src="/ucomm/templatedependents/templatecss/images/go.gif" value="Submit" id="submitbutton" />
+</form>
\ No newline at end of file
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/apple-touch-icon.png b/lib/www/UNL_Peoplefinder/pear.unl.edu/apple-touch-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..cadb4bfe1504a7ca9ec26f94b8b49cce09fb991e
GIT binary patch
literal 5367
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
JmO+dH{}1@XgRB4m

literal 0
HcmV?d00001

diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/config-sample.inc.php b/lib/www/UNL_Peoplefinder/pear.unl.edu/config-sample.inc.php
new file mode 100644
index 00000000..860e8f7c
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/config-sample.inc.php
@@ -0,0 +1,18 @@
+<?php
+ini_set('display_errors', true);
+error_reporting(E_ALL|E_STRICT);
+set_include_path(dirname(__FILE__).'/../src/'.PATH_SEPARATOR.get_include_path());
+require_once 'UNL/Autoload.php';
+
+define('DOCUMENT_ROOT', $_SERVER['DOCUMENT_ROOT']);
+
+UNL_Peoplefinder_Driver_LDAP::$bindDN = 'uid=giggidy,ou=service,dc=unl,dc=edu';
+UNL_Peoplefinder_Driver_LDAP::$bindPW = 'flibbertygibberty';
+
+define('UNL_PEOPLEFINDER_URI', 'http://peoplefinder.unl.edu/');
+set_time_limit(5);
+// If you have LDAP access credentials, best to use this driver
+$driver = new UNL_Peoplefinder_Driver_LDAP();
+
+// Otherwise, use the webservice driver
+$driver = new UNL_Peoplefinder_Driver_WebService();
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/config.inc.php b/lib/www/UNL_Peoplefinder/pear.unl.edu/config.inc.php
new file mode 100644
index 00000000..0d46c1a9
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/config.inc.php
@@ -0,0 +1,15 @@
+<?php
+ini_set('display_errors', true);
+error_reporting(E_ALL);
+set_include_path(dirname(__FILE__).'/../src/'.PATH_SEPARATOR.get_include_path());
+require_once 'UNL/Autoload.php';
+
+define('DOCUMENT_ROOT', $_SERVER['DOCUMENT_ROOT']);
+
+UNL_Peoplefinder_Driver_LDAP::$bindDN = 'uid=unlwebsearch,ou=service,dc=unl,dc=edu';
+UNL_Peoplefinder_Driver_LDAP::$bindPW = 'gagfawki';
+
+define('UNL_PEOPLEFINDER_URI', 'http://ucommbieber.unl.edu/workspace/peoplefinder/www/');
+set_time_limit(5);
+//$driver = new UNL_Peoplefinder_Driver_WebService();
+$driver = new UNL_Peoplefinder_Driver_LDAP();
\ No newline at end of file
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/departments/index.php b/lib/www/UNL_Peoplefinder/pear.unl.edu/departments/index.php
new file mode 100644
index 00000000..9370b293
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/departments/index.php
@@ -0,0 +1,89 @@
+<?php
+require_once '../config.inc.php';
+
+UNL_Templates::$options['version'] = 3;
+$page = UNL_Templates::factory('Document');
+$page->doctitle = '<title>UNL | Officefinder</title>';
+$page->titlegraphic = '<h1>Officefinder</h1>';
+$page->addStylesheet('../peoplefinder_default.css');
+$page->head .= <<<META
+<meta name="description" content="UNL Officefinder is the searchable department directory for the University. Information obtained from this directory may not be used to provide addresses for mailings to students, faculty or staff. Any solicitation of business, information, contributions or other response from individuals listed in this publication by mail, telephone or other means is forbidden." />
+<meta name="keywords" content="university of nebraska-lincoln student faculty staff directory vcard" />
+<meta name="author" content="Brett Bieber, UNL Office of University Communications" />
+<meta name="viewport" content="width = 320" />
+<link media="only screen and (max-device-width: 480px)" href="../small_devices.css" type="text/css" rel="stylesheet" />
+META;
+
+if(isset($_GET['q'])) {
+    $page->head .= '<meta name="robots" content="NOINDEX, NOFOLLOW" />';
+}
+
+$q = '';
+if (!empty($_GET['q'])) {
+    $q = $_GET['q'];
+    $departments = new UNL_Peoplefinder_Department_Search($q);
+}
+if (!empty($_GET['d'])) {
+    $q = $_GET['d'];
+    $department = new UNL_Peoplefinder_Department($q);
+    $q = htmlentities($q, ENT_QUOTES);
+}
+$page->maincontentarea = <<<FORM
+<p>Search for UNL departments:</p>
+<form method="get" action="?">
+    <div>
+    <label for="q">Search:&nbsp;</label> 
+    <input style="width:18em;" type="text" value="$q" id="q" name="q" /> 
+    <input style="margin-bottom:-7px;" name="submitbutton" type="image" src="/ucomm/templatedependents/templatecss/images/go.gif" value="Submit" id="submitbutton" />
+    </div> 
+</form>
+
+FORM;
+
+if (isset($department)) {
+    if (count($department)) {
+        $renderer_options = array('uri'=>UNL_PEOPLEFINDER_URI);
+        $renderer = new UNL_Peoplefinder_Renderer_HTML($renderer_options);
+        $page->maincontentarea .= count($department).' results.';
+        $page->maincontentarea .= '<h2>'.htmlentities($department->name).'</h2>';
+        if (isset($department->building)) {
+            $bldgs = new UNL_Common_Building();
+            if ($bldgs->buildingExists($department->building)) {
+                $sd = new UNL_Geography_SpatialData_Campus();
+                $department->building = '<a href="'.$sd->getMapUrl($department->building).'">'.htmlentities($bldgs->codes[$department->building]).'</a>';
+            }
+        }
+        $page->maincontentarea .= "<p>{$department->room} <span class='location'>{$department->building}</span><br />{$department->city}, {$department->state} {$department->postal_code}</p>";
+        if ($department->hasChildren()) {
+            $page->maincontentarea .= 'Sub-departments:<ul>';
+            foreach ($department->getChildren() as $child) {
+                $page->maincontentarea .= '<li><a href="'.UNL_PEOPLEFINDER_URI.'departments/?d='.urlencode($child).'">'.htmlentities($child).'</a></li>';
+            }
+            $page->maincontentarea .= '</ul>';
+        }
+        $page->maincontentarea .= '<ul class="department">';
+        ob_start();
+        foreach ($department as $employee) {
+            echo '<li class="ppl_Sresult">';
+            $renderer->renderListRecord($employee);
+            echo '</li>';
+        }
+        $page->maincontentarea .= ob_get_clean().'</ul>';
+    } else {
+        $page->maincontentarea .= 'No results could be found.';
+    }
+}
+if (isset($departments)) {
+    if (count($departments)) {
+        $page->maincontentarea .= '<h2>Search results for '.$q.'</h2><ul class="departments">';
+        foreach($departments as $department) {
+            $page->maincontentarea .= '<li class="ppl_Sresult"><a href="'.UNL_PEOPLEFINDER_URI.'departments/?d='.urlencode($department->name).'">'.$department->name.'</a></li>';
+        }
+        $page->maincontentarea .= '</ul>';
+    } else {
+        $page->maincontentarea .= 'No results could be found.';
+    }
+}
+
+echo $page;
+?>
\ No newline at end of file
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/images/btn_back.gif b/lib/www/UNL_Peoplefinder/pear.unl.edu/images/btn_back.gif
new file mode 100644
index 00000000..e69de29b
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/images/home.gif b/lib/www/UNL_Peoplefinder/pear.unl.edu/images/home.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f4b1ea7daba1696aef4a800b4583544c1bf8b211
GIT binary patch
literal 92
zcmZ?wbhEHb<YM4rSj50!Y;1h@?%m0gC;vb5KP@fo|Ns9CV4(Pug^`_snL!7{1F2<T
qR<y8k`K=<tzI4f%Y1RxG3J(pPGJ^tz*JK2&bNs!@OM;J+!5RQU;2cu`

literal 0
HcmV?d00001

diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/images/icon_question.gif b/lib/www/UNL_Peoplefinder/pear.unl.edu/images/icon_question.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f171dc0f81790fb0198da03a2e9208c14ebac2e4
GIT binary patch
literal 85
zcmZ?wbhEHb<Y(Yxn8?KN;lqcSGiUz)|DS<@LGdRGBLf2ygAS0*0Fq~5Qk&ASGC`a_
oIl*C7N5S0LhyUa*5Vu==b?(zu3x!VZTib2<>AKFYKn4bD0I;hcP5=M^

literal 0
HcmV?d00001

diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/images/mobile.gif b/lib/www/UNL_Peoplefinder/pear.unl.edu/images/mobile.gif
new file mode 100644
index 0000000000000000000000000000000000000000..10f8f325118241bc075a6ae9099f5b09872087ed
GIT binary patch
literal 90
zcmZ?wbhEHb<YM4rSj50!Y;64h%>VB0?z?yIrlqBA*|O#T|NjgO42nNl7}*&Z8FYYb
tph_+V24;DQU5-8mMut6-Nl~-Kx84wTyc{61P<>5y<uWdX^Il90)&OyJ9ccgn

literal 0
HcmV?d00001

diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/images/person.gif b/lib/www/UNL_Peoplefinder/pear.unl.edu/images/person.gif
new file mode 100644
index 0000000000000000000000000000000000000000..c3f9e1b040fcbac6ecd43068c503ae8e2576d1ab
GIT binary patch
literal 124
zcmZ?wbhEHb<YM4r*v!CSY;64h%>PT5E~TZV?cBNZ-Me@H|NnpW>eb!5cNwq&#h)yU
z><o+yIv`1q84N6%1}7Zb_c%)^>)73X=(|8M&aq5Jc9zf)3q=znKG$9mxwt>}{0Sa1
IY)TB)0D49x;s5{u

literal 0
HcmV?d00001

diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/index.php b/lib/www/UNL_Peoplefinder/pear.unl.edu/index.php
new file mode 100644
index 00000000..b4ab8b69
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/index.php
@@ -0,0 +1,141 @@
+<?php
+require_once 'config.inc.php';
+
+session_start();
+session_cache_expire(5);
+
+$renderer_options = array('uri'=>UNL_PEOPLEFINDER_URI);
+
+$peepObj  = new UNL_Peoplefinder($driver);
+$renderer = new UNL_Peoplefinder_Renderer_HTML($renderer_options);
+
+$myself = htmlentities(str_replace('index.php', '', $_SERVER['PHP_SELF']), ENT_QUOTES);
+UNL_Templates::$options['version'] = 3;
+$page = UNL_Templates::factory('Document');
+
+$page->doctitle = '<title>UNL | Peoplefinder</title>';
+
+$page->head .= '
+<meta name="description" content="UNL Peoplefinder is the Faculty, Staff and Student online directory for the University. Information obtained from this directory may not be used to provide addresses for mailings to students, faculty or staff. Any solicitation of business, information, contributions or other response from individuals listed in this publication by mail, telephone or other means is forbidden." />
+<meta name="keywords" content="university of nebraska-lincoln student faculty staff directory vcard" />
+<meta name="author" content="Brett Bieber, UNL Office of University Communications" />
+<meta name="viewport" content="width = 320" />
+<link rel="stylesheet" type="text/css" media="screen" href="peoplefinder_default.css" />
+<link media="only screen and (max-device-width: 480px)" href="small_devices.css" type="text/css" rel="stylesheet" />
+<script type="text/javascript" src="'.UNL_PEOPLEFINDER_URI.'peoplefinder.js"></script>
+';
+
+if (isset($_GET['q']) 
+    || isset($_GET['uid'])
+    || isset($_GET['cn'])
+    || isset($_GET['sn'])) {
+    $page->head .= '<meta name="robots" content="NOINDEX, NOFOLLOW" />';
+}
+
+$page->breadcrumbs = '
+<ul>
+    <li><a href="http://www.unl.edu/" title="University of Nebraska�Lincoln">UNL</a></li>
+    <li>Peoplefinder</li>
+</ul>';
+
+$page->titlegraphic = '<h1>UNL Peoplefinder</h1>';
+
+ob_start();
+
+if (isset($_GET['uid'])) {
+    try {
+        $renderer->renderRecord($peepObj->getUID($_GET['uid']));
+    } catch (Exception $e) {
+        header('HTTP/1.0 404 Not Found');
+        echo '<p><br />Sorry, no one with that name could be found!</p>';
+    }
+} else {
+    // Display form
+    (@$_GET['adv'] == 'y')?$renderer->displayAdvancedForm():$renderer->displayStandardForm();
+    if (isset($_GET['p'])) {
+        // Display the next page
+        if ($_SESSION['lastResultCount'] > 0) {
+            // Old results have been set.
+            $renderer->renderSearchResults($_SESSION['lastResult'], $_GET['p']*$_SESSION['lastResultDisplayed']);
+        } else {
+            echo 'Your session has expired, please search again.';
+        }
+    } else {
+        if (isset($_GET['q']) && !empty($_GET['q'])) {
+            // Basic query, build filter and display results
+            if (strlen($_GET['q']) > 3) {
+                if (is_numeric(str_replace(array('-', '(', ')'),
+                                           array('',  '',  ''),
+                                           $_GET['q']))) {
+                    $records = $peepObj->getPhoneMatches($_GET['q']);
+                    $renderer->renderSearchResults($records);
+                } else {
+                    $records = $peepObj->getExactMatches($_GET['q']);
+                    if (count($records)) {
+                        echo '<div class="cMatch">Exact matches:';
+                        if (count($records) >= UNL_Peoplefinder::$resultLimit) {
+                            echo "<p>Your search could only return a subset of the results. ";
+                            if (@$_GET['adv'] != 'y')    echo "Would you like to <a href='".$renderer->uri."?adv=y' title='Click here to perform a detailed Peoplefinder search'>try a Detailed Search?</a>\n";
+                            else                         echo 'Try refining your search.';
+                            echo '</p>';
+                        }
+                        echo '</div>';
+                        $renderer->renderSearchResults($records);
+                    } else {
+                        echo '<p>Sorry, I couldn\'t find anyone matching '.htmlentities($_GET['q']).'.</p>';
+                    }
+                    if (count($records) < UNL_Peoplefinder::$displayResultLimit) {
+                        // More room to display LIKE results
+                        UNL_Peoplefinder::$displayResultLimit = UNL_Peoplefinder::$displayResultLimit - count($records);
+                        $records = $peepObj->getLikeMatches($_GET['q'], $records);
+                        if (count($records) > 0) {
+                            echo '<div class="cMatch">Possible matches:';
+                            if (count($records) >= UNL_Peoplefinder::$resultLimit) {
+                                echo "<p>Your search could only return a subset of the results. ";
+                                if (@$_GET['adv'] != 'y')    echo "Would you like to <a href='".$renderer->uri."?adv=y' title='Click here to perform a detailed Peoplefinder search'>try a Detailed Search?</a>\n";
+                                else                         echo 'Try refining your search.';
+                                echo '</p>';
+                            }
+                            echo '</div>';
+                            $renderer->renderSearchResults($records);
+                        }
+                    }
+                }
+            } else {
+                echo "<p>Please enter more information or <a href='".$_SERVER['PHP_SELF']."?adv=y' title='Click here to perform a detailed Peoplefinder search'>try a Detailed Search.</a></p>";
+            }
+        } elseif (isset($_GET['sn']) || isset($_GET['cn'])) {
+            // Advanced search
+            $records = $peepObj->getAdvancedSearchMatches($_GET['sn'],$_GET['cn'],$_GET['eppa']);
+            $renderer->renderSearchResults($records);
+        }
+        if (isset($records)) {
+            // Prepare for sleep
+            $_SESSION['lastResult']          = $records;
+            $_SESSION['lastResultCount']     = count($records);
+            $_SESSION['lastResultDisplayed'] = UNL_Peoplefinder::$displayResultLimit;
+        }
+    }
+}
+
+//show instructions if no results are showing
+if (!isset($_GET['uid']) && !isset($records)) {
+    echo '<div class="two_col left" id="results">';
+    $renderer->displayInstructions((@$_GET['adv'] == 'y')?true:false);
+    echo '</div>
+        <div class="two_col right" id="pfShowRecord"></div>';
+}
+
+if (!isset($_GET['uid'])) { ?>
+     <div class="clear">
+        <a href="<?php echo $myself; ?>" title="Click here to run a basic Peoplefinder search">Basic</a>&nbsp;|&nbsp;<a href="<?php echo $myself; ?>?adv=y" title="Click here to perform a detailed Peoplefinder search">Detailed</a>
+    </div>
+<?php
+}
+
+$page->maincontentarea = ob_get_clean();
+
+$page->footercontent = 'UNL | Office of University Communications | <a href="http://www1.unl.edu/wdn/wiki/About_Peoplefinder" onclick="window.open(this.href); return false;">About Peoplefinder</a><br /><br />';
+$page->footercontent .= 'Information obtained from this directory may not be used to provide addresses for mailings to students, faculty or staff.<br />Any solicitation of business, information, contributions or other response from individuals listed in this publication by mail, telephone or other means is forbidden.<br />';
+
+echo $page;
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/peoplefinder.js b/lib/www/UNL_Peoplefinder/pear.unl.edu/peoplefinder.js
new file mode 100644
index 00000000..e3436f13
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/peoplefinder.js
@@ -0,0 +1,13 @@
+
+
+WDN.jQuery(document).ready(function() {
+	self.focus();
+	document.getElementById("form1").elements[0].focus();
+	WDN.loadJS('wdn/templates_3.0/scripts/toobar_peoplefinder.js');
+	WDN.jQuery('#form1').submit(function(eventObject) {
+		WDN.toolbar_peoplefinder.queuePFRequest(WDN.jQuery('#q').val(), 'results');
+		eventObject.preventDefault();
+		eventObject.stopPropagation();
+		return false;
+	});
+});
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/peoplefinder_default.css b/lib/www/UNL_Peoplefinder/pear.unl.edu/peoplefinder_default.css
new file mode 100644
index 00000000..162b93d9
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/peoplefinder_default.css
@@ -0,0 +1,139 @@
+#maincontent form#form1 {
+    margin-bottom:20px;
+}
+#maincontent form#form1 input#q{
+    background:#eee;
+    border:1px solid #ccc;
+    border-color:#c3c3c3 #eee #eee #c3c3c3;
+    color:#333;
+    padding:1px 2px;
+}
+#maincontent ul{
+    list-style:none;
+    padding:0;
+    margin-bottom:5px;
+    border-top:1px solid #ddd;clear:both;
+}
+#maincontent ul li.ppl_Sresult,
+#maincontent ul li.org_Sresult{
+    border-bottom:1px solid #ddd;
+    padding:0.7em 0 0.7em 0.7em;
+    border-left:1px solid #ccc;
+}
+#maincontent ul li.ppl_Sresult:hover,
+#maincontent ul li.ppl_Sresult.alt:hover,
+#maincontent ul li.org_Sresult:hover,
+#maincontent ul li.org_Sresult.alt:hover{
+    background:#EBF6FF;
+    border-bottom:1px solid #d3d3d3;
+}
+#maincontent ul li.ppl_Sresult.alt,
+#maincontent ul li.org_Sresult.alt{
+    background:#FAFAFA;
+}
+#maincontent ul li.ppl_Sresult div.tel,
+#maincontent ul li.org_Sresult div.tel{
+    background:url(images/mobile.gif) no-repeat 0 0.75em;
+    padding:0.5em 0 0 1em;
+    position:relative;
+    color:#333;
+}
+#maincontent ul li.org_Sresult .organization-unit {
+    clear:both;
+}
+#maincontent ul.department li.ppl_Sresult .organization-unit {
+    display:none;
+}
+#maincontent .fn{
+    float:left;
+    margin-right:0.2em;
+}
+#maincontent .result_head{
+    position:relative;
+    padding-bottom:0.4em;
+    font-weight:bold;
+}
+#maincontent .cMatch{
+    background:#ffffcc;
+    margin:1em 0 1em 0;
+    padding:0.5em;
+    border:1px solid #d0c8a5;
+}
+#maincontent .cMatch p {
+    margin:0;
+}
+#maincontent .cNav{
+    position:absolute;
+    right:0;
+    top:0;
+    font-weight:normal;
+    letter-spacing:-0.1em;
+}
+#maincontent a.next, #maincontent a.previous{
+    background:#eee;
+    border:1px solid #eee;
+    border-color:#eee #ccc #ccc #eee;
+    margin-left:3px;
+    padding:0;
+}
+#maincontent a.cInfo{
+    padding:0 0 0 1em;
+    margin-left:0.8em;color:#555;text-decoration:underline;
+}
+#maincontent ul li.ppl_Sresult a.cInfo {
+    background:url(images/person.gif) no-repeat 0 3px;
+}
+#maincontent ul li.org_Sresult a.cInfo {
+    background:url(images/home.gif) no-repeat 0 3px;
+}
+#maincontent .eppa{
+    font-size:0.75em;
+    margin-top:0.2em;
+}
+
+/** Individual Record */
+#maincontent .vcard{
+    border:1px solid #d3d3d3;
+    margin-top:8px;
+}
+#maincontent .vcard .photo{
+    float:right;
+}
+#maincontent .vcard .fn{
+    color:#900;
+    margin-bottom:2px;
+    padding:8px 0px 2px 5px;
+}
+#maincontent .vcard .eppa {
+    float:left;
+    margin-top:10px;
+}
+#maincontent .vcardInfo{
+    clear:both;
+    background: #FAFAFA;
+    padding:6px;
+    position:relative;
+    border-top:2px solid #E3E3E3;
+}
+#maincontent .vcard .adr, #maincontent .vcard .tel{
+    margin-top:10px;
+    margin-bottom:10px;
+    font-size:0.9em;
+}
+#maincontent .type{
+    font-weight:bold;
+}
+#maincontent .value{
+    display:block;
+}
+#maincontent a.downloadVcard{
+    position:absolute;
+    bottom:0;
+    right:0;
+    margin:0 6px 4px 0;
+}
+
+#maincontent span.email {
+    display:block;
+    line-height:1.5em
+}
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/service.php b/lib/www/UNL_Peoplefinder/pear.unl.edu/service.php
new file mode 100644
index 00000000..9745d382
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/service.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * This page provides the peoplefinder service to applications.
+ *
+ */
+
+require_once 'config.inc.php';
+
+// Specify domains from which requests are allowed
+header('Access-Control-Allow-Origin: *');
+
+// Specify which request methods are allowed
+header('Access-Control-Allow-Methods: GET, OPTIONS');
+
+// Additional headers which may be sent along with the CORS request
+// The X-Requested-With header allows jQuery requests to go through
+header('Access-Control-Allow-Headers: X-Requested-With');
+
+// Set the ages for the access-control header to 20 days to improve speed/caching.
+header('Access-Control-Max-Age: 1728000');
+
+// Set expires header for 24 hours to improve speed caching.
+header('Expires: '.date('r', strtotime('tomorrow')));
+
+// Exit early so the page isn't fully loaded for options requests
+if (strtolower($_SERVER['REQUEST_METHOD']) == 'options') {
+    exit();
+}
+
+$peepObj = new UNL_Peoplefinder();
+
+$format = 'html';
+
+$renderer_options = array('uid_onclick' => 'pf_getUID',
+                          'uri'         => UNL_PEOPLEFINDER_URI);
+if (isset($_GET['chooser'])) {
+    $renderer_options['choose_uid'] = true;
+}
+
+if (isset($_GET['renderer']) || isset($_GET['format'])) {
+    $format = isset($_GET['renderer'])?$_GET['renderer']:$_GET['format'];
+}
+switch($format) {
+case 'vcard':
+    $renderer_class = 'vCard';
+    break;
+case 'serialized':
+case 'php':
+    $renderer_class = 'Serialized';
+    break;
+case 'xml':
+    $renderer_class = 'XML';
+    break;
+case 'json':
+    $renderer_class = 'JSON';
+    break;
+default:
+case 'hcard':
+case 'html':
+    $renderer_class = 'HTML';
+    break;
+}
+
+$method = false;
+
+if (isset($_GET['method'])) {
+    switch ($_GET['method']) {
+    case 'getLikeMatches':
+    case 'getExactMatches':
+    case 'getPhoneMatches':
+        $method = $_GET['method'];
+        break;
+    }
+}
+
+$renderer_class = 'UNL_Peoplefinder_Renderer_'.$renderer_class;
+$renderer = new $renderer_class($renderer_options);
+if (isset($_GET['q']) && !empty($_GET['q'])) {
+    // Basic query, build filter and display results
+    if (strlen($_GET['q']) > 3) {
+        if (is_numeric(str_replace('-','',str_replace('(','',str_replace(')','',$_GET['q']))))) {
+            $records = $peepObj->getPhoneMatches($_GET['q']);
+            $renderer->renderSearchResults($records);
+        } else {
+            if ($method) {
+                $records = $peepObj->$method($_GET['q']);
+                if (count($records) > 0) {
+                    $renderer->renderSearchResults($records);
+                } else {
+                    $renderer->renderError();
+                }
+            } else {
+                $records = $peepObj->getExactMatches($_GET['q']);
+                if (count($records) > 0) {
+                    if ($renderer instanceof UNL_Peoplefinder_Renderer_HTML) {
+                        echo "<div class='cMatch'>Exact matches:</div>\n";
+                    }
+                    $renderer->renderSearchResults($records);
+                } else {
+                    if ($renderer instanceof UNL_Peoplefinder_Renderer_HTML) {
+                        echo 'No exact matches found.';
+                    }
+                }
+                if (count($records) < UNL_Peoplefinder::$displayResultLimit) {
+                    // More room to display LIKE results
+                    UNL_Peoplefinder::$displayResultLimit = UNL_Peoplefinder::$displayResultLimit-$peepObj->lastResultCount;
+                    $records = $peepObj->getLikeMatches($_GET['q'], $records);
+                    if (count($records) > 0) {
+                        if ($renderer instanceof UNL_Peoplefinder_Renderer_HTML) {
+                           echo "<div class='cMatch'>Possible matches:</div>\n";
+                        }
+                        $renderer->renderSearchResults($records);
+                    }
+                }
+            }
+        }
+    } else {
+        $renderer->renderError();
+    }
+} elseif (isset($_GET['uid']) && !empty($_GET['uid'])) {
+    $renderer->renderRecord($peepObj->getUID($_GET['uid']));
+} elseif (isset($_GET['d'])) {
+    try {
+        $department = new UNL_Peoplefinder_Department($_GET['d']);
+        foreach ($department as $employee) {
+            $renderer->renderRecord($employee);
+        }
+    } catch(Exception $e) {
+        $renderer->renderError($e->getMessage());
+    }
+} else {
+    $renderer->renderError();
+}
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/small_devices.css b/lib/www/UNL_Peoplefinder/pear.unl.edu/small_devices.css
new file mode 100644
index 00000000..cdc76534
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/small_devices.css
@@ -0,0 +1,4 @@
+@CHARSET "UTF-8";
+#maincontent {font-size:120%;}
+input {font-size:1.5em;}
+#submitbutton {width:42px;height:27px;}
\ No newline at end of file
diff --git a/lib/www/UNL_Peoplefinder/pear.unl.edu/standardForm.php b/lib/www/UNL_Peoplefinder/pear.unl.edu/standardForm.php
new file mode 100644
index 00000000..cd6a2fde
--- /dev/null
+++ b/lib/www/UNL_Peoplefinder/pear.unl.edu/standardForm.php
@@ -0,0 +1,16 @@
+<form method="get" id="form1" action="<?php echo htmlentities(str_replace('index.php', '', $_SERVER['PHP_SELF']), ENT_QUOTES); ?>">
+	<div>
+	<label for="q">Search People:&nbsp;</label> 
+    <?php if (isset($_GET['chooser'])) {
+    	echo '<input type="hidden" name="chooser" value="true" />';
+    }
+    if (isset($_GET['q'])) {
+        $default = htmlentities($_GET['q'], ENT_QUOTES);
+    } else {
+        $default = '';
+    }
+    ?>
+	<input style="width:18ex;" type="text" value="<?php echo $default; ?>" id="q" name="q" /> 
+	<input style="margin-bottom:-7px;" name="submitbutton" type="image" src="/ucomm/templatedependents/templatecss/images/go.gif" value="Submit" id="submitbutton" />
+	</div> 
+</form>
\ No newline at end of file
-- 
GitLab