diff --git a/build/.cvsignore b/build/.cvsignore
index 8b334c95e9940ecdedbe23a4cfad0c1abb2063f0..08502ee9ea800d8df3e3c006b1b4758c8d426df5 100644
--- a/build/.cvsignore
+++ b/build/.cvsignore
@@ -1,9 +1,9 @@
-dolibarr-*.exe
-dolibarr-*.tgz
-dolibarr-*.zip
-dolibarr-*.rpm
-dolibarr-*.deb
-makepack-google.conf
-module_google-*.tgz
-module_pibarcode-1.0.tgz
-*.exe
+dolibarr-*.exe
+dolibarr-*.tgz
+dolibarr-*.zip
+dolibarr-*.rpm
+dolibarr-*.deb
+makepack-google.conf
+module_google-*.tgz
+module_pibarcode-1.0.tgz
+*.exe
diff --git a/build/exe/doliwamp/.cvsignore b/build/exe/doliwamp/.cvsignore
index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644
--- a/build/exe/doliwamp/.cvsignore
+++ b/build/exe/doliwamp/.cvsignore
@@ -1 +1 @@
-*.db
+*.db
diff --git a/build/exe/doliwamp/dolibarr.conf.install b/build/exe/doliwamp/dolibarr.conf.install
index c57cfddfbbbe82c8ad7de9af2af3739798482f87..40b8dea77846a62ddbf934702143e4a32d3ae3bb 100644
--- a/build/exe/doliwamp/dolibarr.conf.install
+++ b/build/exe/doliwamp/dolibarr.conf.install
@@ -1,21 +1,21 @@
-Alias /dolibarr "WAMPROOT/www/dolibarr/htdocs/" 
-
-# NOTE:
-# To restrict access to dolibarr from outside set lines
-#
-#	Order Deny,Allow
-#	Deny from all
-#	Allow from 127.0.0.1
-#
-# instead of
-#
-#	Order Allow,Deny 
-#	Allow from all
-#
-
-<Directory "WAMPROOT/www/dolibarr/htdocs/">
-	Options Indexes FollowSymLinks MultiViews
-	AllowOverride all
-	Order Allow,Deny 
-	Allow from all
+Alias /dolibarr "WAMPROOT/www/dolibarr/htdocs/" 
+
+# NOTE:
+# To restrict access to dolibarr from outside set lines
+#
+#	Order Deny,Allow
+#	Deny from all
+#	Allow from 127.0.0.1
+#
+# instead of
+#
+#	Order Allow,Deny 
+#	Allow from all
+#
+
+<Directory "WAMPROOT/www/dolibarr/htdocs/">
+	Options Indexes FollowSymLinks MultiViews
+	AllowOverride all
+	Order Allow,Deny 
+	Allow from all
 </Directory>
\ No newline at end of file
diff --git a/build/exe/doliwamp/install_services.bat.install b/build/exe/doliwamp/install_services.bat.install
index e0e8310c15fddfae5a3e77e7f568240a34c03a03..b1f6eb45682e44815d742ba46f40d4be92c33533 100644
--- a/build/exe/doliwamp/install_services.bat.install
+++ b/build/exe/doliwamp/install_services.bat.install
@@ -1,7 +1,7 @@
-@echo off
-REM NET STOP doliwampapache
-REM NET STOP doliwampmysqld 
-.\bin\apache\apacheWAMPAPACHEVERSION\bin\httpd.exe -k install -n doliwampapache
-REM reg add HKLM\SYSTEM\CurrentControlSet\Services\doliwampapache /V Start /t REG_DWORD /d 3 /f
-REM .\bin\mysql\mysqlWAMPMYSQLVERSION\bin\mysqld-nt.exe --install-manual doliwampmysqld
-.\bin\mysql\mysqlWAMPMYSQLVERSION\bin\mysqld-nt.exe --install doliwampmysqld
+@echo off
+REM NET STOP doliwampapache
+REM NET STOP doliwampmysqld 
+.\bin\apache\apacheWAMPAPACHEVERSION\bin\httpd.exe -k install -n doliwampapache
+REM reg add HKLM\SYSTEM\CurrentControlSet\Services\doliwampapache /V Start /t REG_DWORD /d 3 /f
+REM .\bin\mysql\mysqlWAMPMYSQLVERSION\bin\mysqld-nt.exe --install-manual doliwampmysqld
+.\bin\mysql\mysqlWAMPMYSQLVERSION\bin\mysqld-nt.exe --install doliwampmysqld
diff --git a/build/exe/doliwamp/phpmyadmin.conf.install b/build/exe/doliwamp/phpmyadmin.conf.install
index f607a3bc5833f74c62435014bb307eb521187d81..ff7045835fae81ce171d794c6b8a6d11a362dc35 100644
--- a/build/exe/doliwamp/phpmyadmin.conf.install
+++ b/build/exe/doliwamp/phpmyadmin.conf.install
@@ -1,22 +1,22 @@
-Alias /phpmyadmin "WAMPROOT/apps/phpmyadminWAMPPHPMYADMINVERSION/" 
-
-# to give access to phpmyadmin from outside 
-# replace the lines
-#
-#        Order Deny,Allow
-#	Deny from all
-#	Allow from 127.0.0.1
-#
-# by
-#
-#        Order Allow,Deny 
-#   Allow from all
-#
-
-<Directory "WAMPROOT/apps/phpmyadminWAMPPHPMYADMINVERSION/">
-    Options Indexes FollowSymLinks MultiViews
-    AllowOverride all
-        Order Deny,Allow
-	Deny from all
-	Allow from 127.0.0.1
+Alias /phpmyadmin "WAMPROOT/apps/phpmyadminWAMPPHPMYADMINVERSION/" 
+
+# to give access to phpmyadmin from outside 
+# replace the lines
+#
+#        Order Deny,Allow
+#	Deny from all
+#	Allow from 127.0.0.1
+#
+# by
+#
+#        Order Allow,Deny 
+#   Allow from all
+#
+
+<Directory "WAMPROOT/apps/phpmyadminWAMPPHPMYADMINVERSION/">
+    Options Indexes FollowSymLinks MultiViews
+    AllowOverride all
+        Order Deny,Allow
+	Deny from all
+	Allow from 127.0.0.1
 </Directory>
\ No newline at end of file
diff --git a/build/exe/doliwamp/startdoliwamp.bat b/build/exe/doliwamp/startdoliwamp.bat
index 20171268be6f3458462edd3b47a9e5fd845c2004..452126b5a6968cfc4077fe8b1b4c51533ec527bb 100644
--- a/build/exe/doliwamp/startdoliwamp.bat
+++ b/build/exe/doliwamp/startdoliwamp.bat
@@ -1,5 +1,5 @@
-@echo off
-NET START doliwampapache
-NET START doliwampmysqld
-echo Please wait...
+@echo off
+NET START doliwampapache
+NET START doliwampmysqld
+echo Please wait...
 sleep 1
\ No newline at end of file
diff --git a/build/exe/doliwamp/stopdoliwamp.bat b/build/exe/doliwamp/stopdoliwamp.bat
index a863a727ddc16f2b6515caf6f41fa23dbfc79fa5..c65edefc10a6255584bc8ff2a1d45a97a641698e 100644
--- a/build/exe/doliwamp/stopdoliwamp.bat
+++ b/build/exe/doliwamp/stopdoliwamp.bat
@@ -1,5 +1,5 @@
-@echo off
-NET STOP doliwampapache
-NET STOP doliwampmysqld 
-echo Please wait...
+@echo off
+NET STOP doliwampapache
+NET STOP doliwampmysqld 
+echo Please wait...
 sleep 1
\ No newline at end of file
diff --git a/build/exe/doliwamp/uninstall_services.bat.install b/build/exe/doliwamp/uninstall_services.bat.install
index b3038ee4e06cf89225345bfb49c3b7fb95f57316..68a697de29636529c57e9e11a13526644ef276e6 100644
--- a/build/exe/doliwamp/uninstall_services.bat.install
+++ b/build/exe/doliwamp/uninstall_services.bat.install
@@ -1,5 +1,5 @@
-NET STOP doliwampapache
-.\bin\apache\apacheWAMPAPACHEVERSION\bin\httpd.exe -k uninstall -n doliwampapache
-NET STOP doliwampmysqld 
-.\bin\mysql\mysqlWAMPMYSQLVERSION\bin\mysqld-nt.exe --remove doliwampmysqld
+NET STOP doliwampapache
+.\bin\apache\apacheWAMPAPACHEVERSION\bin\httpd.exe -k uninstall -n doliwampapache
+NET STOP doliwampmysqld 
+.\bin\mysql\mysqlWAMPMYSQLVERSION\bin\mysqld-nt.exe --remove doliwampmysqld
 REM wampmanager.exe -quit -id={doliwampserver}
\ No newline at end of file
diff --git a/build/pad/Dolibarr v2.1.pml b/build/pad/Dolibarr v2.1.pml
index 247d43d3b00a5426e7c089088c3a66ab97e8768e..e64e0efb3671309940ae082fbabcc0117c513ae8 100644
--- a/build/pad/Dolibarr v2.1.pml	
+++ b/build/pad/Dolibarr v2.1.pml	
@@ -1,178 +1,178 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<PADGEN_PML>
-	<AppVerInfo>PADGen 3.0.1.35</AppVerInfo>
-	<CompanyName />
-	<Program_Info>
-		<Program_Name>Dolibarr</Program_Name>
-		<Program_Version>2.1</Program_Version>
-		<Program_Release_Month>04</Program_Release_Month>
-		<Program_Release_Day>27</Program_Release_Day>
-		<Program_Release_Year>2007</Program_Release_Year>
-		<Program_Cost_Dollars />
-		<Program_Cost_Other_Code />
-		<Program_Cost_Other />
-		<Program_Type>Freeware</Program_Type>
-		<Program_Release_Status>Major Update</Program_Release_Status>
-		<Program_Install_Support>No Install Support</Program_Install_Support>
-		<Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac Other,BEOS</Program_OS_Support>
-		<Program_Language>English,French</Program_Language>
-		<Program_Change_Info>http://www.dolibarr.org</Program_Change_Info>
-		<Program_Specific_Category>Business</Program_Specific_Category>
-		<Program_Category_Class>Business::Accounting &amp; Finance</Program_Category_Class>
-		<Program_System_Requirements>None</Program_System_Requirements>
-		<File_Info>
-			<File_Size_Bytes>1016660</File_Size_Bytes>
-			<File_Size_K>992</File_Size_K>
-			<File_Size_MB>0.97</File_Size_MB>
-		</File_Info>
-		<Expire_Info>
-			<Has_Expire_Info>N</Has_Expire_Info>
-			<Expire_Count />
-			<Expire_Based_On>Days</Expire_Based_On>
-			<Expire_Other_Info />
-			<Expire_Month />
-			<Expire_Day />
-			<Expire_Year />
-		</Expire_Info>
-	</Program_Info>
-	<Program_Descriptions>
-		<English>
-			<Keywords>dolibarr</Keywords>
-			<Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45>
-			<Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80>
-			<Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250>
-			<Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450>
-			<Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000>
-		</English>
-		<French>
-			<Keywords />
-			<Char_Desc_45 />
-			<Char_Desc_80 />
-			<Char_Desc_250 />
-			<Char_Desc_450 />
-			<Char_Desc_2000 />
-		</French>
-	</Program_Descriptions>
-	<Web_Info>
-		<Application_URLs>
-			<Application_Info_URL>http://www.dolibarr.org</Application_Info_URL>
-			<Application_Order_URL>http://www.dolibarr.org</Application_Order_URL>
-			<Application_Screenshot_URL>http://www.dolibarr.org/demo/doc/images/dolibarr_screenshot2.png</Application_Screenshot_URL>
-			<Application_Icon_URL>http://www.dolibarr.org/demo/doc/images/dolibarr.gif</Application_Icon_URL>
-			<Application_XML_File_URL>http://www.dolibarr.org/demo/build/pad/pad_dolibarr.xml</Application_XML_File_URL>
-		</Application_URLs>
-		<Download_URLs>
-			<Primary_Download_URL>http://www.dolibarr.org/component/option,com_docman/task,doc_download/gid,1/Itemid,36/lang,en/</Primary_Download_URL>
-			<Secondary_Download_URL />
-			<Additional_Download_URL_1 />
-			<Additional_Download_URL_2 />
-		</Download_URLs>
-	</Web_Info>
-	<Permissions>
-		<Distribution_Permissions>GNU GPL</Distribution_Permissions>
-		<EULA>GNU GPL</EULA>
-	</Permissions>
-	<ASP>
-		<ASP_FORM>Y</ASP_FORM>
-		<ASP_Member>N</ASP_Member>
-		<ASP_Member_Number />
-	</ASP>
-	<Affiliates>
-		<Affiliates_FORM>Y</Affiliates_FORM>
-		<Affiliates_VERSION>1.2</Affiliates_VERSION>
-		<Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL>
-		<Affiliates_Information_Page />
-		<Affiliates_Avangate_Order_Page />
-		<Affiliates_Avangate_Vendor_ID />
-		<Affiliates_Avangate_Product_ID />
-		<Affiliates_Avangate_Maximum_Commission_Rate />
-		<Affiliates_BMTMicro_Order_Page />
-		<Affiliates_BMTMicro_Vendor_ID />
-		<Affiliates_BMTMicro_Product_ID />
-		<Affiliates_BMTMicro_Maximum_Commission_Rate />
-		<Affiliates_clixGalore_Order_Page />
-		<Affiliates_clixGalore_Vendor_ID />
-		<Affiliates_clixGalore_Product_ID />
-		<Affiliates_clixGalore_Maximum_Commission_Rate />
-		<Affiliates_CommissionJunction_Order_Page />
-		<Affiliates_CommissionJunction_Vendor_ID />
-		<Affiliates_CommissionJunction_Product_ID />
-		<Affiliates_CommissionJunction_Maximum_Commission_Rate />
-		<Affiliates_DigiBuy_Order_Page />
-		<Affiliates_DigiBuy_Vendor_ID />
-		<Affiliates_DigiBuy_Product_ID />
-		<Affiliates_DigiBuy_Maximum_Commission_Rate />
-		<Affiliates_DigitalCandle_Order_Page />
-		<Affiliates_DigitalCandle_Vendor_ID />
-		<Affiliates_DigitalCandle_Product_ID />
-		<Affiliates_DigitalCandle_Maximum_Commission_Rate />
-		<Affiliates_Emetrix_Order_Page />
-		<Affiliates_Emetrix_Vendor_ID />
-		<Affiliates_Emetrix_Product_ID />
-		<Affiliates_Emetrix_Maximum_Commission_Rate />
-		<Affiliates_eSellerate_Order_Page />
-		<Affiliates_eSellerate_Vendor_ID />
-		<Affiliates_eSellerate_Product_ID />
-		<Affiliates_eSellerate_Maximum_Commission_Rate />
-		<Affiliates_Kagi_Order_Page />
-		<Affiliates_Kagi_Vendor_ID />
-		<Affiliates_Kagi_Product_ID />
-		<Affiliates_Kagi_Maximum_Commission_Rate />
-		<Affiliates_LinkShare_Order_Page />
-		<Affiliates_LinkShare_Vendor_ID />
-		<Affiliates_LinkShare_Product_ID />
-		<Affiliates_LinkShare_Maximum_Commission_Rate />
-		<Affiliates_NorthStarSol_Order_Page />
-		<Affiliates_NorthStarSol_Vendor_ID />
-		<Affiliates_NorthStarSol_Product_ID />
-		<Affiliates_NorthStarSol_Maximum_Commission_Rate />
-		<Affiliates_Order1_Order_Page />
-		<Affiliates_Order1_Vendor_ID />
-		<Affiliates_Order1_Product_ID />
-		<Affiliates_Order1_Maximum_Commission_Rate />
-		<Affiliates_Osolis_Order_Page />
-		<Affiliates_Osolis_Vendor_ID />
-		<Affiliates_Osolis_Product_ID />
-		<Affiliates_Osolis_Maximum_Commission_Rate />
-		<Affiliates_Plimus_Order_Page />
-		<Affiliates_Plimus_Vendor_ID />
-		<Affiliates_Plimus_Product_ID />
-		<Affiliates_Plimus_Maximum_Commission_Rate />
-		<Affiliates_Regnet_Order_Page />
-		<Affiliates_Regnet_Vendor_ID />
-		<Affiliates_Regnet_Product_ID />
-		<Affiliates_Regnet_Maximum_Commission_Rate />
-		<Affiliates_Regnow_Order_Page />
-		<Affiliates_Regnow_Vendor_ID />
-		<Affiliates_Regnow_Product_ID />
-		<Affiliates_Regnow_Maximum_Commission_Rate />
-		<Affiliates_Regsoft_Order_Page />
-		<Affiliates_Regsoft_Vendor_ID />
-		<Affiliates_Regsoft_Product_ID />
-		<Affiliates_Regsoft_Maximum_Commission_Rate />
-		<Affiliates_ShareIt_Order_Page />
-		<Affiliates_ShareIt_Vendor_ID />
-		<Affiliates_ShareIt_Product_ID />
-		<Affiliates_ShareIt_Maximum_Commission_Rate />
-		<Affiliates_Shareasale_Order_Page />
-		<Affiliates_Shareasale_Vendor_ID />
-		<Affiliates_Shareasale_Product_ID />
-		<Affiliates_Shareasale_Maximum_Commission_Rate />
-		<Affiliates_SWReg_Order_Page />
-		<Affiliates_SWReg_Vendor_ID />
-		<Affiliates_SWReg_Product_ID />
-		<Affiliates_SWReg_Maximum_Commission_Rate />
-		<Affiliates_V-Share_Order_Page />
-		<Affiliates_V-Share_Vendor_ID />
-		<Affiliates_V-Share_Product_ID />
-		<Affiliates_V-Share_Maximum_Commission_Rate />
-		<Affiliates_VFree_Order_Page />
-		<Affiliates_VFree_Vendor_ID />
-		<Affiliates_VFree_Product_ID />
-		<Affiliates_VFree_Maximum_Commission_Rate />
-		<Affiliates_Yaskifo_Order_Page />
-		<Affiliates_Yaskifo_Vendor_ID />
-		<Affiliates_Yaskifo_Product_ID />
-		<Affiliates_Yaskifo_Maximum_Commission_Rate />
-	</Affiliates>
-</PADGEN_PML>
+<?xml version="1.0" encoding="UTF-8" ?>
+<PADGEN_PML>
+	<AppVerInfo>PADGen 3.0.1.35</AppVerInfo>
+	<CompanyName />
+	<Program_Info>
+		<Program_Name>Dolibarr</Program_Name>
+		<Program_Version>2.1</Program_Version>
+		<Program_Release_Month>04</Program_Release_Month>
+		<Program_Release_Day>27</Program_Release_Day>
+		<Program_Release_Year>2007</Program_Release_Year>
+		<Program_Cost_Dollars />
+		<Program_Cost_Other_Code />
+		<Program_Cost_Other />
+		<Program_Type>Freeware</Program_Type>
+		<Program_Release_Status>Major Update</Program_Release_Status>
+		<Program_Install_Support>No Install Support</Program_Install_Support>
+		<Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac Other,BEOS</Program_OS_Support>
+		<Program_Language>English,French</Program_Language>
+		<Program_Change_Info>http://www.dolibarr.org</Program_Change_Info>
+		<Program_Specific_Category>Business</Program_Specific_Category>
+		<Program_Category_Class>Business::Accounting &amp; Finance</Program_Category_Class>
+		<Program_System_Requirements>None</Program_System_Requirements>
+		<File_Info>
+			<File_Size_Bytes>1016660</File_Size_Bytes>
+			<File_Size_K>992</File_Size_K>
+			<File_Size_MB>0.97</File_Size_MB>
+		</File_Info>
+		<Expire_Info>
+			<Has_Expire_Info>N</Has_Expire_Info>
+			<Expire_Count />
+			<Expire_Based_On>Days</Expire_Based_On>
+			<Expire_Other_Info />
+			<Expire_Month />
+			<Expire_Day />
+			<Expire_Year />
+		</Expire_Info>
+	</Program_Info>
+	<Program_Descriptions>
+		<English>
+			<Keywords>dolibarr</Keywords>
+			<Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45>
+			<Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80>
+			<Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250>
+			<Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450>
+			<Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000>
+		</English>
+		<French>
+			<Keywords />
+			<Char_Desc_45 />
+			<Char_Desc_80 />
+			<Char_Desc_250 />
+			<Char_Desc_450 />
+			<Char_Desc_2000 />
+		</French>
+	</Program_Descriptions>
+	<Web_Info>
+		<Application_URLs>
+			<Application_Info_URL>http://www.dolibarr.org</Application_Info_URL>
+			<Application_Order_URL>http://www.dolibarr.org</Application_Order_URL>
+			<Application_Screenshot_URL>http://www.dolibarr.org/demo/doc/images/dolibarr_screenshot2.png</Application_Screenshot_URL>
+			<Application_Icon_URL>http://www.dolibarr.org/demo/doc/images/dolibarr.gif</Application_Icon_URL>
+			<Application_XML_File_URL>http://www.dolibarr.org/demo/build/pad/pad_dolibarr.xml</Application_XML_File_URL>
+		</Application_URLs>
+		<Download_URLs>
+			<Primary_Download_URL>http://www.dolibarr.org/component/option,com_docman/task,doc_download/gid,1/Itemid,36/lang,en/</Primary_Download_URL>
+			<Secondary_Download_URL />
+			<Additional_Download_URL_1 />
+			<Additional_Download_URL_2 />
+		</Download_URLs>
+	</Web_Info>
+	<Permissions>
+		<Distribution_Permissions>GNU GPL</Distribution_Permissions>
+		<EULA>GNU GPL</EULA>
+	</Permissions>
+	<ASP>
+		<ASP_FORM>Y</ASP_FORM>
+		<ASP_Member>N</ASP_Member>
+		<ASP_Member_Number />
+	</ASP>
+	<Affiliates>
+		<Affiliates_FORM>Y</Affiliates_FORM>
+		<Affiliates_VERSION>1.2</Affiliates_VERSION>
+		<Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL>
+		<Affiliates_Information_Page />
+		<Affiliates_Avangate_Order_Page />
+		<Affiliates_Avangate_Vendor_ID />
+		<Affiliates_Avangate_Product_ID />
+		<Affiliates_Avangate_Maximum_Commission_Rate />
+		<Affiliates_BMTMicro_Order_Page />
+		<Affiliates_BMTMicro_Vendor_ID />
+		<Affiliates_BMTMicro_Product_ID />
+		<Affiliates_BMTMicro_Maximum_Commission_Rate />
+		<Affiliates_clixGalore_Order_Page />
+		<Affiliates_clixGalore_Vendor_ID />
+		<Affiliates_clixGalore_Product_ID />
+		<Affiliates_clixGalore_Maximum_Commission_Rate />
+		<Affiliates_CommissionJunction_Order_Page />
+		<Affiliates_CommissionJunction_Vendor_ID />
+		<Affiliates_CommissionJunction_Product_ID />
+		<Affiliates_CommissionJunction_Maximum_Commission_Rate />
+		<Affiliates_DigiBuy_Order_Page />
+		<Affiliates_DigiBuy_Vendor_ID />
+		<Affiliates_DigiBuy_Product_ID />
+		<Affiliates_DigiBuy_Maximum_Commission_Rate />
+		<Affiliates_DigitalCandle_Order_Page />
+		<Affiliates_DigitalCandle_Vendor_ID />
+		<Affiliates_DigitalCandle_Product_ID />
+		<Affiliates_DigitalCandle_Maximum_Commission_Rate />
+		<Affiliates_Emetrix_Order_Page />
+		<Affiliates_Emetrix_Vendor_ID />
+		<Affiliates_Emetrix_Product_ID />
+		<Affiliates_Emetrix_Maximum_Commission_Rate />
+		<Affiliates_eSellerate_Order_Page />
+		<Affiliates_eSellerate_Vendor_ID />
+		<Affiliates_eSellerate_Product_ID />
+		<Affiliates_eSellerate_Maximum_Commission_Rate />
+		<Affiliates_Kagi_Order_Page />
+		<Affiliates_Kagi_Vendor_ID />
+		<Affiliates_Kagi_Product_ID />
+		<Affiliates_Kagi_Maximum_Commission_Rate />
+		<Affiliates_LinkShare_Order_Page />
+		<Affiliates_LinkShare_Vendor_ID />
+		<Affiliates_LinkShare_Product_ID />
+		<Affiliates_LinkShare_Maximum_Commission_Rate />
+		<Affiliates_NorthStarSol_Order_Page />
+		<Affiliates_NorthStarSol_Vendor_ID />
+		<Affiliates_NorthStarSol_Product_ID />
+		<Affiliates_NorthStarSol_Maximum_Commission_Rate />
+		<Affiliates_Order1_Order_Page />
+		<Affiliates_Order1_Vendor_ID />
+		<Affiliates_Order1_Product_ID />
+		<Affiliates_Order1_Maximum_Commission_Rate />
+		<Affiliates_Osolis_Order_Page />
+		<Affiliates_Osolis_Vendor_ID />
+		<Affiliates_Osolis_Product_ID />
+		<Affiliates_Osolis_Maximum_Commission_Rate />
+		<Affiliates_Plimus_Order_Page />
+		<Affiliates_Plimus_Vendor_ID />
+		<Affiliates_Plimus_Product_ID />
+		<Affiliates_Plimus_Maximum_Commission_Rate />
+		<Affiliates_Regnet_Order_Page />
+		<Affiliates_Regnet_Vendor_ID />
+		<Affiliates_Regnet_Product_ID />
+		<Affiliates_Regnet_Maximum_Commission_Rate />
+		<Affiliates_Regnow_Order_Page />
+		<Affiliates_Regnow_Vendor_ID />
+		<Affiliates_Regnow_Product_ID />
+		<Affiliates_Regnow_Maximum_Commission_Rate />
+		<Affiliates_Regsoft_Order_Page />
+		<Affiliates_Regsoft_Vendor_ID />
+		<Affiliates_Regsoft_Product_ID />
+		<Affiliates_Regsoft_Maximum_Commission_Rate />
+		<Affiliates_ShareIt_Order_Page />
+		<Affiliates_ShareIt_Vendor_ID />
+		<Affiliates_ShareIt_Product_ID />
+		<Affiliates_ShareIt_Maximum_Commission_Rate />
+		<Affiliates_Shareasale_Order_Page />
+		<Affiliates_Shareasale_Vendor_ID />
+		<Affiliates_Shareasale_Product_ID />
+		<Affiliates_Shareasale_Maximum_Commission_Rate />
+		<Affiliates_SWReg_Order_Page />
+		<Affiliates_SWReg_Vendor_ID />
+		<Affiliates_SWReg_Product_ID />
+		<Affiliates_SWReg_Maximum_Commission_Rate />
+		<Affiliates_V-Share_Order_Page />
+		<Affiliates_V-Share_Vendor_ID />
+		<Affiliates_V-Share_Product_ID />
+		<Affiliates_V-Share_Maximum_Commission_Rate />
+		<Affiliates_VFree_Order_Page />
+		<Affiliates_VFree_Vendor_ID />
+		<Affiliates_VFree_Product_ID />
+		<Affiliates_VFree_Maximum_Commission_Rate />
+		<Affiliates_Yaskifo_Order_Page />
+		<Affiliates_Yaskifo_Vendor_ID />
+		<Affiliates_Yaskifo_Product_ID />
+		<Affiliates_Yaskifo_Maximum_Commission_Rate />
+	</Affiliates>
+</PADGEN_PML>
diff --git a/build/pad/Dolibarr v2.2.pml b/build/pad/Dolibarr v2.2.pml
index d6833e13763c4dec6e872b60aa15ac6230f57c3a..d3f3bc02f4a6f1514ab3a43eaf37671810ed4f5e 100644
--- a/build/pad/Dolibarr v2.2.pml	
+++ b/build/pad/Dolibarr v2.2.pml	
@@ -1,178 +1,178 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<PADGEN_PML>
-	<AppVerInfo>PADGen 3.0.1.35</AppVerInfo>
-	<CompanyName />
-	<Program_Info>
-		<Program_Name>Dolibarr</Program_Name>
-		<Program_Version>2.2</Program_Version>
-		<Program_Release_Month>12</Program_Release_Month>
-		<Program_Release_Day>27</Program_Release_Day>
-		<Program_Release_Year>2007</Program_Release_Year>
-		<Program_Cost_Dollars />
-		<Program_Cost_Other_Code />
-		<Program_Cost_Other />
-		<Program_Type>Freeware</Program_Type>
-		<Program_Release_Status>Major Update</Program_Release_Status>
-		<Program_Install_Support>No Install Support</Program_Install_Support>
-		<Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac OS X 10.1,Mac OS X 10.2,Mac OS X 10.3,Mac OS X 10.4,Mac OS X 10.5,Mac Other,BEOS</Program_OS_Support>
-		<Program_Language>English,French</Program_Language>
-		<Program_Change_Info>http://www.dolibarr.org</Program_Change_Info>
-		<Program_Specific_Category>Business</Program_Specific_Category>
-		<Program_Category_Class>Business::Accounting &amp; Finance</Program_Category_Class>
-		<Program_System_Requirements>None</Program_System_Requirements>
-		<File_Info>
-			<File_Size_Bytes>1016660</File_Size_Bytes>
-			<File_Size_K>992</File_Size_K>
-			<File_Size_MB>0.97</File_Size_MB>
-		</File_Info>
-		<Expire_Info>
-			<Has_Expire_Info>N</Has_Expire_Info>
-			<Expire_Count />
-			<Expire_Based_On>Days</Expire_Based_On>
-			<Expire_Other_Info />
-			<Expire_Month />
-			<Expire_Day />
-			<Expire_Year />
-		</Expire_Info>
-	</Program_Info>
-	<Program_Descriptions>
-		<English>
-			<Keywords>dolibarr</Keywords>
-			<Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45>
-			<Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80>
-			<Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250>
-			<Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450>
-			<Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000>
-		</English>
-		<French>
-			<Keywords />
-			<Char_Desc_45 />
-			<Char_Desc_80 />
-			<Char_Desc_250 />
-			<Char_Desc_450 />
-			<Char_Desc_2000 />
-		</French>
-	</Program_Descriptions>
-	<Web_Info>
-		<Application_URLs>
-			<Application_Info_URL>http://www.dolibarr.org</Application_Info_URL>
-			<Application_Order_URL>http://www.dolibarr.org</Application_Order_URL>
-			<Application_Screenshot_URL>http://www.dolibarr.org/images/dolibarr_screenshot2.png</Application_Screenshot_URL>
-			<Application_Icon_URL>http://www.dolibarr.org/images/dolibarr.gif</Application_Icon_URL>
-			<Application_XML_File_URL>http://www.dolibarr.org/images/pad_dolibarr.xml</Application_XML_File_URL>
-		</Application_URLs>
-		<Download_URLs>
-			<Primary_Download_URL>http://www.dolibarr.org/images/dolibarr.tgz</Primary_Download_URL>
-			<Secondary_Download_URL>http://www.dolibarr.org/images/dolibarr.tgz</Secondary_Download_URL>
-			<Additional_Download_URL_1 />
-			<Additional_Download_URL_2 />
-		</Download_URLs>
-	</Web_Info>
-	<Permissions>
-		<Distribution_Permissions>GNU GPL</Distribution_Permissions>
-		<EULA>GNU GPL</EULA>
-	</Permissions>
-	<ASP>
-		<ASP_FORM>Y</ASP_FORM>
-		<ASP_Member>N</ASP_Member>
-		<ASP_Member_Number />
-	</ASP>
-	<Affiliates>
-		<Affiliates_FORM>Y</Affiliates_FORM>
-		<Affiliates_VERSION>1.2</Affiliates_VERSION>
-		<Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL>
-		<Affiliates_Information_Page />
-		<Affiliates_Avangate_Order_Page />
-		<Affiliates_Avangate_Vendor_ID />
-		<Affiliates_Avangate_Product_ID />
-		<Affiliates_Avangate_Maximum_Commission_Rate />
-		<Affiliates_BMTMicro_Order_Page />
-		<Affiliates_BMTMicro_Vendor_ID />
-		<Affiliates_BMTMicro_Product_ID />
-		<Affiliates_BMTMicro_Maximum_Commission_Rate />
-		<Affiliates_clixGalore_Order_Page />
-		<Affiliates_clixGalore_Vendor_ID />
-		<Affiliates_clixGalore_Product_ID />
-		<Affiliates_clixGalore_Maximum_Commission_Rate />
-		<Affiliates_CommissionJunction_Order_Page />
-		<Affiliates_CommissionJunction_Vendor_ID />
-		<Affiliates_CommissionJunction_Product_ID />
-		<Affiliates_CommissionJunction_Maximum_Commission_Rate />
-		<Affiliates_DigiBuy_Order_Page />
-		<Affiliates_DigiBuy_Vendor_ID />
-		<Affiliates_DigiBuy_Product_ID />
-		<Affiliates_DigiBuy_Maximum_Commission_Rate />
-		<Affiliates_DigitalCandle_Order_Page />
-		<Affiliates_DigitalCandle_Vendor_ID />
-		<Affiliates_DigitalCandle_Product_ID />
-		<Affiliates_DigitalCandle_Maximum_Commission_Rate />
-		<Affiliates_Emetrix_Order_Page />
-		<Affiliates_Emetrix_Vendor_ID />
-		<Affiliates_Emetrix_Product_ID />
-		<Affiliates_Emetrix_Maximum_Commission_Rate />
-		<Affiliates_eSellerate_Order_Page />
-		<Affiliates_eSellerate_Vendor_ID />
-		<Affiliates_eSellerate_Product_ID />
-		<Affiliates_eSellerate_Maximum_Commission_Rate />
-		<Affiliates_Kagi_Order_Page />
-		<Affiliates_Kagi_Vendor_ID />
-		<Affiliates_Kagi_Product_ID />
-		<Affiliates_Kagi_Maximum_Commission_Rate />
-		<Affiliates_LinkShare_Order_Page />
-		<Affiliates_LinkShare_Vendor_ID />
-		<Affiliates_LinkShare_Product_ID />
-		<Affiliates_LinkShare_Maximum_Commission_Rate />
-		<Affiliates_NorthStarSol_Order_Page />
-		<Affiliates_NorthStarSol_Vendor_ID />
-		<Affiliates_NorthStarSol_Product_ID />
-		<Affiliates_NorthStarSol_Maximum_Commission_Rate />
-		<Affiliates_Order1_Order_Page />
-		<Affiliates_Order1_Vendor_ID />
-		<Affiliates_Order1_Product_ID />
-		<Affiliates_Order1_Maximum_Commission_Rate />
-		<Affiliates_Osolis_Order_Page />
-		<Affiliates_Osolis_Vendor_ID />
-		<Affiliates_Osolis_Product_ID />
-		<Affiliates_Osolis_Maximum_Commission_Rate />
-		<Affiliates_Plimus_Order_Page />
-		<Affiliates_Plimus_Vendor_ID />
-		<Affiliates_Plimus_Product_ID />
-		<Affiliates_Plimus_Maximum_Commission_Rate />
-		<Affiliates_Regnet_Order_Page />
-		<Affiliates_Regnet_Vendor_ID />
-		<Affiliates_Regnet_Product_ID />
-		<Affiliates_Regnet_Maximum_Commission_Rate />
-		<Affiliates_Regnow_Order_Page />
-		<Affiliates_Regnow_Vendor_ID />
-		<Affiliates_Regnow_Product_ID />
-		<Affiliates_Regnow_Maximum_Commission_Rate />
-		<Affiliates_Regsoft_Order_Page />
-		<Affiliates_Regsoft_Vendor_ID />
-		<Affiliates_Regsoft_Product_ID />
-		<Affiliates_Regsoft_Maximum_Commission_Rate />
-		<Affiliates_ShareIt_Order_Page />
-		<Affiliates_ShareIt_Vendor_ID />
-		<Affiliates_ShareIt_Product_ID />
-		<Affiliates_ShareIt_Maximum_Commission_Rate />
-		<Affiliates_Shareasale_Order_Page />
-		<Affiliates_Shareasale_Vendor_ID />
-		<Affiliates_Shareasale_Product_ID />
-		<Affiliates_Shareasale_Maximum_Commission_Rate />
-		<Affiliates_SWReg_Order_Page />
-		<Affiliates_SWReg_Vendor_ID />
-		<Affiliates_SWReg_Product_ID />
-		<Affiliates_SWReg_Maximum_Commission_Rate />
-		<Affiliates_V-Share_Order_Page />
-		<Affiliates_V-Share_Vendor_ID />
-		<Affiliates_V-Share_Product_ID />
-		<Affiliates_V-Share_Maximum_Commission_Rate />
-		<Affiliates_VFree_Order_Page />
-		<Affiliates_VFree_Vendor_ID />
-		<Affiliates_VFree_Product_ID />
-		<Affiliates_VFree_Maximum_Commission_Rate />
-		<Affiliates_Yaskifo_Order_Page />
-		<Affiliates_Yaskifo_Vendor_ID />
-		<Affiliates_Yaskifo_Product_ID />
-		<Affiliates_Yaskifo_Maximum_Commission_Rate />
-	</Affiliates>
-</PADGEN_PML>
+<?xml version="1.0" encoding="UTF-8" ?>
+<PADGEN_PML>
+	<AppVerInfo>PADGen 3.0.1.35</AppVerInfo>
+	<CompanyName />
+	<Program_Info>
+		<Program_Name>Dolibarr</Program_Name>
+		<Program_Version>2.2</Program_Version>
+		<Program_Release_Month>12</Program_Release_Month>
+		<Program_Release_Day>27</Program_Release_Day>
+		<Program_Release_Year>2007</Program_Release_Year>
+		<Program_Cost_Dollars />
+		<Program_Cost_Other_Code />
+		<Program_Cost_Other />
+		<Program_Type>Freeware</Program_Type>
+		<Program_Release_Status>Major Update</Program_Release_Status>
+		<Program_Install_Support>No Install Support</Program_Install_Support>
+		<Program_OS_Support>Win95,Win98,WinME,WinNT 4.x,Windows2000,WinXP,Windows2003,Windows Vista Starter,Windows Vista Home Basic,Windows Vista Home Premium,Windows Vista Business,Windows Vista Enterprise,Windows Vista Ultimate,Windows Vista Home Basic x64,Windows Vista Home Premium x64,Windows Vista Business x64,Windows Vista Enterprise x64,Windows Vista Ultimate x64,Unix,Linux,OS/2,OS/2 Warp,OS/2 Warp 4,MAC 68k,Mac PPC,Mac OS X,Mac OS X 10.1,Mac OS X 10.2,Mac OS X 10.3,Mac OS X 10.4,Mac OS X 10.5,Mac Other,BEOS</Program_OS_Support>
+		<Program_Language>English,French</Program_Language>
+		<Program_Change_Info>http://www.dolibarr.org</Program_Change_Info>
+		<Program_Specific_Category>Business</Program_Specific_Category>
+		<Program_Category_Class>Business::Accounting &amp; Finance</Program_Category_Class>
+		<Program_System_Requirements>None</Program_System_Requirements>
+		<File_Info>
+			<File_Size_Bytes>1016660</File_Size_Bytes>
+			<File_Size_K>992</File_Size_K>
+			<File_Size_MB>0.97</File_Size_MB>
+		</File_Info>
+		<Expire_Info>
+			<Has_Expire_Info>N</Has_Expire_Info>
+			<Expire_Count />
+			<Expire_Based_On>Days</Expire_Based_On>
+			<Expire_Other_Info />
+			<Expire_Month />
+			<Expire_Day />
+			<Expire_Year />
+		</Expire_Info>
+	</Program_Info>
+	<Program_Descriptions>
+		<English>
+			<Keywords>dolibarr</Keywords>
+			<Char_Desc_45>Dolibarr ERP/CRM</Char_Desc_45>
+			<Char_Desc_80>Dolibarr ERP/CRM</Char_Desc_80>
+			<Char_Desc_250>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_250>
+			<Char_Desc_450>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_450>
+			<Char_Desc_2000>Dolibarr ERP/CRM is an open source tool to manage invoices, customers, suppliers, contracts and any other things a small or medium company needs.</Char_Desc_2000>
+		</English>
+		<French>
+			<Keywords />
+			<Char_Desc_45 />
+			<Char_Desc_80 />
+			<Char_Desc_250 />
+			<Char_Desc_450 />
+			<Char_Desc_2000 />
+		</French>
+	</Program_Descriptions>
+	<Web_Info>
+		<Application_URLs>
+			<Application_Info_URL>http://www.dolibarr.org</Application_Info_URL>
+			<Application_Order_URL>http://www.dolibarr.org</Application_Order_URL>
+			<Application_Screenshot_URL>http://www.dolibarr.org/images/dolibarr_screenshot2.png</Application_Screenshot_URL>
+			<Application_Icon_URL>http://www.dolibarr.org/images/dolibarr.gif</Application_Icon_URL>
+			<Application_XML_File_URL>http://www.dolibarr.org/images/pad_dolibarr.xml</Application_XML_File_URL>
+		</Application_URLs>
+		<Download_URLs>
+			<Primary_Download_URL>http://www.dolibarr.org/images/dolibarr.tgz</Primary_Download_URL>
+			<Secondary_Download_URL>http://www.dolibarr.org/images/dolibarr.tgz</Secondary_Download_URL>
+			<Additional_Download_URL_1 />
+			<Additional_Download_URL_2 />
+		</Download_URLs>
+	</Web_Info>
+	<Permissions>
+		<Distribution_Permissions>GNU GPL</Distribution_Permissions>
+		<EULA>GNU GPL</EULA>
+	</Permissions>
+	<ASP>
+		<ASP_FORM>Y</ASP_FORM>
+		<ASP_Member>N</ASP_Member>
+		<ASP_Member_Number />
+	</ASP>
+	<Affiliates>
+		<Affiliates_FORM>Y</Affiliates_FORM>
+		<Affiliates_VERSION>1.2</Affiliates_VERSION>
+		<Affiliates_URL>http://www.asp-shareware.org/pad/extensions/Affiliates.htm</Affiliates_URL>
+		<Affiliates_Information_Page />
+		<Affiliates_Avangate_Order_Page />
+		<Affiliates_Avangate_Vendor_ID />
+		<Affiliates_Avangate_Product_ID />
+		<Affiliates_Avangate_Maximum_Commission_Rate />
+		<Affiliates_BMTMicro_Order_Page />
+		<Affiliates_BMTMicro_Vendor_ID />
+		<Affiliates_BMTMicro_Product_ID />
+		<Affiliates_BMTMicro_Maximum_Commission_Rate />
+		<Affiliates_clixGalore_Order_Page />
+		<Affiliates_clixGalore_Vendor_ID />
+		<Affiliates_clixGalore_Product_ID />
+		<Affiliates_clixGalore_Maximum_Commission_Rate />
+		<Affiliates_CommissionJunction_Order_Page />
+		<Affiliates_CommissionJunction_Vendor_ID />
+		<Affiliates_CommissionJunction_Product_ID />
+		<Affiliates_CommissionJunction_Maximum_Commission_Rate />
+		<Affiliates_DigiBuy_Order_Page />
+		<Affiliates_DigiBuy_Vendor_ID />
+		<Affiliates_DigiBuy_Product_ID />
+		<Affiliates_DigiBuy_Maximum_Commission_Rate />
+		<Affiliates_DigitalCandle_Order_Page />
+		<Affiliates_DigitalCandle_Vendor_ID />
+		<Affiliates_DigitalCandle_Product_ID />
+		<Affiliates_DigitalCandle_Maximum_Commission_Rate />
+		<Affiliates_Emetrix_Order_Page />
+		<Affiliates_Emetrix_Vendor_ID />
+		<Affiliates_Emetrix_Product_ID />
+		<Affiliates_Emetrix_Maximum_Commission_Rate />
+		<Affiliates_eSellerate_Order_Page />
+		<Affiliates_eSellerate_Vendor_ID />
+		<Affiliates_eSellerate_Product_ID />
+		<Affiliates_eSellerate_Maximum_Commission_Rate />
+		<Affiliates_Kagi_Order_Page />
+		<Affiliates_Kagi_Vendor_ID />
+		<Affiliates_Kagi_Product_ID />
+		<Affiliates_Kagi_Maximum_Commission_Rate />
+		<Affiliates_LinkShare_Order_Page />
+		<Affiliates_LinkShare_Vendor_ID />
+		<Affiliates_LinkShare_Product_ID />
+		<Affiliates_LinkShare_Maximum_Commission_Rate />
+		<Affiliates_NorthStarSol_Order_Page />
+		<Affiliates_NorthStarSol_Vendor_ID />
+		<Affiliates_NorthStarSol_Product_ID />
+		<Affiliates_NorthStarSol_Maximum_Commission_Rate />
+		<Affiliates_Order1_Order_Page />
+		<Affiliates_Order1_Vendor_ID />
+		<Affiliates_Order1_Product_ID />
+		<Affiliates_Order1_Maximum_Commission_Rate />
+		<Affiliates_Osolis_Order_Page />
+		<Affiliates_Osolis_Vendor_ID />
+		<Affiliates_Osolis_Product_ID />
+		<Affiliates_Osolis_Maximum_Commission_Rate />
+		<Affiliates_Plimus_Order_Page />
+		<Affiliates_Plimus_Vendor_ID />
+		<Affiliates_Plimus_Product_ID />
+		<Affiliates_Plimus_Maximum_Commission_Rate />
+		<Affiliates_Regnet_Order_Page />
+		<Affiliates_Regnet_Vendor_ID />
+		<Affiliates_Regnet_Product_ID />
+		<Affiliates_Regnet_Maximum_Commission_Rate />
+		<Affiliates_Regnow_Order_Page />
+		<Affiliates_Regnow_Vendor_ID />
+		<Affiliates_Regnow_Product_ID />
+		<Affiliates_Regnow_Maximum_Commission_Rate />
+		<Affiliates_Regsoft_Order_Page />
+		<Affiliates_Regsoft_Vendor_ID />
+		<Affiliates_Regsoft_Product_ID />
+		<Affiliates_Regsoft_Maximum_Commission_Rate />
+		<Affiliates_ShareIt_Order_Page />
+		<Affiliates_ShareIt_Vendor_ID />
+		<Affiliates_ShareIt_Product_ID />
+		<Affiliates_ShareIt_Maximum_Commission_Rate />
+		<Affiliates_Shareasale_Order_Page />
+		<Affiliates_Shareasale_Vendor_ID />
+		<Affiliates_Shareasale_Product_ID />
+		<Affiliates_Shareasale_Maximum_Commission_Rate />
+		<Affiliates_SWReg_Order_Page />
+		<Affiliates_SWReg_Vendor_ID />
+		<Affiliates_SWReg_Product_ID />
+		<Affiliates_SWReg_Maximum_Commission_Rate />
+		<Affiliates_V-Share_Order_Page />
+		<Affiliates_V-Share_Vendor_ID />
+		<Affiliates_V-Share_Product_ID />
+		<Affiliates_V-Share_Maximum_Commission_Rate />
+		<Affiliates_VFree_Order_Page />
+		<Affiliates_VFree_Vendor_ID />
+		<Affiliates_VFree_Product_ID />
+		<Affiliates_VFree_Maximum_Commission_Rate />
+		<Affiliates_Yaskifo_Order_Page />
+		<Affiliates_Yaskifo_Vendor_ID />
+		<Affiliates_Yaskifo_Product_ID />
+		<Affiliates_Yaskifo_Maximum_Commission_Rate />
+	</Affiliates>
+</PADGEN_PML>
diff --git a/dev/ldap/README b/dev/ldap/README
index 94131962af8e8ee2481d5247eba74d15f1eb8aaf..11ab3031335881c86f550cff0dc3ef15f7035e30 100644
--- a/dev/ldap/README
+++ b/dev/ldap/README
@@ -1,4 +1,4 @@
-README (english)
---------------------------------
-This directory contains some sample files to test ldap command on command line.
+README (english)
+--------------------------------
+This directory contains some sample files to test ldap command on command line.
 They are used to help developmement and debugging of Dolibarr LDAP features.
\ No newline at end of file
diff --git a/dev/ldap/ldapadd_sample1.txt b/dev/ldap/ldapadd_sample1.txt
index 8a11738d1bb89a5b9fe73e49be3fc847f30323a0..2a9738381a72d0c5e4bfdab9ea0f67135eb5b913 100644
--- a/dev/ldap/ldapadd_sample1.txt
+++ b/dev/ldap/ldapadd_sample1.txt
@@ -1,13 +1,13 @@
-# ldapadd_sample1.txt
-#
-# Use this sample to add a dc "my-domain".
-# This is the first thing to create
-#
-# ldapadd -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapadd_sample1.txt
-
-dn: dc=my-domain,dc=com
-objectclass: dcObject
-objectClass: organization
-objectClass: top
-dc: my-domain
+# ldapadd_sample1.txt
+#
+# Use this sample to add a dc "my-domain".
+# This is the first thing to create
+#
+# ldapadd -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapadd_sample1.txt
+
+dn: dc=my-domain,dc=com
+objectclass: dcObject
+objectClass: organization
+objectClass: top
+dc: my-domain
 o: Mon organisation
\ No newline at end of file
diff --git a/dev/ldap/ldapadd_sample3.txt b/dev/ldap/ldapadd_sample3.txt
index 5acfad510b7775a52f4b6ef0f109e2fbb8ca197b..65576a790903139fb63446389f91de108ac67038 100644
--- a/dev/ldap/ldapadd_sample3.txt
+++ b/dev/ldap/ldapadd_sample3.txt
@@ -1,19 +1,19 @@
-# ldapadd_sample3.txt
-#
-# Use this sample to add cn records
-# This is the step to create records inside tree ou=contacts,dc=my-domain,dc=com
-#
-# ldapadd -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapadd_sample3.txt
-
-dn: cn=Bruno et Sabine Tary,ou=contacts,dc=my-domain,dc=com
-objectClass: inetOrgPerson
-objectClass: organizationalPerson
-objectClass: person
-objectClass: top
-cn: Bruno et Sabine Tary
-cn: Barbara Jensen
-cn: Babs Jensen
-sn: Jensen
-description: aaa
-title: this is title
-mail: mail@mail.com
+# ldapadd_sample3.txt
+#
+# Use this sample to add cn records
+# This is the step to create records inside tree ou=contacts,dc=my-domain,dc=com
+#
+# ldapadd -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapadd_sample3.txt
+
+dn: cn=Bruno et Sabine Tary,ou=contacts,dc=my-domain,dc=com
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+objectClass: top
+cn: Bruno et Sabine Tary
+cn: Barbara Jensen
+cn: Babs Jensen
+sn: Jensen
+description: aaa
+title: this is title
+mail: mail@mail.com
diff --git a/dev/ldap/ldapdelete_sample1.txt b/dev/ldap/ldapdelete_sample1.txt
index d9f6cd5a941d1044fee60debab0d5adfde2b6fe8..cc2db307eeb1a3d2ab9de066c0501b98d647a7ed 100644
--- a/dev/ldap/ldapdelete_sample1.txt
+++ b/dev/ldap/ldapdelete_sample1.txt
@@ -1,9 +1,9 @@
-# ldapdelete_sample1.txt
-#
-# Use this sample to delete a dc "my-domain"
-# This delete the first level of LDAP tree.
-#
-# ldapmodify -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapdelete_sample1.txt
-
-dn: dc=my-domain,dc=com
-changetype: delete
+# ldapdelete_sample1.txt
+#
+# Use this sample to delete a dc "my-domain"
+# This delete the first level of LDAP tree.
+#
+# ldapmodify -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapdelete_sample1.txt
+
+dn: dc=my-domain,dc=com
+changetype: delete
diff --git a/dev/ldap/ldapdelete_sample3.txt b/dev/ldap/ldapdelete_sample3.txt
index 8571e16972a45cce5d5f3ccf35b9c68582e3a9f8..3d2d357d8763881e98f8fbfaff71f5e2d558261b 100644
--- a/dev/ldap/ldapdelete_sample3.txt
+++ b/dev/ldap/ldapdelete_sample3.txt
@@ -1,9 +1,9 @@
-# ldapdelete_sample3.txt
-#
-# Use this sample to delete cn records
-# This is the step to delete a cn record stored inside tree ou=contacts,dc=my-domain,dc=com
-#
-# ldapmodify -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapdelete_sample3.txt
-
-dn: cn=Bruno et Sabine Tary,ou=contacts,dc=my-domain,dc=com
-changetype: delete
+# ldapdelete_sample3.txt
+#
+# Use this sample to delete cn records
+# This is the step to delete a cn record stored inside tree ou=contacts,dc=my-domain,dc=com
+#
+# ldapmodify -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapdelete_sample3.txt
+
+dn: cn=Bruno et Sabine Tary,ou=contacts,dc=my-domain,dc=com
+changetype: delete
diff --git a/dev/ldap/ldapmodify_sample1.txt b/dev/ldap/ldapmodify_sample1.txt
index 2ecc031e62b45dcdefae4fefa1449a407938a70c..f80c6ac25b9e91940d8430f4362a5e939ea49761 100644
--- a/dev/ldap/ldapmodify_sample1.txt
+++ b/dev/ldap/ldapmodify_sample1.txt
@@ -1,14 +1,14 @@
-# ldapmodify_sample1.txt
-#
-# Use this sample to modify a dc "my-domain"
-#
-# ldapmodify -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapmodify_sample1.txt
-
-dn: dc=my-domain,dc=com
-changetype: modify
-replace: o
-objectclass: dcObject
-objectClass: organization
-objectClass: top
-dc: my-domain
+# ldapmodify_sample1.txt
+#
+# Use this sample to modify a dc "my-domain"
+#
+# ldapmodify -c -v -D cn=Manager,dc=my-domain,dc=com -W -f ldapmodify_sample1.txt
+
+dn: dc=my-domain,dc=com
+changetype: modify
+replace: o
+objectclass: dcObject
+objectClass: organization
+objectClass: top
+dc: my-domain
 o: Mon organisation
\ No newline at end of file
diff --git a/doc/dev/iso-normes/currencies_iso-4217.txt b/doc/dev/iso-normes/currencies_iso-4217.txt
index bc5653f344f66cf7397cb5e427b88ec8fdab5a15..6c0a13feff34dffcb401a24353add7ad043f1edd 100644
--- a/doc/dev/iso-normes/currencies_iso-4217.txt
+++ b/doc/dev/iso-normes/currencies_iso-4217.txt
@@ -1,168 +1,168 @@
-# File of all ISO-4217 currencies codes
-# http://en.wikipedia.org/wiki/ISO_4217
-# http://fx.sauder.ubc.ca/currency_table.html for symbols for 2 letter code
-#
-# Code,Name,Nb decimals
-AED,UAE Dirham,2
-AFN,Afghanistan Afghani,2
-ALL,Albanian Lek,2
-AMD,Armenian Dram,2
-ANG,Netherlands Antillian Guilder,2
-AOA,Angolan Kwanza,2
-ARS,Argentine Peso,2
-AUD,Australian Dollar,2
-AWG,Aruban Guilder,2
-AZM,Azerbaijanian Manat,2
-BAM,Bosnia and Herzegovina Convertible Marks,2
-BBD,Barbados Dollar,2
-BDT,Bangladesh Taka,2
-BGN,Bulgarian Lev,2
-BHD,Bahraini Dinar,3
-BIF,Burundi Franc,0
-BMD,Bermudian Dollar,2
-BND,Brunei Dollar,2
-BOB,Bolivian Boliviano,2
-BRL,Brazilian Real,2
-BSD,Bahamian Dollar,2
-BTN,Bhutan Ngultrum,2
-BWP,Botswana Pula,2
-BYR,Belarussian Ruble,0
-BZD,Belize Dollar,2
-CAD,Canadian Dollar,2
-CDF,Franc Congolais,2
-CHF,Swiss Franc,2
-CLP,Chilean Peso,0
-CNY,Chinese Yuan Renminbi,2
-COP,Colombian Peso,2
-CRC,Costa Rican Colon,2
-CSD,Serbian Dinar,2
-CUP,Cuban Peso,2
-CVE,Cape Verde Escudo,2
-CYP,Cyprus Pound,2
-CZK,Czech Koruna,2
-DJF,Djibouti Franc,0
-DKK,Danish Krone,2
-DOP,Dominican Peso,2
-DZD,Algerian Dinar,2
-EEK,Estonian Kroon,2
-EGP,Egyptian Pound,2
-ERN,Eritrea Nafka,2
-ETB,Ethiopian Birr,2
-EUR,euro,2
-FJD,Fiji Dollar,2
-FKP,Falkland Islands Pound,2
-GBP,Pound Sterling,2
-GEL,Georgian Lari,2
-GHC,Ghana Cedi,2
-GIP,Gibraltar Pound,2
-GMD,Gambian Dalasi,2
-GNF,Guinea Franc,0
-GTQ,Guatemala Quetzal,2
-GYD,Guyana Dollar,2
-HKD,Hong Kong Dollar,2
-HNL,Honduras Lempira,2
-HRK,Croatian Kuna,2
-HTG,Haiti Gourde,2
-HUF,Hungarian Forint,2
-IDR,Indonesian Rupiah,2
-ILS,New Israeli Shekel,2
-INR,Indian Rupee,2
-IQD,Iraqi Dinar,3
-IRR,Iranian Rial,2
-ISK,Iceland Krona,2
-JMD,Jamaican Dollar,2
-JOD,Jordanian Dinar,3
-JPY,Japanese Yen,0
-KES,Kenyan Shilling,2
-KGS,Kyrgyzstan Som,2
-KHR,Cambodia Riel,2
-KMF,Comoro Franc,0
-KPW,North Korean Won,2
-KRW,Korean Won,0
-KWD,Kuwaiti Dinar,3
-KYD,Cayman Islands Dollar,2
-KZT,Kazakhstan Tenge,2
-LAK,Lao Kip,2
-LBP,Lebanese Pound,2
-LKR,Sri Lanka Rupee,2
-LRD,Liberian Dollar,2
-LSL,Lesotho Loti,2
-LTL,Lithuanian Litas,2
-LVL,Latvian Lats,2
-LYD,Libyan Dinar,3
-MAD,Moroccan Dirham,2
-MDL,Moldovan Leu,2
-MGA,Malagasy Ariary,2
-MKD,Macedonian Denar,2
-MMK,Myanmar Kyat,2
-MNT,Mongolian Tugrik,2
-MOP,Macau Pataca,2
-MRO,Mauritania Ouguiya,2
-MTL,Maltese Lira,2
-MUR,Mauritius Rupee,2
-MVR,Maldives Rufiyaa,2
-MWK,Malawi Kwacha,2
-MXN,Mexican Peso,2
-MYR,Malaysian Ringgit,2
-MZM,Mozambique Metical,2
-NAD,Namibia Dollar,2
-NGN,Nigerian Naira,2
-NIO,Nicaragua Cordoba Oro,2
-NOK,Norwegian Krone,2
-NPR,Nepalese Rupee,2
-NZD,New Zealand Dollar,2
-OMR,Rial Omani,3
-PAB,Panama Balboa,2
-PEN,Peruvian Nuevo Sol,2
-PGK,Papua New Guinea Kina,2
-PHP,Philippine Peso,2
-PKR,Pakistan Rupee,2
-PLN,Polish Zloty,2
-PYG,Paraguayan Guarani,0
-QAR,Qatari Rial,2
-RON,Romanian Leu,2
-RUB,Russian Ruble,2
-RWF,Rwanda Franc,0
-SAR,Saudi Riyal,2
-SBD,Solomon Islands Dollar,2
-SCR,Seychelles Rupee,2
-SDD,Sudanese Dinar,2
-SEK,Swedish Krona,2
-SGD,Singapore Dollar,2
-SHP,St Helena Pound,2
-SIT,Slovenian Tolar,2
-SKK,Slovak Koruna,2
-SLL,Sierra Leone Leone,2
-SOS,Somali Shilling,2
-SRD,Surinam Dollar,2
-STD,S�o Tome and Principe Dobra,2
-SVC,El Salvador Colon,2
-SYP,Syrian Pound,2
-SZL,Swaziland Lilangeni,2
-THB,Thai Baht,2
-TJS,Tajik Somoni,2
-TMM,Turkmenistan Manat,2
-TND,Tunisian Dinar,3
-TOP,Tonga Pa'anga,2
-TRY,Turkish Lira,2
-TTD,Trinidad and Tobago Dollar,2
-TWD,New Taiwan Dollar,2
-TZS,Tanzanian Shilling,2
-UAH,Ukraine Hryvnia,2
-UGX,Uganda Shilling,2
-USD,US Dollar,2
-UYU,Peso Uruguayo,2
-UZS,Uzbekistan Sum,2
-VEB,Venezuelan Bolivar,2
-VND,Vietnamese Dong,2
-VUV,Vanuatu Vatu,0
-WST,Samoa Tala,2
-XAF,CFA Franc BEAC,0
-XCD,East Caribbean Dollar,2
-XDR,SDR (Special Drawing Rights),5
-XOF,CFA Franc BCEAO,0
-XPF,CFP Franc,0
-YER,Yemeni Rial,2
-ZAR,South African Rand,2
-ZMK,Zambian Kwacha,2
-ZWD,Zimbabwe Dollar,2
+# File of all ISO-4217 currencies codes
+# http://en.wikipedia.org/wiki/ISO_4217
+# http://fx.sauder.ubc.ca/currency_table.html for symbols for 2 letter code
+#
+# Code,Name,Nb decimals
+AED,UAE Dirham,2
+AFN,Afghanistan Afghani,2
+ALL,Albanian Lek,2
+AMD,Armenian Dram,2
+ANG,Netherlands Antillian Guilder,2
+AOA,Angolan Kwanza,2
+ARS,Argentine Peso,2
+AUD,Australian Dollar,2
+AWG,Aruban Guilder,2
+AZM,Azerbaijanian Manat,2
+BAM,Bosnia and Herzegovina Convertible Marks,2
+BBD,Barbados Dollar,2
+BDT,Bangladesh Taka,2
+BGN,Bulgarian Lev,2
+BHD,Bahraini Dinar,3
+BIF,Burundi Franc,0
+BMD,Bermudian Dollar,2
+BND,Brunei Dollar,2
+BOB,Bolivian Boliviano,2
+BRL,Brazilian Real,2
+BSD,Bahamian Dollar,2
+BTN,Bhutan Ngultrum,2
+BWP,Botswana Pula,2
+BYR,Belarussian Ruble,0
+BZD,Belize Dollar,2
+CAD,Canadian Dollar,2
+CDF,Franc Congolais,2
+CHF,Swiss Franc,2
+CLP,Chilean Peso,0
+CNY,Chinese Yuan Renminbi,2
+COP,Colombian Peso,2
+CRC,Costa Rican Colon,2
+CSD,Serbian Dinar,2
+CUP,Cuban Peso,2
+CVE,Cape Verde Escudo,2
+CYP,Cyprus Pound,2
+CZK,Czech Koruna,2
+DJF,Djibouti Franc,0
+DKK,Danish Krone,2
+DOP,Dominican Peso,2
+DZD,Algerian Dinar,2
+EEK,Estonian Kroon,2
+EGP,Egyptian Pound,2
+ERN,Eritrea Nafka,2
+ETB,Ethiopian Birr,2
+EUR,euro,2
+FJD,Fiji Dollar,2
+FKP,Falkland Islands Pound,2
+GBP,Pound Sterling,2
+GEL,Georgian Lari,2
+GHC,Ghana Cedi,2
+GIP,Gibraltar Pound,2
+GMD,Gambian Dalasi,2
+GNF,Guinea Franc,0
+GTQ,Guatemala Quetzal,2
+GYD,Guyana Dollar,2
+HKD,Hong Kong Dollar,2
+HNL,Honduras Lempira,2
+HRK,Croatian Kuna,2
+HTG,Haiti Gourde,2
+HUF,Hungarian Forint,2
+IDR,Indonesian Rupiah,2
+ILS,New Israeli Shekel,2
+INR,Indian Rupee,2
+IQD,Iraqi Dinar,3
+IRR,Iranian Rial,2
+ISK,Iceland Krona,2
+JMD,Jamaican Dollar,2
+JOD,Jordanian Dinar,3
+JPY,Japanese Yen,0
+KES,Kenyan Shilling,2
+KGS,Kyrgyzstan Som,2
+KHR,Cambodia Riel,2
+KMF,Comoro Franc,0
+KPW,North Korean Won,2
+KRW,Korean Won,0
+KWD,Kuwaiti Dinar,3
+KYD,Cayman Islands Dollar,2
+KZT,Kazakhstan Tenge,2
+LAK,Lao Kip,2
+LBP,Lebanese Pound,2
+LKR,Sri Lanka Rupee,2
+LRD,Liberian Dollar,2
+LSL,Lesotho Loti,2
+LTL,Lithuanian Litas,2
+LVL,Latvian Lats,2
+LYD,Libyan Dinar,3
+MAD,Moroccan Dirham,2
+MDL,Moldovan Leu,2
+MGA,Malagasy Ariary,2
+MKD,Macedonian Denar,2
+MMK,Myanmar Kyat,2
+MNT,Mongolian Tugrik,2
+MOP,Macau Pataca,2
+MRO,Mauritania Ouguiya,2
+MTL,Maltese Lira,2
+MUR,Mauritius Rupee,2
+MVR,Maldives Rufiyaa,2
+MWK,Malawi Kwacha,2
+MXN,Mexican Peso,2
+MYR,Malaysian Ringgit,2
+MZM,Mozambique Metical,2
+NAD,Namibia Dollar,2
+NGN,Nigerian Naira,2
+NIO,Nicaragua Cordoba Oro,2
+NOK,Norwegian Krone,2
+NPR,Nepalese Rupee,2
+NZD,New Zealand Dollar,2
+OMR,Rial Omani,3
+PAB,Panama Balboa,2
+PEN,Peruvian Nuevo Sol,2
+PGK,Papua New Guinea Kina,2
+PHP,Philippine Peso,2
+PKR,Pakistan Rupee,2
+PLN,Polish Zloty,2
+PYG,Paraguayan Guarani,0
+QAR,Qatari Rial,2
+RON,Romanian Leu,2
+RUB,Russian Ruble,2
+RWF,Rwanda Franc,0
+SAR,Saudi Riyal,2
+SBD,Solomon Islands Dollar,2
+SCR,Seychelles Rupee,2
+SDD,Sudanese Dinar,2
+SEK,Swedish Krona,2
+SGD,Singapore Dollar,2
+SHP,St Helena Pound,2
+SIT,Slovenian Tolar,2
+SKK,Slovak Koruna,2
+SLL,Sierra Leone Leone,2
+SOS,Somali Shilling,2
+SRD,Surinam Dollar,2
+STD,S�o Tome and Principe Dobra,2
+SVC,El Salvador Colon,2
+SYP,Syrian Pound,2
+SZL,Swaziland Lilangeni,2
+THB,Thai Baht,2
+TJS,Tajik Somoni,2
+TMM,Turkmenistan Manat,2
+TND,Tunisian Dinar,3
+TOP,Tonga Pa'anga,2
+TRY,Turkish Lira,2
+TTD,Trinidad and Tobago Dollar,2
+TWD,New Taiwan Dollar,2
+TZS,Tanzanian Shilling,2
+UAH,Ukraine Hryvnia,2
+UGX,Uganda Shilling,2
+USD,US Dollar,2
+UYU,Peso Uruguayo,2
+UZS,Uzbekistan Sum,2
+VEB,Venezuelan Bolivar,2
+VND,Vietnamese Dong,2
+VUV,Vanuatu Vatu,0
+WST,Samoa Tala,2
+XAF,CFA Franc BEAC,0
+XCD,East Caribbean Dollar,2
+XDR,SDR (Special Drawing Rights),5
+XOF,CFA Franc BCEAO,0
+XPF,CFP Franc,0
+YER,Yemeni Rial,2
+ZAR,South African Rand,2
+ZMK,Zambian Kwacha,2
+ZWD,Zimbabwe Dollar,2
diff --git a/doc/images/.cvsignore b/doc/images/.cvsignore
index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644
--- a/doc/images/.cvsignore
+++ b/doc/images/.cvsignore
@@ -1 +1 @@
-*.db
+*.db
diff --git a/htdocs/admin/cashdesk.php b/htdocs/admin/cashdesk.php
index 25adbb6595e4451c4a20a99ea07be080ac2711c7..748e34e685b5908294dda24d898c7868a591ef42 100644
--- a/htdocs/admin/cashdesk.php
+++ b/htdocs/admin/cashdesk.php
@@ -25,6 +25,7 @@
 
 require("./pre.inc.php");
 require_once(DOL_DOCUMENT_ROOT."/lib/admin.lib.php");
+require_once(DOL_DOCUMENT_ROOT."/html.formproduct.class.php");
 
 if (!$user->admin)
 accessforbidden();
@@ -49,6 +50,7 @@ if ($_POST["action"] == 'set')
  */
 
 $form=new Form($db);
+$formproduct=new FormProduct($db);
 
 llxHeader();
 
@@ -85,9 +87,8 @@ if ($conf->global->MAIN_MODULE_STOCK)
 {
 	$var=!$var;
 	print '<tr '.$bc[$var].'><td>'.$langs->trans("CashDeskIdWareHouse").'</td>';
-	print '<td colspan="2"><select class="flat" name="level">';
-	//$conf->global->CASHDESK_ID_WAREHOUSE
-	print '</select>';
+	print '<td colspan="2">';
+	$formproduct->selectWarehouses($conf->global->CASHDESK_ID_WAREHOUSE,'CASHDESK_ID_WAREHOUSE');
 	print '</td></tr>';
 }
 
diff --git a/htdocs/includes/fckeditor/.cvsignore b/htdocs/includes/fckeditor/.cvsignore
index f588dbc45b15b59d86148e2214d8abafb5b5d576..e86d54950d4063f3a0e4f53585cb81314d954f13 100644
--- a/htdocs/includes/fckeditor/.cvsignore
+++ b/htdocs/includes/fckeditor/.cvsignore
@@ -1,2 +1,2 @@
-_samples
-_testcases
+_samples
+_testcases
diff --git a/htdocs/includes/fckeditor/editor/.cvsignore b/htdocs/includes/fckeditor/editor/.cvsignore
index a5156980bc989144e7e59bae7142b68ea748cd9b..f9e18280af7a71194a65b53e9259467bdf4778f4 100644
--- a/htdocs/includes/fckeditor/editor/.cvsignore
+++ b/htdocs/includes/fckeditor/editor/.cvsignore
@@ -1 +1 @@
-_sources
+_sources
diff --git a/htdocs/includes/fpdf/fpdfi/README.txt b/htdocs/includes/fpdf/fpdfi/README.txt
index b1c69409786717270bbf1b8b3bb833128a4426c3..070304494ee2ee9d9e1c9a58c93270c0b26f2624 100644
--- a/htdocs/includes/fpdf/fpdfi/README.txt
+++ b/htdocs/includes/fpdf/fpdfi/README.txt
@@ -1,5 +1,5 @@
-This directory contains all FPDFI librairies:
-- FPDI
-- FPDI_TPL
-- FPDI_Protection
-Found on http://www.setasign.de/products/pdf-php-solutions/fpdi/
+This directory contains all FPDFI librairies:
+- FPDI
+- FPDI_TPL
+- FPDI_Protection
+Found on http://www.setasign.de/products/pdf-php-solutions/fpdi/
diff --git a/htdocs/includes/fpdf/fpdfi/decoders/ASCII85Decode.php b/htdocs/includes/fpdf/fpdfi/decoders/ASCII85Decode.php
index 02191dc2c424e0743574f22f3453a91af036a81c..6bf53fb1b24c9d034e9b0e4320fd9c3755176d5b 100644
--- a/htdocs/includes/fpdf/fpdfi/decoders/ASCII85Decode.php
+++ b/htdocs/includes/fpdf/fpdfi/decoders/ASCII85Decode.php
@@ -1,97 +1,97 @@
-<?php
-//
-//  FPDI - Version 1.2
-//
-//    Copyright 2004-2007 Setasign - Jan Slabon
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-if (!defined("ORD_z"))
-	define("ORD_z",ord('z'));
-if (!defined("ORD_exclmark"))
-	define("ORD_exclmark", ord('!'));
-if (!defined("ORD_u"))	
-	define("ORD_u", ord("u"));
-if (!defined("ORD_tilde"))
-	define("ORD_tilde", ord('~'));
-
-class ASCII85Decode {
-
-    function ASCII85Decode(&$fpdi) {
-        $this->fpdi =& $fpdi;
-    }
-
-
-    function decode($in) {
-        $out = "";
-        $state = 0;
-        $chn = null;
-        
-        $l = strlen($in);
-        
-        for ($k = 0; $k < $l; ++$k) {
-            $ch = ord($in[$k]) & 0xff;
-            
-            if ($ch == ORD_tilde) {
-                break;
-            }
-            if (preg_match("/^\s$/",chr($ch))) {
-                continue;
-            }
-            if ($ch == ORD_z && $state == 0) {
-                $out .= chr(0).chr(0).chr(0).chr(0);
-                continue;
-            }
-            if ($ch < ORD_exclmark || $ch > ORD_u) {
-                $this->fpdi->error("Illegal character in ASCII85Decode.");
-            }
-            
-            $chn[$state++] = $ch - ORD_exclmark;
-            
-            if ($state == 5) {
-                $state = 0;
-                $r = 0;
-                for ($j = 0; $j < 5; ++$j)
-                    $r = $r * 85 + $chn[$j];
-                $out .= chr($r >> 24);
-                $out .= chr($r >> 16);
-                $out .= chr($r >> 8);
-                $out .= chr($r);
-            }
-        }
-        $r = 0;
-        
-        if ($state == 1)
-            $this->fpdi->error("Illegal length in ASCII85Decode.");
-        if ($state == 2) {
-            $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1]+1) * 85 * 85 * 85;
-            $out .= chr($r >> 24);
-        }
-        else if ($state == 3) {
-            $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85  + ($chn[2]+1) * 85 * 85;
-            $out .= chr($r >> 24);
-            $out .= chr($r >> 16);
-        }
-        else if ($state == 4) {
-            $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85  + $chn[2] * 85 * 85  + ($chn[3]+1) * 85 ;
-            $out .= chr($r >> 24);
-            $out .= chr($r >> 16);
-            $out .= chr($r >> 8);
-        }
-
-        return $out;
-    }
-}
-
+<?php
+//
+//  FPDI - Version 1.2
+//
+//    Copyright 2004-2007 Setasign - Jan Slabon
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+if (!defined("ORD_z"))
+	define("ORD_z",ord('z'));
+if (!defined("ORD_exclmark"))
+	define("ORD_exclmark", ord('!'));
+if (!defined("ORD_u"))	
+	define("ORD_u", ord("u"));
+if (!defined("ORD_tilde"))
+	define("ORD_tilde", ord('~'));
+
+class ASCII85Decode {
+
+    function ASCII85Decode(&$fpdi) {
+        $this->fpdi =& $fpdi;
+    }
+
+
+    function decode($in) {
+        $out = "";
+        $state = 0;
+        $chn = null;
+        
+        $l = strlen($in);
+        
+        for ($k = 0; $k < $l; ++$k) {
+            $ch = ord($in[$k]) & 0xff;
+            
+            if ($ch == ORD_tilde) {
+                break;
+            }
+            if (preg_match("/^\s$/",chr($ch))) {
+                continue;
+            }
+            if ($ch == ORD_z && $state == 0) {
+                $out .= chr(0).chr(0).chr(0).chr(0);
+                continue;
+            }
+            if ($ch < ORD_exclmark || $ch > ORD_u) {
+                $this->fpdi->error("Illegal character in ASCII85Decode.");
+            }
+            
+            $chn[$state++] = $ch - ORD_exclmark;
+            
+            if ($state == 5) {
+                $state = 0;
+                $r = 0;
+                for ($j = 0; $j < 5; ++$j)
+                    $r = $r * 85 + $chn[$j];
+                $out .= chr($r >> 24);
+                $out .= chr($r >> 16);
+                $out .= chr($r >> 8);
+                $out .= chr($r);
+            }
+        }
+        $r = 0;
+        
+        if ($state == 1)
+            $this->fpdi->error("Illegal length in ASCII85Decode.");
+        if ($state == 2) {
+            $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1]+1) * 85 * 85 * 85;
+            $out .= chr($r >> 24);
+        }
+        else if ($state == 3) {
+            $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85  + ($chn[2]+1) * 85 * 85;
+            $out .= chr($r >> 24);
+            $out .= chr($r >> 16);
+        }
+        else if ($state == 4) {
+            $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85  + $chn[2] * 85 * 85  + ($chn[3]+1) * 85 ;
+            $out .= chr($r >> 24);
+            $out .= chr($r >> 16);
+            $out .= chr($r >> 8);
+        }
+
+        return $out;
+    }
+}
+
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/fpdf/fpdfi/decoders/LZWDecode.php b/htdocs/includes/fpdf/fpdfi/decoders/LZWDecode.php
index b3b41c72215d8ad6d9ed975049885d0dbc4f864a..75d19e0261777d50bd4ffef26f3c518db250ad94 100644
--- a/htdocs/includes/fpdf/fpdfi/decoders/LZWDecode.php
+++ b/htdocs/includes/fpdf/fpdfi/decoders/LZWDecode.php
@@ -1,151 +1,151 @@
-<?php
-//
-//  FPDI - Version 1.2
-//
-//    Copyright 2004-2007 Setasign - Jan Slabon
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-class LZWDecode {
-
-    var $sTable = array();
-    var $data = null;
-    var $tIdx;
-    var $bitsToGet = 9;
-    var $bytePointer;
-    var $bitPointer;
-    var $nextData = 0;
-    var $nextBits = 0;
-    var $andTable = array(511, 1023, 2047, 4095);
-
-    function LZWDecode(&$fpdi) {
-        $this->fpdi =& $fpdi;
-    }
-
-    /**
-     * Method to decode LZW compressed data.
-     *
-     * @param string data    The compressed data.
-     */
-    function decode(&$data) {
-
-        if($data[0] == 0x00 && $data[1] == 0x01) {
-            $this->fpdi->error("LZW flavour not supported.");
-        }
-
-        $this->initsTable();
-
-        $this->data =& $data;
-
-        // Initialize pointers
-        $this->bytePointer = 0;
-        $this->bitPointer = 0;
-
-        $this->nextData = 0;
-        $this->nextBits = 0;
-
-        $oldCode = 0;
-
-        $string = "";
-        $uncompData = "";
-
-        while (($code = $this->getNextCode()) != 257) {
-            if ($code == 256) {
-                $this->initsTable();
-                $code = $this->getNextCode();
-
-                if ($code == 257) {
-                    break;
-                }
-
-                $uncompData .= $this->sTable[$code];
-                $oldCode = $code;
-
-            } else {
-
-                if ($code < $this->tIdx) {
-                    $string = $this->sTable[$code];
-                    $uncompData .= $string;
-
-                    $this->addStringToTable($this->sTable[$oldCode], $string[0]);
-                    $oldCode = $code;
-                } else {
-                    $string = $this->sTable[$oldCode];
-                    $string = $string.$string[0];
-                    $uncompData .= $string;
-
-                    $this->addStringToTable($string);
-                    $oldCode = $code;
-                }
-            }
-        }
-        
-        return $uncompData;
-    }
-
-
-    /**
-     * Initialize the string table.
-     */
-    function initsTable() {
-        $this->sTable = array();
-
-        for ($i = 0; $i < 256; $i++)
-            $this->sTable[$i] = chr($i);
-
-        $this->tIdx = 258;
-        $this->bitsToGet = 9;
-    }
-
-    /**
-     * Add a new string to the string table.
-     */
-    function addStringToTable ($oldString, $newString="") {
-        $string = $oldString.$newString;
-
-        // Add this new String to the table
-        $this->sTable[$this->tIdx++] = $string;
-
-        if ($this->tIdx == 511) {
-            $this->bitsToGet = 10;
-        } else if ($this->tIdx == 1023) {
-            $this->bitsToGet = 11;
-        } else if ($this->tIdx == 2047) {
-            $this->bitsToGet = 12;
-        }
-    }
-
-    // Returns the next 9, 10, 11 or 12 bits
-    function getNextCode() {
-        if ($this->bytePointer == strlen($this->data))
-            return 257;
-
-        $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
-        $this->nextBits += 8;
-
-        if ($this->nextBits < $this->bitsToGet) {
-            $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
-            $this->nextBits += 8;
-        }
-
-        $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet-9];
-        $this->nextBits -= $this->bitsToGet;
-
-        return $code;
-    }
-}
-
-
-
+<?php
+//
+//  FPDI - Version 1.2
+//
+//    Copyright 2004-2007 Setasign - Jan Slabon
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+class LZWDecode {
+
+    var $sTable = array();
+    var $data = null;
+    var $tIdx;
+    var $bitsToGet = 9;
+    var $bytePointer;
+    var $bitPointer;
+    var $nextData = 0;
+    var $nextBits = 0;
+    var $andTable = array(511, 1023, 2047, 4095);
+
+    function LZWDecode(&$fpdi) {
+        $this->fpdi =& $fpdi;
+    }
+
+    /**
+     * Method to decode LZW compressed data.
+     *
+     * @param string data    The compressed data.
+     */
+    function decode(&$data) {
+
+        if($data[0] == 0x00 && $data[1] == 0x01) {
+            $this->fpdi->error("LZW flavour not supported.");
+        }
+
+        $this->initsTable();
+
+        $this->data =& $data;
+
+        // Initialize pointers
+        $this->bytePointer = 0;
+        $this->bitPointer = 0;
+
+        $this->nextData = 0;
+        $this->nextBits = 0;
+
+        $oldCode = 0;
+
+        $string = "";
+        $uncompData = "";
+
+        while (($code = $this->getNextCode()) != 257) {
+            if ($code == 256) {
+                $this->initsTable();
+                $code = $this->getNextCode();
+
+                if ($code == 257) {
+                    break;
+                }
+
+                $uncompData .= $this->sTable[$code];
+                $oldCode = $code;
+
+            } else {
+
+                if ($code < $this->tIdx) {
+                    $string = $this->sTable[$code];
+                    $uncompData .= $string;
+
+                    $this->addStringToTable($this->sTable[$oldCode], $string[0]);
+                    $oldCode = $code;
+                } else {
+                    $string = $this->sTable[$oldCode];
+                    $string = $string.$string[0];
+                    $uncompData .= $string;
+
+                    $this->addStringToTable($string);
+                    $oldCode = $code;
+                }
+            }
+        }
+        
+        return $uncompData;
+    }
+
+
+    /**
+     * Initialize the string table.
+     */
+    function initsTable() {
+        $this->sTable = array();
+
+        for ($i = 0; $i < 256; $i++)
+            $this->sTable[$i] = chr($i);
+
+        $this->tIdx = 258;
+        $this->bitsToGet = 9;
+    }
+
+    /**
+     * Add a new string to the string table.
+     */
+    function addStringToTable ($oldString, $newString="") {
+        $string = $oldString.$newString;
+
+        // Add this new String to the table
+        $this->sTable[$this->tIdx++] = $string;
+
+        if ($this->tIdx == 511) {
+            $this->bitsToGet = 10;
+        } else if ($this->tIdx == 1023) {
+            $this->bitsToGet = 11;
+        } else if ($this->tIdx == 2047) {
+            $this->bitsToGet = 12;
+        }
+    }
+
+    // Returns the next 9, 10, 11 or 12 bits
+    function getNextCode() {
+        if ($this->bytePointer == strlen($this->data))
+            return 257;
+
+        $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
+        $this->nextBits += 8;
+
+        if ($this->nextBits < $this->bitsToGet) {
+            $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff);
+            $this->nextBits += 8;
+        }
+
+        $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet-9];
+        $this->nextBits -= $this->bitsToGet;
+
+        return $code;
+    }
+}
+
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/fpdf/fpdfi/fpdf_tpl.php b/htdocs/includes/fpdf/fpdfi/fpdf_tpl.php
index bfbe066b7f749d2ef4814418674301bc1f5b0602..ee9722c32987b2c02eab2e53d27fd12f64749dd1 100644
--- a/htdocs/includes/fpdf/fpdfi/fpdf_tpl.php
+++ b/htdocs/includes/fpdf/fpdfi/fpdf_tpl.php
@@ -1,385 +1,385 @@
-<?php
-//
-//  FPDF_TPL - Version 1.1.1
-//
-//    Copyright 2004-2007 Setasign - Jan Slabon
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-require_once(FPDF_PATH."fpdf.php");
-
-class FPDF_TPL extends FPDF {
-    /**
-     * Array of Tpl-Data
-     * @var array
-     */
-    var $tpls = array();
-
-    /**
-     * Current Template-ID
-     * @var int
-     */
-    var $tpl = 0;
-    
-    /**
-     * "In Template"-Flag
-     * @var boolean
-     */
-    var $_intpl = false;
-    
-    /**
-     * Nameprefix of Templates used in Resources-Dictonary
-     * @var string A String defining the Prefix used as Template-Object-Names. Have to beginn with an /
-     */
-    var $tplprefix = "/TPL";
-
-    /**
-     * Resources used By Templates and Pages
-     * @var array
-     */
-    var $_res = array();
-    
-    /**
-     * Constructor
-     * See FPDF-Documentation
-     * @param string $orientation
-     * @param string $unit
-     * @param mixed $format
-     */
-    function fpdf_tpl($orientation='P',$unit='mm',$format='A4') {
-        parent::fpdf($orientation,$unit,$format);
-    }
-    
-    /**
-     * Start a Template
-     *
-     * This method starts a template. You can give own coordinates to build an own sized
-     * Template. Pay attention, that the margins are adapted to the new templatesize.
-     * If you want to write outside the template, for example to build a clipped Template,
-     * you have to set the Margins and "Cursor"-Position manual after beginTemplate-Call.
-     *
-     * If no parameter is given, the template uses the current page-size.
-     * The Method returns an ID of the current Template. This ID is used later for using this template.
-     * Warning: A created Template is used in PDF at all events. Still if you don't use it after creation!
-     *
-     * @param int $x The x-coordinate given in user-unit
-     * @param int $y The y-coordinate given in user-unit
-     * @param int $w The width given in user-unit
-     * @param int $h The height given in user-unit
-     * @return int The ID of new created Template
-     */
-    function beginTemplate($x=null,$y=null,$w=null,$h=null) {
-        if ($this->page <= 0)
-            $this->error("You have to add a page to fpdf first!");
-
-        if ($x == null)
-            $x = 0;
-        if ($y == null)
-            $y = 0;
-        if ($w == null)
-            $w = $this->w;
-        if ($h == null)
-            $h = $this->h;
-
-        // Save settings
-        $this->tpl++;
-        $tpl =& $this->tpls[$this->tpl];
-        $tpl = array(
-            'o_x' => $this->x,
-            'o_y' => $this->y,
-            'o_AutoPageBreak' => $this->AutoPageBreak,
-            'o_bMargin' => $this->bMargin,
-            'o_tMargin' => $this->tMargin,
-            'o_lMargin' => $this->lMargin,
-            'o_rMargin' => $this->rMargin,
-            'o_h' => $this->h,
-            'o_w' => $this->w,
-            'buffer' => '',
-            'x' => $x,
-            'y' => $y,
-            'w' => $w,
-            'h' => $h
-        );
-
-        $this->SetAutoPageBreak(false);
-        
-        // Define own high and width to calculate possitions correct
-        $this->h = $h;
-        $this->w = $w;
-
-        $this->_intpl = true;
-        $this->SetXY($x+$this->lMargin,$y+$this->tMargin);
-        $this->SetRightMargin($this->w-$w+$this->rMargin);
-
-        return $this->tpl;
-    }
-    
-    /**
-     * End Template
-     *
-     * This method ends a template and reset initiated variables on beginTemplate.
-     *
-     * @return mixed If a template is opened, the ID is returned. If not a false is returned.
-     */
-    function endTemplate() {
-        if ($this->_intpl) {
-            $this->_intpl = false; 
-            $tpl =& $this->tpls[$this->tpl];
-            $this->SetXY($tpl['o_x'], $tpl['o_y']);
-            $this->tMargin = $tpl['o_tMargin'];
-            $this->lMargin = $tpl['o_lMargin'];
-            $this->rMargin = $tpl['o_rMargin'];
-            $this->h = $tpl['o_h'];
-            $this->w = $tpl['o_w'];
-            $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']);
-            
-            return $this->tpl;
-        } else {
-            return false;
-        }
-    }
-    
-    /**
-     * Use a Template in current Page or other Template
-     *
-     * You can use a template in a page or in another template.
-     * You can give the used template a new size like you use the Image()-method.
-     * All parameters are optional. The width or height is calculated automaticaly
-     * if one is given. If no parameter is given the origin size as defined in
-     * beginTemplate() is used.
-     * The calculated or used width and height are returned as an array.
-     *
-     * @param int $tplidx A valid template-Id
-     * @param int $_x The x-position
-     * @param int $_y The y-position
-     * @param int $_w The new width of the template
-     * @param int $_h The new height of the template
-     * @retrun array The height and width of the template
-     */
-    function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
-        if ($this->page <= 0)
-            $this->error("You have to add a page to fpdf first!");
-
-        if (!isset($this->tpls[$tplidx]))
-            $this->error("Template does not exist!");
-            
-        if ($this->_intpl) {
-            $this->_res['tpl'][$this->tpl]['tpls'][$tplidx] =& $this->tpls[$tplidx];
-        }
-        
-        $tpl =& $this->tpls[$tplidx];
-        $x = $tpl['x'];
-        $y = $tpl['y'];
-        $w = $tpl['w'];
-        $h = $tpl['h'];
-        
-        if ($_x == null)
-            $_x = $x;
-        if ($_y == null)
-            $_y = $y;
-        $wh = $this->getTemplateSize($tplidx,$_w,$_h);
-        $_w = $wh['w'];
-        $_h = $wh['h'];
-    
-        $this->_out(sprintf("q %.4f 0 0 %.4f %.2f %.2f cm", ($_w/$w), ($_h/$h), $_x*$this->k, ($this->h-($_y+$_h))*$this->k)); // Translate 
-        $this->_out($this->tplprefix.$tplidx." Do Q");
-
-        return array("w" => $_w, "h" => $_h);
-    }
-    
-    /**
-     * Get The calculated Size of a Template
-     *
-     * If one size is given, this method calculates the other one.
-     *
-     * @param int $tplidx A valid template-Id
-     * @param int $_w The width of the template
-     * @param int $_h The height of the template
-     * @return array The height and width of the template
-     */
-    function getTemplateSize($tplidx, $_w=0, $_h=0) {
-        if (!$this->tpls[$tplidx])
-            return false;
-
-        $tpl =& $this->tpls[$tplidx];
-        $w = $tpl['w'];
-        $h = $tpl['h'];
-        
-        if ($_w == 0 and $_h == 0) {
-            $_w = $w;
-            $_h = $h;
-        }
-
-    	if($_w==0)
-    		$_w=$_h*$w/$h;
-    	if($_h==0)
-    		$_h=$_w*$h/$w;
-    		
-        return array("w" => $_w, "h" => $_h);
-    }
-    
-    /**
-     * See FPDF-Documentation ;-)
-     */
-    function SetFont($family,$style='',$size=0) {
-        /**
-         * force the resetting of font changes in a template
-         */
-        if ($this->_intpl)
-            $this->FontFamily = '';
-            
-        parent::SetFont($family, $style, $size);
-       
-        $fontkey = $this->FontFamily.$this->FontStyle;
-        
-        if ($this->_intpl) {
-            $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey];
-        } else {
-            $this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey];
-        }
-    }
-    
-    /**
-     * See FPDF-Documentation ;-)
-     */
-    function Image($file,$x,$y,$w=0,$h=0,$type='',$link='') {
-        parent::Image($file,$x,$y,$w,$h,$type,$link);
-        if ($this->_intpl) {
-            $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file];
-        } else {
-            $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file];
-        }
-    }
-    
-    /**
-     * See FPDF-Documentation ;-)
-     *
-     * AddPage is not available when you're "in" a template.
-     */
-    function AddPage($orientation='') {
-        if ($this->_intpl)
-            $this->Error('Adding pages in templates isn\'t possible!');
-        parent::AddPage($orientation);
-    }
-
-    /**
-     * Preserve adding Links in Templates ...won't work
-     */
-    function Link($x,$y,$w,$h,$link) {
-        if ($this->_intpl)
-            $this->Error('Using links in templates aren\'t possible!');
-        parent::Link($x,$y,$w,$h,$link);
-    }
-    
-    function AddLink() {
-        if ($this->_intpl)
-            $this->Error('Adding links in templates aren\'t possible!');
-        return parent::AddLink();
-    }
-    
-    function SetLink($link,$y=0,$page=-1) {
-        if ($this->_intpl)
-            $this->Error('Setting links in templates aren\'t possible!');
-        parent::SetLink($link,$y,$page);
-    }
-    
-    /**
-     * Private Method that writes the form xobjects
-     */
-    function _putformxobjects() {
-        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
-	    reset($this->tpls);
-        foreach($this->tpls AS $tplidx => $tpl) {
-
-            $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
-    		$this->_newobj();
-    		$this->tpls[$tplidx]['n'] = $this->n;
-    		$this->_out('<<'.$filter.'/Type /XObject');
-            $this->_out('/Subtype /Form');
-            $this->_out('/FormType 1');
-            $this->_out(sprintf('/BBox [%.2f %.2f %.2f %.2f]',$tpl['x']*$this->k, ($tpl['h']-$tpl['y'])*$this->k, $tpl['w']*$this->k, ($tpl['h']-$tpl['y']-$tpl['h'])*$this->k));
-            $this->_out('/Resources ');
-
-            $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
-        	if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
-            	$this->_out('/Font <<');
-                foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
-            		$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
-            	$this->_out('>>');
-            }
-        	if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || 
-        	   isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
-        	{
-                $this->_out('/XObject <<');
-                if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
-                    foreach($this->_res['tpl'][$tplidx]['images'] as $image)
-              			$this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
-                }
-                if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
-                    foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl)
-                        $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R');
-                }
-                $this->_out('>>');
-        	}
-        	$this->_out('>>');
-        	
-        	$this->_out('/Length '.strlen($p).' >>');
-    		$this->_putstream($p);
-    		$this->_out('endobj');
-        }
-    }
-    
-    /**
-     * Private Method
-     */
-    function _putresources() {
-        $this->_putfonts();
-    	$this->_putimages();
-    	$this->_putformxobjects();
-        //Resource dictionary
-    	$this->offsets[2]=strlen($this->buffer);
-    	$this->_out('2 0 obj');
-    	$this->_out('<<');
-    	$this->_putresourcedict();
-    	$this->_out('>>');
-    	$this->_out('endobj');
-    }
-    
-    function _putxobjectdict() {
-        parent::_putxobjectdict();
-        
-        if (count($this->tpls)) {
-            foreach($this->tpls as $tplidx => $tpl) {
-                $this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R');
-            }
-        }
-    }
-
-    /**
-     * Private Method
-     */
-    function _out($s) {
-	   //Add a line to the document
-	   if ($this->state==2) {
-           if (!$this->_intpl)
-	           $this->pages[$this->page].=$s."\n";
-           else
-               $this->tpls[$this->tpl]['buffer'] .= $s."\n";
-       } else {
-		   $this->buffer.=$s."\n";
-       }
-    }
-}
-
+<?php
+//
+//  FPDF_TPL - Version 1.1.1
+//
+//    Copyright 2004-2007 Setasign - Jan Slabon
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+require_once(FPDF_PATH."fpdf.php");
+
+class FPDF_TPL extends FPDF {
+    /**
+     * Array of Tpl-Data
+     * @var array
+     */
+    var $tpls = array();
+
+    /**
+     * Current Template-ID
+     * @var int
+     */
+    var $tpl = 0;
+    
+    /**
+     * "In Template"-Flag
+     * @var boolean
+     */
+    var $_intpl = false;
+    
+    /**
+     * Nameprefix of Templates used in Resources-Dictonary
+     * @var string A String defining the Prefix used as Template-Object-Names. Have to beginn with an /
+     */
+    var $tplprefix = "/TPL";
+
+    /**
+     * Resources used By Templates and Pages
+     * @var array
+     */
+    var $_res = array();
+    
+    /**
+     * Constructor
+     * See FPDF-Documentation
+     * @param string $orientation
+     * @param string $unit
+     * @param mixed $format
+     */
+    function fpdf_tpl($orientation='P',$unit='mm',$format='A4') {
+        parent::fpdf($orientation,$unit,$format);
+    }
+    
+    /**
+     * Start a Template
+     *
+     * This method starts a template. You can give own coordinates to build an own sized
+     * Template. Pay attention, that the margins are adapted to the new templatesize.
+     * If you want to write outside the template, for example to build a clipped Template,
+     * you have to set the Margins and "Cursor"-Position manual after beginTemplate-Call.
+     *
+     * If no parameter is given, the template uses the current page-size.
+     * The Method returns an ID of the current Template. This ID is used later for using this template.
+     * Warning: A created Template is used in PDF at all events. Still if you don't use it after creation!
+     *
+     * @param int $x The x-coordinate given in user-unit
+     * @param int $y The y-coordinate given in user-unit
+     * @param int $w The width given in user-unit
+     * @param int $h The height given in user-unit
+     * @return int The ID of new created Template
+     */
+    function beginTemplate($x=null,$y=null,$w=null,$h=null) {
+        if ($this->page <= 0)
+            $this->error("You have to add a page to fpdf first!");
+
+        if ($x == null)
+            $x = 0;
+        if ($y == null)
+            $y = 0;
+        if ($w == null)
+            $w = $this->w;
+        if ($h == null)
+            $h = $this->h;
+
+        // Save settings
+        $this->tpl++;
+        $tpl =& $this->tpls[$this->tpl];
+        $tpl = array(
+            'o_x' => $this->x,
+            'o_y' => $this->y,
+            'o_AutoPageBreak' => $this->AutoPageBreak,
+            'o_bMargin' => $this->bMargin,
+            'o_tMargin' => $this->tMargin,
+            'o_lMargin' => $this->lMargin,
+            'o_rMargin' => $this->rMargin,
+            'o_h' => $this->h,
+            'o_w' => $this->w,
+            'buffer' => '',
+            'x' => $x,
+            'y' => $y,
+            'w' => $w,
+            'h' => $h
+        );
+
+        $this->SetAutoPageBreak(false);
+        
+        // Define own high and width to calculate possitions correct
+        $this->h = $h;
+        $this->w = $w;
+
+        $this->_intpl = true;
+        $this->SetXY($x+$this->lMargin,$y+$this->tMargin);
+        $this->SetRightMargin($this->w-$w+$this->rMargin);
+
+        return $this->tpl;
+    }
+    
+    /**
+     * End Template
+     *
+     * This method ends a template and reset initiated variables on beginTemplate.
+     *
+     * @return mixed If a template is opened, the ID is returned. If not a false is returned.
+     */
+    function endTemplate() {
+        if ($this->_intpl) {
+            $this->_intpl = false; 
+            $tpl =& $this->tpls[$this->tpl];
+            $this->SetXY($tpl['o_x'], $tpl['o_y']);
+            $this->tMargin = $tpl['o_tMargin'];
+            $this->lMargin = $tpl['o_lMargin'];
+            $this->rMargin = $tpl['o_rMargin'];
+            $this->h = $tpl['o_h'];
+            $this->w = $tpl['o_w'];
+            $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']);
+            
+            return $this->tpl;
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Use a Template in current Page or other Template
+     *
+     * You can use a template in a page or in another template.
+     * You can give the used template a new size like you use the Image()-method.
+     * All parameters are optional. The width or height is calculated automaticaly
+     * if one is given. If no parameter is given the origin size as defined in
+     * beginTemplate() is used.
+     * The calculated or used width and height are returned as an array.
+     *
+     * @param int $tplidx A valid template-Id
+     * @param int $_x The x-position
+     * @param int $_y The y-position
+     * @param int $_w The new width of the template
+     * @param int $_h The new height of the template
+     * @retrun array The height and width of the template
+     */
+    function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
+        if ($this->page <= 0)
+            $this->error("You have to add a page to fpdf first!");
+
+        if (!isset($this->tpls[$tplidx]))
+            $this->error("Template does not exist!");
+            
+        if ($this->_intpl) {
+            $this->_res['tpl'][$this->tpl]['tpls'][$tplidx] =& $this->tpls[$tplidx];
+        }
+        
+        $tpl =& $this->tpls[$tplidx];
+        $x = $tpl['x'];
+        $y = $tpl['y'];
+        $w = $tpl['w'];
+        $h = $tpl['h'];
+        
+        if ($_x == null)
+            $_x = $x;
+        if ($_y == null)
+            $_y = $y;
+        $wh = $this->getTemplateSize($tplidx,$_w,$_h);
+        $_w = $wh['w'];
+        $_h = $wh['h'];
+    
+        $this->_out(sprintf("q %.4f 0 0 %.4f %.2f %.2f cm", ($_w/$w), ($_h/$h), $_x*$this->k, ($this->h-($_y+$_h))*$this->k)); // Translate 
+        $this->_out($this->tplprefix.$tplidx." Do Q");
+
+        return array("w" => $_w, "h" => $_h);
+    }
+    
+    /**
+     * Get The calculated Size of a Template
+     *
+     * If one size is given, this method calculates the other one.
+     *
+     * @param int $tplidx A valid template-Id
+     * @param int $_w The width of the template
+     * @param int $_h The height of the template
+     * @return array The height and width of the template
+     */
+    function getTemplateSize($tplidx, $_w=0, $_h=0) {
+        if (!$this->tpls[$tplidx])
+            return false;
+
+        $tpl =& $this->tpls[$tplidx];
+        $w = $tpl['w'];
+        $h = $tpl['h'];
+        
+        if ($_w == 0 and $_h == 0) {
+            $_w = $w;
+            $_h = $h;
+        }
+
+    	if($_w==0)
+    		$_w=$_h*$w/$h;
+    	if($_h==0)
+    		$_h=$_w*$h/$w;
+    		
+        return array("w" => $_w, "h" => $_h);
+    }
+    
+    /**
+     * See FPDF-Documentation ;-)
+     */
+    function SetFont($family,$style='',$size=0) {
+        /**
+         * force the resetting of font changes in a template
+         */
+        if ($this->_intpl)
+            $this->FontFamily = '';
+            
+        parent::SetFont($family, $style, $size);
+       
+        $fontkey = $this->FontFamily.$this->FontStyle;
+        
+        if ($this->_intpl) {
+            $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey];
+        } else {
+            $this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey];
+        }
+    }
+    
+    /**
+     * See FPDF-Documentation ;-)
+     */
+    function Image($file,$x,$y,$w=0,$h=0,$type='',$link='') {
+        parent::Image($file,$x,$y,$w,$h,$type,$link);
+        if ($this->_intpl) {
+            $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file];
+        } else {
+            $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file];
+        }
+    }
+    
+    /**
+     * See FPDF-Documentation ;-)
+     *
+     * AddPage is not available when you're "in" a template.
+     */
+    function AddPage($orientation='') {
+        if ($this->_intpl)
+            $this->Error('Adding pages in templates isn\'t possible!');
+        parent::AddPage($orientation);
+    }
+
+    /**
+     * Preserve adding Links in Templates ...won't work
+     */
+    function Link($x,$y,$w,$h,$link) {
+        if ($this->_intpl)
+            $this->Error('Using links in templates aren\'t possible!');
+        parent::Link($x,$y,$w,$h,$link);
+    }
+    
+    function AddLink() {
+        if ($this->_intpl)
+            $this->Error('Adding links in templates aren\'t possible!');
+        return parent::AddLink();
+    }
+    
+    function SetLink($link,$y=0,$page=-1) {
+        if ($this->_intpl)
+            $this->Error('Setting links in templates aren\'t possible!');
+        parent::SetLink($link,$y,$page);
+    }
+    
+    /**
+     * Private Method that writes the form xobjects
+     */
+    function _putformxobjects() {
+        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
+	    reset($this->tpls);
+        foreach($this->tpls AS $tplidx => $tpl) {
+
+            $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
+    		$this->_newobj();
+    		$this->tpls[$tplidx]['n'] = $this->n;
+    		$this->_out('<<'.$filter.'/Type /XObject');
+            $this->_out('/Subtype /Form');
+            $this->_out('/FormType 1');
+            $this->_out(sprintf('/BBox [%.2f %.2f %.2f %.2f]',$tpl['x']*$this->k, ($tpl['h']-$tpl['y'])*$this->k, $tpl['w']*$this->k, ($tpl['h']-$tpl['y']-$tpl['h'])*$this->k));
+            $this->_out('/Resources ');
+
+            $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
+        	if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
+            	$this->_out('/Font <<');
+                foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
+            		$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
+            	$this->_out('>>');
+            }
+        	if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || 
+        	   isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
+        	{
+                $this->_out('/XObject <<');
+                if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
+                    foreach($this->_res['tpl'][$tplidx]['images'] as $image)
+              			$this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
+                }
+                if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
+                    foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl)
+                        $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R');
+                }
+                $this->_out('>>');
+        	}
+        	$this->_out('>>');
+        	
+        	$this->_out('/Length '.strlen($p).' >>');
+    		$this->_putstream($p);
+    		$this->_out('endobj');
+        }
+    }
+    
+    /**
+     * Private Method
+     */
+    function _putresources() {
+        $this->_putfonts();
+    	$this->_putimages();
+    	$this->_putformxobjects();
+        //Resource dictionary
+    	$this->offsets[2]=strlen($this->buffer);
+    	$this->_out('2 0 obj');
+    	$this->_out('<<');
+    	$this->_putresourcedict();
+    	$this->_out('>>');
+    	$this->_out('endobj');
+    }
+    
+    function _putxobjectdict() {
+        parent::_putxobjectdict();
+        
+        if (count($this->tpls)) {
+            foreach($this->tpls as $tplidx => $tpl) {
+                $this->_out($this->tplprefix.$tplidx.' '.$tpl['n'].' 0 R');
+            }
+        }
+    }
+
+    /**
+     * Private Method
+     */
+    function _out($s) {
+	   //Add a line to the document
+	   if ($this->state==2) {
+           if (!$this->_intpl)
+	           $this->pages[$this->page].=$s."\n";
+           else
+               $this->tpls[$this->tpl]['buffer'] .= $s."\n";
+       } else {
+		   $this->buffer.=$s."\n";
+       }
+    }
+}
+
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/fpdf/fpdfi/fpdi.php b/htdocs/includes/fpdf/fpdfi/fpdi.php
index 1c4b572a47bf5816107231fc1b695ddc5ae62d0f..01eb1c031feb88b4aed6d5d8e46aabed5666da5b 100644
--- a/htdocs/includes/fpdf/fpdfi/fpdi.php
+++ b/htdocs/includes/fpdf/fpdfi/fpdi.php
@@ -1,466 +1,466 @@
-<?php
-//
-//  FPDI - Version 1.2
-//
-//    Copyright 2004-2007 Setasign - Jan Slabon
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-define('FPDI_VERSION','1.2');
-
-ini_set('auto_detect_line_endings',1); // Strongly required!
-
-require_once("fpdf_tpl.php");
-require_once("fpdi_pdf_parser.php");
-
-
-class FPDI extends FPDF_TPL {
-    /**
-     * Actual filename
-     * @var string
-     */
-    var $current_filename;
-
-    /**
-     * Parser-Objects
-     * @var array
-     */
-    var $parsers;
-    
-    /**
-     * Current parser
-     * @var object
-     */
-    var $current_parser;
-    
-    /**
-     * Highest version of imported PDF
-     * @var double
-     */
-    var $importVersion = 1.3;
-
-    /**
-     * object stack
-     * @var array
-     */
-    var $_obj_stack;
-    
-    /**
-     * done object stack
-     * @var array
-     */
-    var $_don_obj_stack;
-
-    /**
-     * Current Object Id.
-     * @var integer
-     */
-    var $_current_obj_id;
-    
-    /**
-     * The name of the last imported page box
-     * @var string
-     */
-    var $lastUsedPageBox;
-    
-    /**
-     * Constructor
-     * See FPDF-Manual
-     */
-    function FPDI($orientation='P',$unit='mm',$format='A4') {
-        parent::FPDF_TPL($orientation,$unit,$format);
-    }
-    
-    /**
-     * Set a source-file
-     *
-     * @param string $filename a valid filename
-     * @return int number of available pages
-     */
-    function setSourceFile($filename) {
-        $this->current_filename = $filename;
-        $fn =& $this->current_filename;
-
-        if (!isset($this->parsers[$fn]))
-            $this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this);
-        $this->current_parser =& $this->parsers[$fn];
-        
-        return $this->parsers[$fn]->getPageCount();
-    }
-    
-    /**
-     * Import a page
-     *
-     * @param int $pageno pagenumber
-     * @return int Index of imported page - to use with fpdf_tpl::useTemplate()
-     */
-    function importPage($pageno, $boxName='/CropBox') {
-        if ($this->_intpl) {
-            return $this->error("Please import the desired pages before creating a new template.");
-        }
-        
-        $fn =& $this->current_filename;
-        
-        $parser =& $this->parsers[$fn];
-        $parser->setPageno($pageno);
-
-        $this->tpl++;
-        $this->tpls[$this->tpl] = array();
-        $tpl =& $this->tpls[$this->tpl];
-        $tpl['parser'] =& $parser;
-        $tpl['resources'] = $parser->getPageResources();
-        $tpl['buffer'] = $parser->getContent();
-        
-        if (!in_array($boxName, $parser->availableBoxes))
-            return $this->Error(sprintf("Unknown box: %s", $boxName));
-        $pageboxes = $parser->getPageBoxes($pageno);
-        
-        /**
-         * MediaBox
-         * CropBox: Default -> MediaBox
-         * BleedBox: Default -> CropBox
-         * TrimBox: Default -> CropBox
-         * ArtBox: Default -> CropBox
-         */
-        if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox"))
-            $boxName = "/CropBox";
-        if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")
-            $boxName = "/MediaBox";
-        
-        if (!isset($pageboxes[$boxName]))
-            return false;
-        $this->lastUsedPageBox = $boxName;
-        
-        $box = $pageboxes[$boxName];
-        $tpl['box'] = $box;
-        
-        // To build an array that can be used by PDF_TPL::useTemplate()
-        $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box);
-        // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
-        $tpl['x'] = 0;
-        $tpl['y'] = 0;
-        
-        $page =& $parser->pages[$parser->pageno];
-        
-        // fix for rotated pages
-        $rotation = $parser->getPageRotation($pageno);
-        if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) {
-            $steps = $angle / 90;
-                
-            $_w = $tpl['w'];
-            $_h = $tpl['h'];
-            $tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
-            $tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
-            
-            if ($steps % 2 != 0) {
-                $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w'];
-            } else {
-                $x = $tpl['w'];
-                $y = $tpl['h'];
-            }
-            
-            $cx=($x/2+$tpl['box']['x'])*$this->k;
-            $cy=($y/2+$tpl['box']['y'])*$this->k;
-            
-            $angle*=-1; 
-            
-            $angle*=M_PI/180;
-            $c=cos($angle);
-            $s=sin($angle);
-            
-            $tpl['buffer'] = sprintf('q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm %s Q',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy, $tpl['buffer']);
-        }
-        
-        return $this->tpl;
-    }
-    
-    function getLastUsedPageBox() {
-        return $this->lastUsedPageBox;
-    }
-    
-    function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
-        $this->_out('q 0 J 1 w 0 j 0 G'); // reset standard values
-        $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h);
-        $this->_out('Q');
-        return $s;
-    }
-    
-    /**
-     * Private method, that rebuilds all needed objects of source files
-     */
-    function _putimportedobjects() {
-        if (is_array($this->parsers) && count($this->parsers) > 0) {
-            foreach($this->parsers AS $filename => $p) {
-                $this->current_parser =& $this->parsers[$filename];
-                if (is_array($this->_obj_stack[$filename])) {
-                    while($n = key($this->_obj_stack[$filename])) {
-                        $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]);
-						
-                        $this->_newobj($this->_obj_stack[$filename][$n][0]);
-                        
-                        if ($nObj[0] == PDF_TYPE_STREAM) {
-							$this->pdf_write_value ($nObj);
-                        } else {
-                            $this->pdf_write_value ($nObj[1]);
-                        }
-                        
-                        $this->_out('endobj');
-                        $this->_obj_stack[$filename][$n] = null; // free memory
-                        unset($this->_obj_stack[$filename][$n]);
-                        reset($this->_obj_stack[$filename]);
-                    }
-                }
-            }
-        }
-    }
-    
-    /**
-     * Sets the PDF Version to the highest of imported documents
-     */
-    function setVersion() {
-        $this->PDFVersion = max($this->importVersion, $this->PDFVersion);
-    }
-    
-    /**
-     * Put resources
-     */
-    function _putresources() {
-        $this->_putfonts();
-    	$this->_putimages();
-    	$this->_putformxobjects();
-        $this->_putimportedobjects();
-        //Resource dictionary
-    	$this->offsets[2]=strlen($this->buffer);
-    	$this->_out('2 0 obj');
-    	$this->_out('<<');
-    	$this->_putresourcedict();
-    	$this->_out('>>');
-    	$this->_out('endobj');
-    }
-    
-    /**
-     * Private Method that writes the form xobjects
-     */
-    function _putformxobjects() {
-        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
-	    reset($this->tpls);
-        foreach($this->tpls AS $tplidx => $tpl) {
-            $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
-    		$this->_newobj();
-    		$this->tpls[$tplidx]['n'] = $this->n;
-    		$this->_out('<<'.$filter.'/Type /XObject');
-            $this->_out('/Subtype /Form');
-            $this->_out('/FormType 1');
-            
-            $this->_out(sprintf('/BBox [%.2f %.2f %.2f %.2f]',
-                ($tpl['x'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k,
-                ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y'])*$this->k,
-                ($tpl['w'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k,
-                ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y']-$tpl['h'])*$this->k)
-            );
-            
-            if (isset($tpl['box']))
-                $this->_out(sprintf('/Matrix [1 0 0 1 %.5f %.5f]',-$tpl['box']['x']*$this->k, -$tpl['box']['y']*$this->k));
-            
-            $this->_out('/Resources ');
-
-            if (isset($tpl['resources'])) {
-                $this->current_parser =& $tpl['parser'];
-                $this->pdf_write_value($tpl['resources']);
-            } else {
-                $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
-            	if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
-                	$this->_out('/Font <<');
-                    foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
-                		$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
-                	$this->_out('>>');
-                }
-            	if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || 
-            	   isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
-            	{
-                    $this->_out('/XObject <<');
-                    if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
-                        foreach($this->_res['tpl'][$tplidx]['images'] as $image)
-                  			$this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
-                    }
-                    if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
-                        foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl)
-                            $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R');
-                    }
-                    $this->_out('>>');
-            	}
-            	$this->_out('>>');
-            }
-
-        	$this->_out('/Length '.strlen($p).' >>');
-    		$this->_putstream($p);
-    		$this->_out('endobj');
-        }
-    }
-
-    /**
-     * Rewritten to handle existing own defined objects
-     */
-    function _newobj($obj_id=false,$onlynewobj=false) {
-        if (!$obj_id) {
-            $obj_id = ++$this->n;
-        }
-
-    	//Begin a new object
-        if (!$onlynewobj) {
-            $this->offsets[$obj_id] = strlen($this->buffer);
-            $this->_out($obj_id.' 0 obj');
-            $this->_current_obj_id = $obj_id; // for later use with encryption
-        }
-        
-    }
-
-    /**
-     * Writes a value
-     * Needed to rebuild the source document
-     *
-     * @param mixed $value A PDF-Value. Structure of values see cases in this method
-     */
-    function pdf_write_value(&$value)
-    {
-
-        switch ($value[0]) {
-
-    		case PDF_TYPE_NUMERIC :
-    		case PDF_TYPE_TOKEN :
-                // A numeric value or a token.
-    			// Simply output them
-                $this->_out($value[1]." ", false);
-    			break;
-
-    		case PDF_TYPE_ARRAY :
-
-    			// An array. Output the proper
-    			// structure and move on.
-
-    			$this->_out("[",false);
-                for ($i = 0; $i < count($value[1]); $i++) {
-    				$this->pdf_write_value($value[1][$i]);
-    			}
-
-    			$this->_out("]");
-    			break;
-
-    		case PDF_TYPE_DICTIONARY :
-
-    			// A dictionary.
-    			$this->_out("<<",false);
-
-    			reset ($value[1]);
-
-    			while (list($k, $v) = each($value[1])) {
-    				$this->_out($k . " ",false);
-    				$this->pdf_write_value($v);
-    			}
-
-    			$this->_out(">>");
-    			break;
-
-    		case PDF_TYPE_OBJREF :
-
-    			// An indirect object reference
-    			// Fill the object stack if needed
-    			$cpfn =& $this->current_parser->filename;
-    			if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
-                    $this->_newobj(false,true);
-                    $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
-                    $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
-                }
-                $objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
-
-    			$this->_out("{$objid} 0 R"); //{$value[2]}
-    			break;
-
-    		case PDF_TYPE_STRING :
-
-    			// A string.
-                $this->_out('('.$value[1].')');
-
-    			break;
-
-    		case PDF_TYPE_STREAM :
-
-    			// A stream. First, output the
-    			// stream dictionary, then the
-    			// stream data itself.
-                $this->pdf_write_value($value[1]);
-    			$this->_out("stream");
-    			$this->_out($value[2][1]);
-    			$this->_out("endstream");
-    			break;
-            case PDF_TYPE_HEX :
-            
-                $this->_out("<".$value[1].">");
-                break;
-
-    		case PDF_TYPE_NULL :
-                // The null object.
-
-    			$this->_out("null");
-    			break;
-    	}
-    }
-    
-    
-    /**
-     * Private Method
-     */
-    function _out($s,$ln=true) {
-	   //Add a line to the document
-	   if ($this->state==2) {
-           if (!$this->_intpl)
-	           $this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
-           else
-               $this->tpls[$this->tpl]['buffer'] .= $s.($ln == true ? "\n" : '');
-       } else {
-		   $this->buffer.=$s.($ln == true ? "\n" : '');
-       }
-    }
-
-    /**
-     * rewritten to close opened parsers
-     *
-     */
-    function _enddoc() {
-        parent::_enddoc();
-        $this->_closeParsers();
-    }
-    
-    /**
-     * close all files opened by parsers
-     */
-    function _closeParsers() {
-        if ($this->state > 2 && count($this->parsers) > 0) {
-          	foreach ($this->parsers as $k => $_){
-            	$this->parsers[$k]->closeFile();
-            	$this->parsers[$k] = null;
-            	unset($this->parsers[$k]);
-            }
-            return true;
-        }
-        return false;
-    }
-
-}
-
-// for PHP5
-if (!class_exists('fpdi')) {
-    class fpdi extends FPDI {}
-}
+<?php
+//
+//  FPDI - Version 1.2
+//
+//    Copyright 2004-2007 Setasign - Jan Slabon
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+define('FPDI_VERSION','1.2');
+
+ini_set('auto_detect_line_endings',1); // Strongly required!
+
+require_once("fpdf_tpl.php");
+require_once("fpdi_pdf_parser.php");
+
+
+class FPDI extends FPDF_TPL {
+    /**
+     * Actual filename
+     * @var string
+     */
+    var $current_filename;
+
+    /**
+     * Parser-Objects
+     * @var array
+     */
+    var $parsers;
+    
+    /**
+     * Current parser
+     * @var object
+     */
+    var $current_parser;
+    
+    /**
+     * Highest version of imported PDF
+     * @var double
+     */
+    var $importVersion = 1.3;
+
+    /**
+     * object stack
+     * @var array
+     */
+    var $_obj_stack;
+    
+    /**
+     * done object stack
+     * @var array
+     */
+    var $_don_obj_stack;
+
+    /**
+     * Current Object Id.
+     * @var integer
+     */
+    var $_current_obj_id;
+    
+    /**
+     * The name of the last imported page box
+     * @var string
+     */
+    var $lastUsedPageBox;
+    
+    /**
+     * Constructor
+     * See FPDF-Manual
+     */
+    function FPDI($orientation='P',$unit='mm',$format='A4') {
+        parent::FPDF_TPL($orientation,$unit,$format);
+    }
+    
+    /**
+     * Set a source-file
+     *
+     * @param string $filename a valid filename
+     * @return int number of available pages
+     */
+    function setSourceFile($filename) {
+        $this->current_filename = $filename;
+        $fn =& $this->current_filename;
+
+        if (!isset($this->parsers[$fn]))
+            $this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this);
+        $this->current_parser =& $this->parsers[$fn];
+        
+        return $this->parsers[$fn]->getPageCount();
+    }
+    
+    /**
+     * Import a page
+     *
+     * @param int $pageno pagenumber
+     * @return int Index of imported page - to use with fpdf_tpl::useTemplate()
+     */
+    function importPage($pageno, $boxName='/CropBox') {
+        if ($this->_intpl) {
+            return $this->error("Please import the desired pages before creating a new template.");
+        }
+        
+        $fn =& $this->current_filename;
+        
+        $parser =& $this->parsers[$fn];
+        $parser->setPageno($pageno);
+
+        $this->tpl++;
+        $this->tpls[$this->tpl] = array();
+        $tpl =& $this->tpls[$this->tpl];
+        $tpl['parser'] =& $parser;
+        $tpl['resources'] = $parser->getPageResources();
+        $tpl['buffer'] = $parser->getContent();
+        
+        if (!in_array($boxName, $parser->availableBoxes))
+            return $this->Error(sprintf("Unknown box: %s", $boxName));
+        $pageboxes = $parser->getPageBoxes($pageno);
+        
+        /**
+         * MediaBox
+         * CropBox: Default -> MediaBox
+         * BleedBox: Default -> CropBox
+         * TrimBox: Default -> CropBox
+         * ArtBox: Default -> CropBox
+         */
+        if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox"))
+            $boxName = "/CropBox";
+        if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")
+            $boxName = "/MediaBox";
+        
+        if (!isset($pageboxes[$boxName]))
+            return false;
+        $this->lastUsedPageBox = $boxName;
+        
+        $box = $pageboxes[$boxName];
+        $tpl['box'] = $box;
+        
+        // To build an array that can be used by PDF_TPL::useTemplate()
+        $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box);
+        // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects()
+        $tpl['x'] = 0;
+        $tpl['y'] = 0;
+        
+        $page =& $parser->pages[$parser->pageno];
+        
+        // fix for rotated pages
+        $rotation = $parser->getPageRotation($pageno);
+        if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) {
+            $steps = $angle / 90;
+                
+            $_w = $tpl['w'];
+            $_h = $tpl['h'];
+            $tpl['w'] = $steps % 2 == 0 ? $_w : $_h;
+            $tpl['h'] = $steps % 2 == 0 ? $_h : $_w;
+            
+            if ($steps % 2 != 0) {
+                $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w'];
+            } else {
+                $x = $tpl['w'];
+                $y = $tpl['h'];
+            }
+            
+            $cx=($x/2+$tpl['box']['x'])*$this->k;
+            $cy=($y/2+$tpl['box']['y'])*$this->k;
+            
+            $angle*=-1; 
+            
+            $angle*=M_PI/180;
+            $c=cos($angle);
+            $s=sin($angle);
+            
+            $tpl['buffer'] = sprintf('q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm %s Q',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy, $tpl['buffer']);
+        }
+        
+        return $this->tpl;
+    }
+    
+    function getLastUsedPageBox() {
+        return $this->lastUsedPageBox;
+    }
+    
+    function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) {
+        $this->_out('q 0 J 1 w 0 j 0 G'); // reset standard values
+        $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h);
+        $this->_out('Q');
+        return $s;
+    }
+    
+    /**
+     * Private method, that rebuilds all needed objects of source files
+     */
+    function _putimportedobjects() {
+        if (is_array($this->parsers) && count($this->parsers) > 0) {
+            foreach($this->parsers AS $filename => $p) {
+                $this->current_parser =& $this->parsers[$filename];
+                if (is_array($this->_obj_stack[$filename])) {
+                    while($n = key($this->_obj_stack[$filename])) {
+                        $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]);
+						
+                        $this->_newobj($this->_obj_stack[$filename][$n][0]);
+                        
+                        if ($nObj[0] == PDF_TYPE_STREAM) {
+							$this->pdf_write_value ($nObj);
+                        } else {
+                            $this->pdf_write_value ($nObj[1]);
+                        }
+                        
+                        $this->_out('endobj');
+                        $this->_obj_stack[$filename][$n] = null; // free memory
+                        unset($this->_obj_stack[$filename][$n]);
+                        reset($this->_obj_stack[$filename]);
+                    }
+                }
+            }
+        }
+    }
+    
+    /**
+     * Sets the PDF Version to the highest of imported documents
+     */
+    function setVersion() {
+        $this->PDFVersion = max($this->importVersion, $this->PDFVersion);
+    }
+    
+    /**
+     * Put resources
+     */
+    function _putresources() {
+        $this->_putfonts();
+    	$this->_putimages();
+    	$this->_putformxobjects();
+        $this->_putimportedobjects();
+        //Resource dictionary
+    	$this->offsets[2]=strlen($this->buffer);
+    	$this->_out('2 0 obj');
+    	$this->_out('<<');
+    	$this->_putresourcedict();
+    	$this->_out('>>');
+    	$this->_out('endobj');
+    }
+    
+    /**
+     * Private Method that writes the form xobjects
+     */
+    function _putformxobjects() {
+        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
+	    reset($this->tpls);
+        foreach($this->tpls AS $tplidx => $tpl) {
+            $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer'];
+    		$this->_newobj();
+    		$this->tpls[$tplidx]['n'] = $this->n;
+    		$this->_out('<<'.$filter.'/Type /XObject');
+            $this->_out('/Subtype /Form');
+            $this->_out('/FormType 1');
+            
+            $this->_out(sprintf('/BBox [%.2f %.2f %.2f %.2f]',
+                ($tpl['x'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k,
+                ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y'])*$this->k,
+                ($tpl['w'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k,
+                ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y']-$tpl['h'])*$this->k)
+            );
+            
+            if (isset($tpl['box']))
+                $this->_out(sprintf('/Matrix [1 0 0 1 %.5f %.5f]',-$tpl['box']['x']*$this->k, -$tpl['box']['y']*$this->k));
+            
+            $this->_out('/Resources ');
+
+            if (isset($tpl['resources'])) {
+                $this->current_parser =& $tpl['parser'];
+                $this->pdf_write_value($tpl['resources']);
+            } else {
+                $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
+            	if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) {
+                	$this->_out('/Font <<');
+                    foreach($this->_res['tpl'][$tplidx]['fonts'] as $font)
+                		$this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
+                	$this->_out('>>');
+                }
+            	if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || 
+            	   isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls']))
+            	{
+                    $this->_out('/XObject <<');
+                    if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) {
+                        foreach($this->_res['tpl'][$tplidx]['images'] as $image)
+                  			$this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
+                    }
+                    if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) {
+                        foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl)
+                            $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R');
+                    }
+                    $this->_out('>>');
+            	}
+            	$this->_out('>>');
+            }
+
+        	$this->_out('/Length '.strlen($p).' >>');
+    		$this->_putstream($p);
+    		$this->_out('endobj');
+        }
+    }
+
+    /**
+     * Rewritten to handle existing own defined objects
+     */
+    function _newobj($obj_id=false,$onlynewobj=false) {
+        if (!$obj_id) {
+            $obj_id = ++$this->n;
+        }
+
+    	//Begin a new object
+        if (!$onlynewobj) {
+            $this->offsets[$obj_id] = strlen($this->buffer);
+            $this->_out($obj_id.' 0 obj');
+            $this->_current_obj_id = $obj_id; // for later use with encryption
+        }
+        
+    }
+
+    /**
+     * Writes a value
+     * Needed to rebuild the source document
+     *
+     * @param mixed $value A PDF-Value. Structure of values see cases in this method
+     */
+    function pdf_write_value(&$value)
+    {
+
+        switch ($value[0]) {
+
+    		case PDF_TYPE_NUMERIC :
+    		case PDF_TYPE_TOKEN :
+                // A numeric value or a token.
+    			// Simply output them
+                $this->_out($value[1]." ", false);
+    			break;
+
+    		case PDF_TYPE_ARRAY :
+
+    			// An array. Output the proper
+    			// structure and move on.
+
+    			$this->_out("[",false);
+                for ($i = 0; $i < count($value[1]); $i++) {
+    				$this->pdf_write_value($value[1][$i]);
+    			}
+
+    			$this->_out("]");
+    			break;
+
+    		case PDF_TYPE_DICTIONARY :
+
+    			// A dictionary.
+    			$this->_out("<<",false);
+
+    			reset ($value[1]);
+
+    			while (list($k, $v) = each($value[1])) {
+    				$this->_out($k . " ",false);
+    				$this->pdf_write_value($v);
+    			}
+
+    			$this->_out(">>");
+    			break;
+
+    		case PDF_TYPE_OBJREF :
+
+    			// An indirect object reference
+    			// Fill the object stack if needed
+    			$cpfn =& $this->current_parser->filename;
+    			if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) {
+                    $this->_newobj(false,true);
+                    $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
+                    $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value);
+                }
+                $objid = $this->_don_obj_stack[$cpfn][$value[1]][0];
+
+    			$this->_out("{$objid} 0 R"); //{$value[2]}
+    			break;
+
+    		case PDF_TYPE_STRING :
+
+    			// A string.
+                $this->_out('('.$value[1].')');
+
+    			break;
+
+    		case PDF_TYPE_STREAM :
+
+    			// A stream. First, output the
+    			// stream dictionary, then the
+    			// stream data itself.
+                $this->pdf_write_value($value[1]);
+    			$this->_out("stream");
+    			$this->_out($value[2][1]);
+    			$this->_out("endstream");
+    			break;
+            case PDF_TYPE_HEX :
+            
+                $this->_out("<".$value[1].">");
+                break;
+
+    		case PDF_TYPE_NULL :
+                // The null object.
+
+    			$this->_out("null");
+    			break;
+    	}
+    }
+    
+    
+    /**
+     * Private Method
+     */
+    function _out($s,$ln=true) {
+	   //Add a line to the document
+	   if ($this->state==2) {
+           if (!$this->_intpl)
+	           $this->pages[$this->page] .= $s.($ln == true ? "\n" : '');
+           else
+               $this->tpls[$this->tpl]['buffer'] .= $s.($ln == true ? "\n" : '');
+       } else {
+		   $this->buffer.=$s.($ln == true ? "\n" : '');
+       }
+    }
+
+    /**
+     * rewritten to close opened parsers
+     *
+     */
+    function _enddoc() {
+        parent::_enddoc();
+        $this->_closeParsers();
+    }
+    
+    /**
+     * close all files opened by parsers
+     */
+    function _closeParsers() {
+        if ($this->state > 2 && count($this->parsers) > 0) {
+          	foreach ($this->parsers as $k => $_){
+            	$this->parsers[$k]->closeFile();
+            	$this->parsers[$k] = null;
+            	unset($this->parsers[$k]);
+            }
+            return true;
+        }
+        return false;
+    }
+
+}
+
+// for PHP5
+if (!class_exists('fpdi')) {
+    class fpdi extends FPDI {}
+}
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/fpdf/fpdfi/fpdi_pdf_parser.php b/htdocs/includes/fpdf/fpdfi/fpdi_pdf_parser.php
index 8c12298903c4072f6b06417f9408aa55ad5b32e8..484e1080356ca4becea7a72cecaa12719da0fbdb 100644
--- a/htdocs/includes/fpdf/fpdfi/fpdi_pdf_parser.php
+++ b/htdocs/includes/fpdf/fpdfi/fpdi_pdf_parser.php
@@ -1,379 +1,379 @@
-<?php
-//
-//  FPDI - Version 1.2
-//
-//    Copyright 2004-2007 Setasign - Jan Slabon
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-require_once("pdf_parser.php");
-
-class fpdi_pdf_parser extends pdf_parser {
-
-    /**
-     * Pages
-     * Index beginns at 0
-     *
-     * @var array
-     */
-    var $pages;
-    
-    /**
-     * Page count
-     * @var integer
-     */
-    var $page_count;
-    
-    /**
-     * actual page number
-     * @var integer
-     */
-    var $pageno;
-    
-    /**
-     * PDF Version of imported Document
-     * @var string
-     */
-    var $pdfVersion;
-    
-    /**
-     * FPDI Reference
-     * @var object
-     */
-    var $fpdi;
-    
-    /**
-     * Available BoxTypes
-     *
-     * @var array
-     */
-    var $availableBoxes = array("/MediaBox","/CropBox","/BleedBox","/TrimBox","/ArtBox");
-        
-    /**
-     * Constructor
-     *
-     * @param string $filename  Source-Filename
-     * @param object $fpdi      Object of type fpdi
-     */
-    function fpdi_pdf_parser($filename,&$fpdi) {
-        $this->fpdi =& $fpdi;
-		$this->filename = $filename;
-		
-        parent::pdf_parser($filename);
-
-        // resolve Pages-Dictonary
-        $pages = $this->pdf_resolve_object($this->c, $this->root[1][1]['/Pages']);
-
-        // Read pages
-        $this->read_pages($this->c, $pages, $this->pages);
-        
-        // count pages;
-        $this->page_count = count($this->pages);
-    }
-    
-    /**
-     * Overwrite parent::error()
-     *
-     * @param string $msg  Error-Message
-     */
-    function error($msg) {
-    	$this->fpdi->error($msg);	
-    }
-    
-    /**
-     * Get pagecount from sourcefile
-     *
-     * @return int
-     */
-    function getPageCount() {
-        return $this->page_count;
-    }
-
-
-    /**
-     * Set pageno
-     *
-     * @param int $pageno Pagenumber to use
-     */
-    function setPageno($pageno) {
-        $pageno = ((int) $pageno) - 1;
-
-        if ($pageno < 0 || $pageno >= $this->getPageCount()) {
-            $this->fpdi->error("Pagenumber is wrong!");
-        }
-
-        $this->pageno = $pageno;
-    }
-    
-    /**
-     * Get page-resources from current page
-     *
-     * @return array
-     */
-    function getPageResources() {
-        return $this->_getPageResources($this->pages[$this->pageno]);
-    }
-    
-    /**
-     * Get page-resources from /Page
-     *
-     * @param array $obj Array of pdf-data
-     */
-    function _getPageResources ($obj) { // $obj = /Page
-    	$obj = $this->pdf_resolve_object($this->c, $obj);
-
-        // If the current object has a resources
-    	// dictionary associated with it, we use
-    	// it. Otherwise, we move back to its
-    	// parent object.
-        if (isset ($obj[1][1]['/Resources'])) {
-    		$res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Resources']);
-    		if ($res[0] == PDF_TYPE_OBJECT)
-                return $res[1];
-            return $res;
-    	} else {
-    		if (!isset ($obj[1][1]['/Parent'])) {
-    			return false;
-    		} else {
-                $res = $this->_getPageResources($obj[1][1]['/Parent']);
-                if ($res[0] == PDF_TYPE_OBJECT)
-                    return $res[1];
-                return $res;
-    		}
-    	}
-    }
-
-
-    /**
-     * Get content of current page
-     *
-     * If more /Contents is an array, the streams are concated
-     *
-     * @return string
-     */
-    function getContent() {
-        $buffer = "";
-        
-        if (isset($this->pages[$this->pageno][1][1]['/Contents'])) {
-            $contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']);
-            foreach($contents AS $tmp_content) {
-                $buffer .= $this->_rebuildContentStream($tmp_content).' ';
-            }
-        }
-        
-        return $buffer;
-    }
-    
-    
-    /**
-     * Resolve all content-objects
-     *
-     * @param array $content_ref
-     * @return array
-     */
-    function _getPageContent($content_ref) {
-        $contents = array();
-        
-        if ($content_ref[0] == PDF_TYPE_OBJREF) {
-            $content = $this->pdf_resolve_object($this->c, $content_ref);
-            if ($content[1][0] == PDF_TYPE_ARRAY) {
-                $contents = $this->_getPageContent($content[1]);
-            } else {
-                $contents[] = $content;
-            }
-        } else if ($content_ref[0] == PDF_TYPE_ARRAY) {
-            foreach ($content_ref[1] AS $tmp_content_ref) {
-                $contents = array_merge($contents,$this->_getPageContent($tmp_content_ref));
-            }
-        }
-
-        return $contents;
-    }
-
-
-    /**
-     * Rebuild content-streams
-     *
-     * @param array $obj
-     * @return string
-     */
-    function _rebuildContentStream($obj) {
-        $filters = array();
-        
-        if (isset($obj[1][1]['/Filter'])) {
-            $_filter = $obj[1][1]['/Filter'];
-
-            if ($_filter[0] == PDF_TYPE_TOKEN) {
-                $filters[] = $_filter;
-            } else if ($_filter[0] == PDF_TYPE_ARRAY) {
-                $filters = $_filter[1];
-            }
-        }
-
-        $stream = $obj[2][1];
-
-        foreach ($filters AS $_filter) {
-            switch ($_filter[1]) {
-                case "/FlateDecode":
-                    if (function_exists('gzuncompress')) {
-                        $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : '';                        
-                    } else {
-                        $this->fpdi->error(sprintf("To handle %s filter, please compile php with zlib support.",$_filter[1]));
-                    }
-                    if ($stream === false) {
-                        $this->fpdi->error("Error while decompressing stream.");
-                    }
-                break;
-                case null:
-                    $stream = $stream;
-                break;
-                default:
-                    if (preg_match("/^\/[a-z85]*$/i", $_filter[1], $filterName) && @include_once('decoders'.$_filter[1].'.php')) {
-                        $filterName = substr($_filter[1],1);
-                        if (class_exists($filterName)) {
-    	                	$decoder =& new $filterName($this->fpdi);
-    	                    $stream = $decoder->decode(trim($stream));
-                        } else {
-                        	$this->fpdi->error(sprintf("Unsupported Filter: %s",$_filter[1]));
-                        }
-                    } else {
-                        $this->fpdi->error(sprintf("Unsupported Filter: %s",$_filter[1]));
-                    }
-            }
-        }
-        
-        return $stream;
-    }
-    
-    
-    /**
-     * Get a Box from a page
-     * Arrayformat is same as used by fpdf_tpl
-     *
-     * @param array $page a /Page
-     * @param string $box_index Type of Box @see $availableBoxes
-     * @return array
-     */
-    function getPageBox($page, $box_index) {
-        $page = $this->pdf_resolve_object($this->c,$page);
-        $box = null;
-        if (isset($page[1][1][$box_index]))
-            $box =& $page[1][1][$box_index];
-        
-        if (!is_null($box) && $box[0] == PDF_TYPE_OBJREF) {
-            $tmp_box = $this->pdf_resolve_object($this->c,$box);
-            $box = $tmp_box[1];
-        }
-            
-        if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) {
-            $b =& $box[1];
-            return array("x" => $b[0][1]/$this->fpdi->k,
-                         "y" => $b[1][1]/$this->fpdi->k,
-                         "w" => abs($b[0][1]-$b[2][1])/$this->fpdi->k,
-                         "h" => abs($b[1][1]-$b[3][1])/$this->fpdi->k);
-        } else if (!isset ($page[1][1]['/Parent'])) {
-            return false;
-        } else {
-            return $this->getPageBox($this->pdf_resolve_object($this->c, $page[1][1]['/Parent']), $box_index);
-        }
-    }
-
-    function getPageBoxes($pageno) {
-        return $this->_getPageBoxes($this->pages[$pageno-1]);
-    }
-    
-    /**
-     * Get all Boxes from /Page
-     *
-     * @param array a /Page
-     * @return array
-     */
-    function _getPageBoxes($page) {
-        $boxes = array();
-
-        foreach($this->availableBoxes AS $box) {
-            if ($_box = $this->getPageBox($page,$box)) {
-                $boxes[$box] = $_box;
-            }
-        }
-
-        return $boxes;
-    }
-
-    function getPageRotation($pageno) {
-        return $this->_getPageRotation($this->pages[$pageno-1]);
-    }
-    
-    function _getPageRotation ($obj) { // $obj = /Page
-    	$obj = $this->pdf_resolve_object($this->c, $obj);
-    	if (isset ($obj[1][1]['/Rotate'])) {
-    		$res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Rotate']);
-    		if ($res[0] == PDF_TYPE_OBJECT)
-                return $res[1];
-            return $res;
-    	} else {
-    		if (!isset ($obj[1][1]['/Parent'])) {
-    			return false;
-    		} else {
-                $res = $this->_getPageRotation($obj[1][1]['/Parent']);
-                if ($res[0] == PDF_TYPE_OBJECT)
-                    return $res[1];
-                return $res;
-    		}
-    	}
-    }
-    
-    /**
-     * Read all /Page(es)
-     *
-     * @param object pdf_context
-     * @param array /Pages
-     * @param array the result-array
-     */
-    function read_pages (&$c, &$pages, &$result) {
-        // Get the kids dictionary
-    	$kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']);
-
-        if (!is_array($kids))
-            $this->fpdi->Error("Cannot find /Kids in current /Page-Dictionary");
-        foreach ($kids[1] as $v) {
-    		$pg = $this->pdf_resolve_object ($c, $v);
-            if ($pg[1][1]['/Type'][1] === '/Pages') {
-                // If one of the kids is an embedded
-    			// /Pages array, resolve it as well.
-                $this->read_pages ($c, $pg, $result);
-    		} else {
-    			$result[] = $pg;
-    		}
-    	}
-    }
-
-    
-    
-    /**
-     * Get PDF-Version
-     *
-     * And reset the PDF Version used in FPDI if needed
-     */
-    function getPDFVersion() {
-        parent::getPDFVersion();
-    	
-        if (isset($this->fpdi->importVersion) && $this->pdfVersion > $this->fpdi->importVersion) {
-            $this->fpdi->importVersion = $this->pdfVersion;
-        }
-    }
-    
-}
-
+<?php
+//
+//  FPDI - Version 1.2
+//
+//    Copyright 2004-2007 Setasign - Jan Slabon
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+require_once("pdf_parser.php");
+
+class fpdi_pdf_parser extends pdf_parser {
+
+    /**
+     * Pages
+     * Index beginns at 0
+     *
+     * @var array
+     */
+    var $pages;
+    
+    /**
+     * Page count
+     * @var integer
+     */
+    var $page_count;
+    
+    /**
+     * actual page number
+     * @var integer
+     */
+    var $pageno;
+    
+    /**
+     * PDF Version of imported Document
+     * @var string
+     */
+    var $pdfVersion;
+    
+    /**
+     * FPDI Reference
+     * @var object
+     */
+    var $fpdi;
+    
+    /**
+     * Available BoxTypes
+     *
+     * @var array
+     */
+    var $availableBoxes = array("/MediaBox","/CropBox","/BleedBox","/TrimBox","/ArtBox");
+        
+    /**
+     * Constructor
+     *
+     * @param string $filename  Source-Filename
+     * @param object $fpdi      Object of type fpdi
+     */
+    function fpdi_pdf_parser($filename,&$fpdi) {
+        $this->fpdi =& $fpdi;
+		$this->filename = $filename;
+		
+        parent::pdf_parser($filename);
+
+        // resolve Pages-Dictonary
+        $pages = $this->pdf_resolve_object($this->c, $this->root[1][1]['/Pages']);
+
+        // Read pages
+        $this->read_pages($this->c, $pages, $this->pages);
+        
+        // count pages;
+        $this->page_count = count($this->pages);
+    }
+    
+    /**
+     * Overwrite parent::error()
+     *
+     * @param string $msg  Error-Message
+     */
+    function error($msg) {
+    	$this->fpdi->error($msg);	
+    }
+    
+    /**
+     * Get pagecount from sourcefile
+     *
+     * @return int
+     */
+    function getPageCount() {
+        return $this->page_count;
+    }
+
+
+    /**
+     * Set pageno
+     *
+     * @param int $pageno Pagenumber to use
+     */
+    function setPageno($pageno) {
+        $pageno = ((int) $pageno) - 1;
+
+        if ($pageno < 0 || $pageno >= $this->getPageCount()) {
+            $this->fpdi->error("Pagenumber is wrong!");
+        }
+
+        $this->pageno = $pageno;
+    }
+    
+    /**
+     * Get page-resources from current page
+     *
+     * @return array
+     */
+    function getPageResources() {
+        return $this->_getPageResources($this->pages[$this->pageno]);
+    }
+    
+    /**
+     * Get page-resources from /Page
+     *
+     * @param array $obj Array of pdf-data
+     */
+    function _getPageResources ($obj) { // $obj = /Page
+    	$obj = $this->pdf_resolve_object($this->c, $obj);
+
+        // If the current object has a resources
+    	// dictionary associated with it, we use
+    	// it. Otherwise, we move back to its
+    	// parent object.
+        if (isset ($obj[1][1]['/Resources'])) {
+    		$res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Resources']);
+    		if ($res[0] == PDF_TYPE_OBJECT)
+                return $res[1];
+            return $res;
+    	} else {
+    		if (!isset ($obj[1][1]['/Parent'])) {
+    			return false;
+    		} else {
+                $res = $this->_getPageResources($obj[1][1]['/Parent']);
+                if ($res[0] == PDF_TYPE_OBJECT)
+                    return $res[1];
+                return $res;
+    		}
+    	}
+    }
+
+
+    /**
+     * Get content of current page
+     *
+     * If more /Contents is an array, the streams are concated
+     *
+     * @return string
+     */
+    function getContent() {
+        $buffer = "";
+        
+        if (isset($this->pages[$this->pageno][1][1]['/Contents'])) {
+            $contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']);
+            foreach($contents AS $tmp_content) {
+                $buffer .= $this->_rebuildContentStream($tmp_content).' ';
+            }
+        }
+        
+        return $buffer;
+    }
+    
+    
+    /**
+     * Resolve all content-objects
+     *
+     * @param array $content_ref
+     * @return array
+     */
+    function _getPageContent($content_ref) {
+        $contents = array();
+        
+        if ($content_ref[0] == PDF_TYPE_OBJREF) {
+            $content = $this->pdf_resolve_object($this->c, $content_ref);
+            if ($content[1][0] == PDF_TYPE_ARRAY) {
+                $contents = $this->_getPageContent($content[1]);
+            } else {
+                $contents[] = $content;
+            }
+        } else if ($content_ref[0] == PDF_TYPE_ARRAY) {
+            foreach ($content_ref[1] AS $tmp_content_ref) {
+                $contents = array_merge($contents,$this->_getPageContent($tmp_content_ref));
+            }
+        }
+
+        return $contents;
+    }
+
+
+    /**
+     * Rebuild content-streams
+     *
+     * @param array $obj
+     * @return string
+     */
+    function _rebuildContentStream($obj) {
+        $filters = array();
+        
+        if (isset($obj[1][1]['/Filter'])) {
+            $_filter = $obj[1][1]['/Filter'];
+
+            if ($_filter[0] == PDF_TYPE_TOKEN) {
+                $filters[] = $_filter;
+            } else if ($_filter[0] == PDF_TYPE_ARRAY) {
+                $filters = $_filter[1];
+            }
+        }
+
+        $stream = $obj[2][1];
+
+        foreach ($filters AS $_filter) {
+            switch ($_filter[1]) {
+                case "/FlateDecode":
+                    if (function_exists('gzuncompress')) {
+                        $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : '';                        
+                    } else {
+                        $this->fpdi->error(sprintf("To handle %s filter, please compile php with zlib support.",$_filter[1]));
+                    }
+                    if ($stream === false) {
+                        $this->fpdi->error("Error while decompressing stream.");
+                    }
+                break;
+                case null:
+                    $stream = $stream;
+                break;
+                default:
+                    if (preg_match("/^\/[a-z85]*$/i", $_filter[1], $filterName) && @include_once('decoders'.$_filter[1].'.php')) {
+                        $filterName = substr($_filter[1],1);
+                        if (class_exists($filterName)) {
+    	                	$decoder =& new $filterName($this->fpdi);
+    	                    $stream = $decoder->decode(trim($stream));
+                        } else {
+                        	$this->fpdi->error(sprintf("Unsupported Filter: %s",$_filter[1]));
+                        }
+                    } else {
+                        $this->fpdi->error(sprintf("Unsupported Filter: %s",$_filter[1]));
+                    }
+            }
+        }
+        
+        return $stream;
+    }
+    
+    
+    /**
+     * Get a Box from a page
+     * Arrayformat is same as used by fpdf_tpl
+     *
+     * @param array $page a /Page
+     * @param string $box_index Type of Box @see $availableBoxes
+     * @return array
+     */
+    function getPageBox($page, $box_index) {
+        $page = $this->pdf_resolve_object($this->c,$page);
+        $box = null;
+        if (isset($page[1][1][$box_index]))
+            $box =& $page[1][1][$box_index];
+        
+        if (!is_null($box) && $box[0] == PDF_TYPE_OBJREF) {
+            $tmp_box = $this->pdf_resolve_object($this->c,$box);
+            $box = $tmp_box[1];
+        }
+            
+        if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) {
+            $b =& $box[1];
+            return array("x" => $b[0][1]/$this->fpdi->k,
+                         "y" => $b[1][1]/$this->fpdi->k,
+                         "w" => abs($b[0][1]-$b[2][1])/$this->fpdi->k,
+                         "h" => abs($b[1][1]-$b[3][1])/$this->fpdi->k);
+        } else if (!isset ($page[1][1]['/Parent'])) {
+            return false;
+        } else {
+            return $this->getPageBox($this->pdf_resolve_object($this->c, $page[1][1]['/Parent']), $box_index);
+        }
+    }
+
+    function getPageBoxes($pageno) {
+        return $this->_getPageBoxes($this->pages[$pageno-1]);
+    }
+    
+    /**
+     * Get all Boxes from /Page
+     *
+     * @param array a /Page
+     * @return array
+     */
+    function _getPageBoxes($page) {
+        $boxes = array();
+
+        foreach($this->availableBoxes AS $box) {
+            if ($_box = $this->getPageBox($page,$box)) {
+                $boxes[$box] = $_box;
+            }
+        }
+
+        return $boxes;
+    }
+
+    function getPageRotation($pageno) {
+        return $this->_getPageRotation($this->pages[$pageno-1]);
+    }
+    
+    function _getPageRotation ($obj) { // $obj = /Page
+    	$obj = $this->pdf_resolve_object($this->c, $obj);
+    	if (isset ($obj[1][1]['/Rotate'])) {
+    		$res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Rotate']);
+    		if ($res[0] == PDF_TYPE_OBJECT)
+                return $res[1];
+            return $res;
+    	} else {
+    		if (!isset ($obj[1][1]['/Parent'])) {
+    			return false;
+    		} else {
+                $res = $this->_getPageRotation($obj[1][1]['/Parent']);
+                if ($res[0] == PDF_TYPE_OBJECT)
+                    return $res[1];
+                return $res;
+    		}
+    	}
+    }
+    
+    /**
+     * Read all /Page(es)
+     *
+     * @param object pdf_context
+     * @param array /Pages
+     * @param array the result-array
+     */
+    function read_pages (&$c, &$pages, &$result) {
+        // Get the kids dictionary
+    	$kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']);
+
+        if (!is_array($kids))
+            $this->fpdi->Error("Cannot find /Kids in current /Page-Dictionary");
+        foreach ($kids[1] as $v) {
+    		$pg = $this->pdf_resolve_object ($c, $v);
+            if ($pg[1][1]['/Type'][1] === '/Pages') {
+                // If one of the kids is an embedded
+    			// /Pages array, resolve it as well.
+                $this->read_pages ($c, $pg, $result);
+    		} else {
+    			$result[] = $pg;
+    		}
+    	}
+    }
+
+    
+    
+    /**
+     * Get PDF-Version
+     *
+     * And reset the PDF Version used in FPDI if needed
+     */
+    function getPDFVersion() {
+        parent::getPDFVersion();
+    	
+        if (isset($this->fpdi->importVersion) && $this->pdfVersion > $this->fpdi->importVersion) {
+            $this->fpdi->importVersion = $this->pdfVersion;
+        }
+    }
+    
+}
+
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/fpdf/fpdfi/fpdi_protection.php b/htdocs/includes/fpdf/fpdfi/fpdi_protection.php
index 0c3ec22cae36d0e23f789374c83ee75758a53115..c45c74b17852f1e99a85ca55c8425bccf68753ff 100644
--- a/htdocs/includes/fpdf/fpdfi/fpdi_protection.php
+++ b/htdocs/includes/fpdf/fpdfi/fpdi_protection.php
@@ -1,269 +1,269 @@
-<?php
-/****************************************************************************
-* Software: FPDI_Protection                                                 *
-* Version:  1.0.2                                                             *
-* Date:     2006/11/20                                                      *
-* Author:   Klemen VODOPIVEC, Jan Slabon                                    *
-* License:  Freeware                                                        *
-*                                                                           *
-* You may use and modify this software as you wish as stated in original    *
-* FPDF package.                                                             *
-*                                                                           *
-* Infos (by Jan Slabon):                                                    *
-* This class extends the FPDI-class available at http://www.setasign.de     *
-* so that you can import pages and create new protected pdf files.          *
-*                                                                           *
-* This release is dedicated to my son Fin Frederik (*2005/06/04)            *
-*                                                                           *
-****************************************************************************/
-
-require_once("fpdi.php");
-
-class FPDI_Protection extends FPDI {
-	
-	var $encrypted;          //whether document is protected
-    var $Uvalue;             //U entry in pdf document
-    var $Ovalue;             //O entry in pdf document
-    var $Pvalue;             //P entry in pdf document
-    var $enc_obj_id;         //encryption object id
-    var $last_rc4_key;       //last RC4 key encrypted (cached for optimisation)
-    var $last_rc4_key_c;     //last RC4 computed key
-    var $padding = '';
-    
-    function FPDI_Protection($orientation='P',$unit='mm',$format='A4')
-    {
-        parent::FPDI($orientation,$unit,$format);
-        $this->_current_obj_id =& $this->current_obj_id; // for FPDI 1.1 compatibility
-        
-        $this->encrypted=false;
-        $this->last_rc4_key = '';
-        $this->padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
-                         "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
-    }
-
-    /**
-    * Function to set permissions as well as user and owner passwords
-    *
-    * - permissions is an array with values taken from the following list:
-    *   40bit:  copy, print, modify, annot-forms
-    *   128bit: fill-in, screenreaders, assemble, degraded-print
-    *   If a value is present it means that the permission is granted
-    * - If a user password is set, user will be prompted before document is opened
-    * - If an owner password is set, document can be opened in privilege mode with no
-    *   restriction if that password is entered
-    */
-    function SetProtection($permissions=array(),$user_pass='',$owner_pass=null)
-    {
-        $options = array('print' => 4, 'modify' => 8, 'copy' => 16, 'annot-forms' => 32 );
-        $protection = 192;
-        foreach($permissions as $permission){
-            if (!isset($options[$permission]))
-                $this->Error('Incorrect permission: '.$permission);
-            $protection += $options[$permission];
-        }
-        if ($owner_pass === null)
-            $owner_pass = uniqid(rand());
-        $this->encrypted = true;
-        $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
-    }
-
-
-    function _putstream($s)
-    {
-        if ($this->encrypted) {
-            $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
-        }
-        parent::_putstream($s);
-    }
-
-
-    function _textstring($s)
-    {
-        if ($this->encrypted) {
-            $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
-        }
-        return parent::_textstring($s);
-    }
-
-
-    /**
-    * Compute key depending on object number where the encrypted data is stored
-    */
-    function _objectkey($n)
-    {
-        return substr($this->_md5_16($this->encryption_key.pack('VXxx',$n)),0,10);
-    }
-
-
-    /**
-    * Escape special characters
-    */
-    function _escape($s)
-    {
-        return str_replace(
-        	array('\\',')','(',"\r"),
-        	array('\\\\','\\)','\\(','\\r'),$s);
-    }
-
-    function _putresources()
-    {
-        parent::_putresources();
-        if ($this->encrypted) {
-            $this->_newobj();
-            $this->enc_obj_id = $this->_current_obj_id;
-            $this->_out('<<');
-            $this->_putencryption();
-            $this->_out('>>');
-        }
-    }
-
-    function _putencryption()
-    {
-        $this->_out('/Filter /Standard');
-        $this->_out('/V 1');
-        $this->_out('/R 2');
-        $this->_out('/O ('.$this->_escape($this->Ovalue).')');
-        $this->_out('/U ('.$this->_escape($this->Uvalue).')');
-        $this->_out('/P '.$this->Pvalue);
-    }
-
-
-    function _puttrailer()
-    {
-        parent::_puttrailer();
-        if ($this->encrypted) {
-            $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
-            $id = isset($this->fileidentifier) ? $this->fileidentifier : '';
-            $this->_out('/ID [<'.$id.'><'.$id.'>]');
-        }
-    }
-
-
-    /**
-    * RC4 is the standard encryption algorithm used in PDF format
-    */
-    function _RC4($key, $text)
-    {
-    	if ($this->last_rc4_key != $key) {
-            $k = str_repeat($key, 256/strlen($key)+1);
-            $rc4 = range(0,255);
-            $j = 0;
-            for ($i=0; $i<256; $i++){
-                $t = $rc4[$i];
-                $j = ($j + $t + ord($k{$i})) % 256;
-                $rc4[$i] = $rc4[$j];
-                $rc4[$j] = $t;
-            }
-            $this->last_rc4_key = $key;
-            $this->last_rc4_key_c = $rc4;
-        } else {
-            $rc4 = $this->last_rc4_key_c;
-        }
-
-        $len = strlen($text);
-        $a = 0;
-        $b = 0;
-        $out = '';
-        for ($i=0; $i<$len; $i++){
-            $a = ($a+1)%256;
-            $t= $rc4[$a];
-            $b = ($b+$t)%256;
-            $rc4[$a] = $rc4[$b];
-            $rc4[$b] = $t;
-            $k = $rc4[($rc4[$a]+$rc4[$b])%256];
-            $out.=chr(ord($text{$i}) ^ $k);
-        }
-
-        return $out;
-    }
-    
-
-    /**
-    * Get MD5 as binary string
-    */
-    function _md5_16($string)
-    {
-        return pack('H*',md5($string));
-    }
-
-    /**
-    * Compute O value
-    */
-    function _Ovalue($user_pass, $owner_pass)
-    {
-        $tmp = $this->_md5_16($owner_pass);
-        $owner_RC4_key = substr($tmp,0,5);
-        return $this->_RC4($owner_RC4_key, $user_pass);
-    }
-
-
-    /**
-    * Compute U value
-    */
-    function _Uvalue()
-    {
-        return $this->_RC4($this->encryption_key, $this->padding);
-    }
-
-
-    /**
-    * Compute encryption key
-    */
-    function _generateencryptionkey($user_pass, $owner_pass, $protection)
-    {
-        // Pad passwords
-        $user_pass = substr($user_pass.$this->padding,0,32);
-        $owner_pass = substr($owner_pass.$this->padding,0,32);
-        // Compute O value
-        $this->Ovalue = $this->_Ovalue($user_pass,$owner_pass);
-        // Compute encyption key
-        $tmp = $this->_md5_16($user_pass.$this->Ovalue.chr($protection)."\xFF\xFF\xFF");
-        $this->encryption_key = substr($tmp,0,5);
-        // Compute U value
-        $this->Uvalue = $this->_Uvalue();
-        // Compute P value
-        $this->Pvalue = -(($protection^255)+1);
-    }
-
-    
-    function pdf_write_value(&$value) {
-    	switch ($value[0]) {
-    		case PDF_TYPE_STRING :
-				if ($this->encrypted) {
-                    $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
-                 	$value[1] = $this->_escape($value[1]);
-                } 
-    			break;
-    			
-			case PDF_TYPE_STREAM :
-				if ($this->encrypted) {
-                    $value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[2][1]);
-                }
-                break;
-                
-            case PDF_TYPE_HEX :
-				
-            	if ($this->encrypted) {
-                	$value[1] = $this->hex2str($value[1]);
-                	$value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
-                    
-                	// remake hexstring of encrypted string
-    				$value[1] = $this->str2hex($value[1]);
-                }
-                break;
-    	}	
-    	
-    	parent::pdf_write_value($value);
-    }
-    
-    
-    function hex2str($hex) {
-    	return pack("H*", str_replace(array("\r","\n"," "),"", $hex));
-    }
-    
-    function str2hex($str) {
-        return current(unpack("H*",$str));
-    }
-}
-
+<?php
+/****************************************************************************
+* Software: FPDI_Protection                                                 *
+* Version:  1.0.2                                                             *
+* Date:     2006/11/20                                                      *
+* Author:   Klemen VODOPIVEC, Jan Slabon                                    *
+* License:  Freeware                                                        *
+*                                                                           *
+* You may use and modify this software as you wish as stated in original    *
+* FPDF package.                                                             *
+*                                                                           *
+* Infos (by Jan Slabon):                                                    *
+* This class extends the FPDI-class available at http://www.setasign.de     *
+* so that you can import pages and create new protected pdf files.          *
+*                                                                           *
+* This release is dedicated to my son Fin Frederik (*2005/06/04)            *
+*                                                                           *
+****************************************************************************/
+
+require_once("fpdi.php");
+
+class FPDI_Protection extends FPDI {
+	
+	var $encrypted;          //whether document is protected
+    var $Uvalue;             //U entry in pdf document
+    var $Ovalue;             //O entry in pdf document
+    var $Pvalue;             //P entry in pdf document
+    var $enc_obj_id;         //encryption object id
+    var $last_rc4_key;       //last RC4 key encrypted (cached for optimisation)
+    var $last_rc4_key_c;     //last RC4 computed key
+    var $padding = '';
+    
+    function FPDI_Protection($orientation='P',$unit='mm',$format='A4')
+    {
+        parent::FPDI($orientation,$unit,$format);
+        $this->_current_obj_id =& $this->current_obj_id; // for FPDI 1.1 compatibility
+        
+        $this->encrypted=false;
+        $this->last_rc4_key = '';
+        $this->padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
+                         "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
+    }
+
+    /**
+    * Function to set permissions as well as user and owner passwords
+    *
+    * - permissions is an array with values taken from the following list:
+    *   40bit:  copy, print, modify, annot-forms
+    *   128bit: fill-in, screenreaders, assemble, degraded-print
+    *   If a value is present it means that the permission is granted
+    * - If a user password is set, user will be prompted before document is opened
+    * - If an owner password is set, document can be opened in privilege mode with no
+    *   restriction if that password is entered
+    */
+    function SetProtection($permissions=array(),$user_pass='',$owner_pass=null)
+    {
+        $options = array('print' => 4, 'modify' => 8, 'copy' => 16, 'annot-forms' => 32 );
+        $protection = 192;
+        foreach($permissions as $permission){
+            if (!isset($options[$permission]))
+                $this->Error('Incorrect permission: '.$permission);
+            $protection += $options[$permission];
+        }
+        if ($owner_pass === null)
+            $owner_pass = uniqid(rand());
+        $this->encrypted = true;
+        $this->_generateencryptionkey($user_pass, $owner_pass, $protection);
+    }
+
+
+    function _putstream($s)
+    {
+        if ($this->encrypted) {
+            $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
+        }
+        parent::_putstream($s);
+    }
+
+
+    function _textstring($s)
+    {
+        if ($this->encrypted) {
+            $s = $this->_RC4($this->_objectkey($this->_current_obj_id), $s);
+        }
+        return parent::_textstring($s);
+    }
+
+
+    /**
+    * Compute key depending on object number where the encrypted data is stored
+    */
+    function _objectkey($n)
+    {
+        return substr($this->_md5_16($this->encryption_key.pack('VXxx',$n)),0,10);
+    }
+
+
+    /**
+    * Escape special characters
+    */
+    function _escape($s)
+    {
+        return str_replace(
+        	array('\\',')','(',"\r"),
+        	array('\\\\','\\)','\\(','\\r'),$s);
+    }
+
+    function _putresources()
+    {
+        parent::_putresources();
+        if ($this->encrypted) {
+            $this->_newobj();
+            $this->enc_obj_id = $this->_current_obj_id;
+            $this->_out('<<');
+            $this->_putencryption();
+            $this->_out('>>');
+        }
+    }
+
+    function _putencryption()
+    {
+        $this->_out('/Filter /Standard');
+        $this->_out('/V 1');
+        $this->_out('/R 2');
+        $this->_out('/O ('.$this->_escape($this->Ovalue).')');
+        $this->_out('/U ('.$this->_escape($this->Uvalue).')');
+        $this->_out('/P '.$this->Pvalue);
+    }
+
+
+    function _puttrailer()
+    {
+        parent::_puttrailer();
+        if ($this->encrypted) {
+            $this->_out('/Encrypt '.$this->enc_obj_id.' 0 R');
+            $id = isset($this->fileidentifier) ? $this->fileidentifier : '';
+            $this->_out('/ID [<'.$id.'><'.$id.'>]');
+        }
+    }
+
+
+    /**
+    * RC4 is the standard encryption algorithm used in PDF format
+    */
+    function _RC4($key, $text)
+    {
+    	if ($this->last_rc4_key != $key) {
+            $k = str_repeat($key, 256/strlen($key)+1);
+            $rc4 = range(0,255);
+            $j = 0;
+            for ($i=0; $i<256; $i++){
+                $t = $rc4[$i];
+                $j = ($j + $t + ord($k{$i})) % 256;
+                $rc4[$i] = $rc4[$j];
+                $rc4[$j] = $t;
+            }
+            $this->last_rc4_key = $key;
+            $this->last_rc4_key_c = $rc4;
+        } else {
+            $rc4 = $this->last_rc4_key_c;
+        }
+
+        $len = strlen($text);
+        $a = 0;
+        $b = 0;
+        $out = '';
+        for ($i=0; $i<$len; $i++){
+            $a = ($a+1)%256;
+            $t= $rc4[$a];
+            $b = ($b+$t)%256;
+            $rc4[$a] = $rc4[$b];
+            $rc4[$b] = $t;
+            $k = $rc4[($rc4[$a]+$rc4[$b])%256];
+            $out.=chr(ord($text{$i}) ^ $k);
+        }
+
+        return $out;
+    }
+    
+
+    /**
+    * Get MD5 as binary string
+    */
+    function _md5_16($string)
+    {
+        return pack('H*',md5($string));
+    }
+
+    /**
+    * Compute O value
+    */
+    function _Ovalue($user_pass, $owner_pass)
+    {
+        $tmp = $this->_md5_16($owner_pass);
+        $owner_RC4_key = substr($tmp,0,5);
+        return $this->_RC4($owner_RC4_key, $user_pass);
+    }
+
+
+    /**
+    * Compute U value
+    */
+    function _Uvalue()
+    {
+        return $this->_RC4($this->encryption_key, $this->padding);
+    }
+
+
+    /**
+    * Compute encryption key
+    */
+    function _generateencryptionkey($user_pass, $owner_pass, $protection)
+    {
+        // Pad passwords
+        $user_pass = substr($user_pass.$this->padding,0,32);
+        $owner_pass = substr($owner_pass.$this->padding,0,32);
+        // Compute O value
+        $this->Ovalue = $this->_Ovalue($user_pass,$owner_pass);
+        // Compute encyption key
+        $tmp = $this->_md5_16($user_pass.$this->Ovalue.chr($protection)."\xFF\xFF\xFF");
+        $this->encryption_key = substr($tmp,0,5);
+        // Compute U value
+        $this->Uvalue = $this->_Uvalue();
+        // Compute P value
+        $this->Pvalue = -(($protection^255)+1);
+    }
+
+    
+    function pdf_write_value(&$value) {
+    	switch ($value[0]) {
+    		case PDF_TYPE_STRING :
+				if ($this->encrypted) {
+                    $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
+                 	$value[1] = $this->_escape($value[1]);
+                } 
+    			break;
+    			
+			case PDF_TYPE_STREAM :
+				if ($this->encrypted) {
+                    $value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[2][1]);
+                }
+                break;
+                
+            case PDF_TYPE_HEX :
+				
+            	if ($this->encrypted) {
+                	$value[1] = $this->hex2str($value[1]);
+                	$value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]);
+                    
+                	// remake hexstring of encrypted string
+    				$value[1] = $this->str2hex($value[1]);
+                }
+                break;
+    	}	
+    	
+    	parent::pdf_write_value($value);
+    }
+    
+    
+    function hex2str($hex) {
+    	return pack("H*", str_replace(array("\r","\n"," "),"", $hex));
+    }
+    
+    function str2hex($str) {
+        return current(unpack("H*",$str));
+    }
+}
+
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/fpdf/fpdfi/pdf_context.php b/htdocs/includes/fpdf/fpdfi/pdf_context.php
index 0e961ca5f08592c02ab3ba58400a6f486342e56a..6cf4bdcc2b6e7c69d3c95903f4494755d9fd6240 100644
--- a/htdocs/includes/fpdf/fpdfi/pdf_context.php
+++ b/htdocs/includes/fpdf/fpdfi/pdf_context.php
@@ -1,78 +1,78 @@
-<?php
-//
-//  FPDI - Version 1.2
-//
-//    Copyright 2004-2007 Setasign - Jan Slabon
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-class pdf_context {
-
-	var $file;
-	var $buffer;
-	var $offset;
-	var $length;
-
-	var $stack;
-
-	// Constructor
-
-	function pdf_context($f) {
-		$this->file = $f;
-		$this->reset();
-	}
-
-	// Optionally move the file
-	// pointer to a new location
-	// and reset the buffered data
-
-	function reset($pos = null, $l = 100) {
-		if (!is_null ($pos)) {
-			fseek ($this->file, $pos);
-		}
-
-		$this->buffer = $l > 0 ? fread($this->file, $l) : '';
-		$this->offset = 0;
-		$this->length = strlen($this->buffer);
-		$this->stack = array();
-	}
-
-	// Make sure that there is at least one
-	// character beyond the current offset in
-	// the buffer to prevent the tokenizer
-	// from attempting to access data that does
-	// not exist
-
-	function ensure_content() {
-		if ($this->offset >= $this->length - 1) {
-			return $this->increase_length();
-		} else {
-			return true;
-		}
-	}
-
-	// Forcefully read more data into the buffer
-
-	function increase_length($l=100) {
-		if (feof($this->file)) {
-			return false;
-		} else {
-			$this->buffer .= fread($this->file, $l);
-			$this->length = strlen($this->buffer);
-			return true;
-		}
-	}
-
-}
+<?php
+//
+//  FPDI - Version 1.2
+//
+//    Copyright 2004-2007 Setasign - Jan Slabon
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+class pdf_context {
+
+	var $file;
+	var $buffer;
+	var $offset;
+	var $length;
+
+	var $stack;
+
+	// Constructor
+
+	function pdf_context($f) {
+		$this->file = $f;
+		$this->reset();
+	}
+
+	// Optionally move the file
+	// pointer to a new location
+	// and reset the buffered data
+
+	function reset($pos = null, $l = 100) {
+		if (!is_null ($pos)) {
+			fseek ($this->file, $pos);
+		}
+
+		$this->buffer = $l > 0 ? fread($this->file, $l) : '';
+		$this->offset = 0;
+		$this->length = strlen($this->buffer);
+		$this->stack = array();
+	}
+
+	// Make sure that there is at least one
+	// character beyond the current offset in
+	// the buffer to prevent the tokenizer
+	// from attempting to access data that does
+	// not exist
+
+	function ensure_content() {
+		if ($this->offset >= $this->length - 1) {
+			return $this->increase_length();
+		} else {
+			return true;
+		}
+	}
+
+	// Forcefully read more data into the buffer
+
+	function increase_length($l=100) {
+		if (feof($this->file)) {
+			return false;
+		} else {
+			$this->buffer .= fread($this->file, $l);
+			$this->length = strlen($this->buffer);
+			return true;
+		}
+	}
+
+}
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/fpdf/fpdfi/pdf_parser.php b/htdocs/includes/fpdf/fpdfi/pdf_parser.php
index baddd3a3587f7c4631c591e86731aea11e899366..3832a0c7cd81f3403b607afd879fba28a35026b5 100644
--- a/htdocs/includes/fpdf/fpdfi/pdf_parser.php
+++ b/htdocs/includes/fpdf/fpdfi/pdf_parser.php
@@ -1,660 +1,660 @@
-<?php
-//
-//  FPDI - Version 1.2
-//
-//    Copyright 2004-2007 Setasign - Jan Slabon
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-if (!defined ('PDF_TYPE_NULL'))
-    define ('PDF_TYPE_NULL', 0);
-if (!defined ('PDF_TYPE_NUMERIC'))
-    define ('PDF_TYPE_NUMERIC', 1);
-if (!defined ('PDF_TYPE_TOKEN'))
-    define ('PDF_TYPE_TOKEN', 2);
-if (!defined ('PDF_TYPE_HEX'))
-    define ('PDF_TYPE_HEX', 3);
-if (!defined ('PDF_TYPE_STRING'))
-    define ('PDF_TYPE_STRING', 4);
-if (!defined ('PDF_TYPE_DICTIONARY'))
-    define ('PDF_TYPE_DICTIONARY', 5);
-if (!defined ('PDF_TYPE_ARRAY'))
-    define ('PDF_TYPE_ARRAY', 6);
-if (!defined ('PDF_TYPE_OBJDEC'))
-    define ('PDF_TYPE_OBJDEC', 7);
-if (!defined ('PDF_TYPE_OBJREF'))
-    define ('PDF_TYPE_OBJREF', 8);
-if (!defined ('PDF_TYPE_OBJECT'))
-    define ('PDF_TYPE_OBJECT', 9);
-if (!defined ('PDF_TYPE_STREAM'))
-    define ('PDF_TYPE_STREAM', 10);
-
-require_once("pdf_context.php");
-require_once("wrapper_functions.php");
-
-class pdf_parser {
-	
-	/**
-     * Filename
-     * @var string
-     */
-    var $filename;
-    
-    /**
-     * File resource
-     * @var resource
-     */
-    var $f;
-    
-    /**
-     * PDF Context
-     * @var object pdf_context-Instance
-     */
-    var $c;
-    
-    /**
-     * xref-Data
-     * @var array
-     */
-    var $xref;
-
-    /**
-     * root-Object
-     * @var array
-     */
-    var $root;
-	
-    
-    /**
-     * Constructor
-     *
-     * @param string $filename  Source-Filename
-     */
-	function pdf_parser($filename) {
-        $this->filename = $filename;
-        
-        $this->f = @fopen($this->filename, "rb");
-
-        if (!$this->f)
-            $this->error(sprintf("Cannot open %s !", $filename));
-
-        $this->getPDFVersion();
-
-        $this->c =& new pdf_context($this->f);
-        // Read xref-Data
-        $this->pdf_read_xref($this->xref, $this->pdf_find_xref());
-
-        // Check for Encryption
-        $this->getEncryption();
-
-        // Read root
-        $this->pdf_read_root();
-    }
-    
-    /**
-     * Close the opened file
-     */
-    function closeFile() {
-    	if (isset($this->f)) {
-    	    fclose($this->f);	
-    		unset($this->f);
-    	}	
-    }
-    
-    /**
-     * Print Error and die
-     *
-     * @param string $msg  Error-Message
-     */
-    function error($msg) {
-    	die("<b>PDF-Parser Error:</b> ".$msg);	
-    }
-    
-    /**
-     * Check Trailer for Encryption
-     */
-    function getEncryption() {
-        if (isset($this->xref['trailer'][1]['/Encrypt'])) {
-            $this->error("File is encrypted!");
-        }
-    }
-    
-	/**
-     * Find/Return /Root
-     *
-     * @return array
-     */
-    function pdf_find_root() {
-        if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) {
-            $this->error("Wrong Type of Root-Element! Must be an indirect reference");
-        }
-        return $this->xref['trailer'][1]['/Root'];
-    }
-
-    /**
-     * Read the /Root
-     */
-    function pdf_read_root() {
-        // read root
-        $this->root = $this->pdf_resolve_object($this->c, $this->pdf_find_root());
-    }
-    
-    /**
-     * Get PDF-Version
-     *
-     * And reset the PDF Version used in FPDI if needed
-     */
-    function getPDFVersion() {
-        fseek($this->f, 0);
-        preg_match("/\d\.\d/",fread($this->f,16),$m);
-        $this->pdfVersion = $m[0];
-    }
-    
-    /**
-     * Find the xref-Table
-     */
-    function pdf_find_xref() {
-       	fseek ($this->f, -min(filesize($this->filename),1500), SEEK_END);
-        $data = fread($this->f, 1500);
-        
-        $pos = strlen($data) - strpos(strrev($data), strrev('startxref')); 
-        $data = substr($data, $pos);
-        
-        if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) {
-            $this->error("Unable to find pointer to xref table");
-    	}
-
-    	return (int) $matches[1];
-    }
-
-    /**
-     * Read xref-table
-     *
-     * @param array $result Array of xref-table
-     * @param integer $offset of xref-table
-     * @param integer $start start-position in xref-table
-     * @param integer $end end-position in xref-table
-     */
-    function pdf_read_xref(&$result, $offset, $start = null, $end = null) {
-        if (is_null ($start) || is_null ($end)) {
-		    fseek($this->f, $o_pos = $offset);
-            $data = trim(fgets($this->f,1024));
-            	        
-            if (strlen($data) == 0) 
-                $data = trim(fgets($this->f,1024));
-            		
-            if ($data !== 'xref') {
-            	fseek($this->f, $o_pos);
-            	$data = trim(_fgets($this->f, true));
-            	if ($data !== 'xref') {
-            	    if (preg_match('/(.*xref)(.*)/m', $data, $m)) { // xref 0 128 - in one line
-                        fseek($this->f, $o_pos+strlen($m[1]));            	        
-            	    } elseif (preg_match('/(x|r|e|f)+/', $data, $m)) { // correct invalid xref-pointer
-            	        $tmpOffset = $offset-4+strlen($m[0]);
-            	        $this->pdf_read_xref($result, $tmpOffset, $start, $end);
-            	        return;
-                    } else {
-                        $this->error("Unable to find xref table - Maybe a Problem with 'auto_detect_line_endings'");
-            	    }
-            	}
-    		}
-
-    		$o_pos = ftell($this->f);
-    	    $data = explode(' ', trim(fgets($this->f,1024)));
-			if (count($data) != 2) {
-    	        fseek($this->f, $o_pos);
-    	        $data = explode(' ', trim(_fgets($this->f, true)));
-			
-            	if (count($data) != 2) {
-            	    if (count($data) > 2) { // no lineending
-            	        $n_pos = $o_pos+strlen($data[0])+strlen($data[1])+2;
-            	        fseek($this->f, $n_pos);
-            	    } else {
-                        $this->error("Unexpected header in xref table");
-            	    }
-            	}
-            }
-            $start = $data[0];
-            $end = $start + $data[1];
-        }
-
-        if (!isset($result['xref_location'])) {
-            $result['xref_location'] = $offset;
-    	}
-
-    	if (!isset($result['max_object']) || $end > $result['max_object']) {
-    	    $result['max_object'] = $end;
-    	}
-
-    	for (; $start < $end; $start++) {
-    		$data = ltrim(fread($this->f, 20)); // Spezifications says: 20 bytes including newlines
-    		$offset = substr($data, 0, 10);
-    		$generation = substr($data, 11, 5);
-
-    	    if (!isset ($result['xref'][$start][(int) $generation])) {
-    	    	$result['xref'][$start][(int) $generation] = (int) $offset;
-    	    }
-    	}
-
-    	$o_pos = ftell($this->f);
-        $data = fgets($this->f,1024);
-		if (strlen(trim($data)) == 0) 
-		    $data = fgets($this->f, 1024);
-        
-        if (preg_match("/trailer/",$data)) {
-            if (preg_match("/(.*trailer[ \n\r]*)/",$data,$m)) {
-            	fseek($this->f, $o_pos+strlen($m[1]));
-    		}
-    		
-			$c =&  new pdf_context($this->f);
-    	    $trailer = $this->pdf_read_value($c);
-    	    
-    	    if (isset($trailer[1]['/Prev'])) {
-    	    	$this->pdf_read_xref($result, $trailer[1]['/Prev'][1]);
-    		    $result['trailer'][1] = array_merge($result['trailer'][1], $trailer[1]);
-    	    } else {
-    	        $result['trailer'] = $trailer;
-            }
-    	} else {
-    	    $data = explode(' ', trim($data));
-            
-    		if (count($data) != 2) {
-            	fseek($this->f, $o_pos);
-        		$data = explode(' ', trim (_fgets ($this->f, true)));
-
-        		if (count($data) != 2) {
-        		    $this->error("Unexpected data in xref table");
-        		}
-		    }
-		    
-		    $this->pdf_read_xref($result, null, (int) $data[0], (int) $data[0] + (int) $data[1]);
-    	}
-    }
-
-
-    /**
-     * Reads an Value
-     *
-     * @param object $c pdf_context
-     * @param string $token a Token
-     * @return mixed
-     */
-    function pdf_read_value(&$c, $token = null) {
-    	if (is_null($token)) {
-    	    $token = $this->pdf_read_token($c);
-    	}
-    	
-        if ($token === false) {
-    	    return false;
-    	}
-
-       	switch ($token) {
-            case	'<':
-    			// This is a hex string.
-    			// Read the value, then the terminator
-
-                $pos = $c->offset;
-
-    			while(1) {
-
-                    $match = strpos ($c->buffer, '>', $pos);
-				
-    				// If you can't find it, try
-    				// reading more data from the stream
-
-    				if ($match === false) {
-    					if (!$c->increase_length()) {
-    						return false;
-    					} else {
-                        	continue;
-                    	}
-    				}
-
-    				$result = substr ($c->buffer, $c->offset, $match - $c->offset);
-    				$c->offset = $match+1;
-    				
-    				return array (PDF_TYPE_HEX, $result);
-                }
-                
-                break;
-    		case	'<<':
-    			// This is a dictionary.
-
-    			$result = array();
-
-    			// Recurse into this function until we reach
-    			// the end of the dictionary.
-    			while (($key = $this->pdf_read_token($c)) !== '>>') {
-    				if ($key === false) {
-    					return false;
-    				}
-					
-    				if (($value =   $this->pdf_read_value($c)) === false) {
-    					return false;
-    				}
-                    $result[$key] = $value;
-    			}
-				
-    			return array (PDF_TYPE_DICTIONARY, $result);
-
-    		case	'[':
-    			// This is an array.
-
-    			$result = array();
-
-    			// Recurse into this function until we reach
-    			// the end of the array.
-    			while (($token = $this->pdf_read_token($c)) !== ']') {
-                    if ($token === false) {
-    					return false;
-    				}
-					
-    				if (($value = $this->pdf_read_value($c, $token)) === false) {
-                        return false;
-    				}
-					
-    				$result[] = $value;
-    			}
-    			
-                return array (PDF_TYPE_ARRAY, $result);
-
-    		case	'('		:
-                // This is a string
-
-    			$pos = $c->offset;
-
-    			while(1) {
-
-                    // Start by finding the next closed
-    				// parenthesis
-
-    				$match = strpos ($c->buffer, ')', $pos);
-
-    				// If you can't find it, try
-    				// reading more data from the stream
-
-    				if ($match === false) {
-    					if (!$c->increase_length()) {
-                            return false;
-    					} else {
-                            continue;
-                        }
-    				}
-
-    				// Make sure that there is no backslash
-    				// before the parenthesis. If there is,
-    				// move on. Otherwise, return the string.
-                    $esc = preg_match('/([\\\\]+)$/', $tmpresult = substr($c->buffer, $c->offset, $match - $c->offset), $m);
-                    
-                    if ($esc === 0 || strlen($m[1]) % 2 == 0) {
-    				    $result = $tmpresult;
-                        $c->offset = $match + 1;
-                        return array (PDF_TYPE_STRING, $result);
-    				} else {
-    					$pos = $match + 1;
-
-    					if ($pos > $c->offset + $c->length) {
-    						$c->increase_length();
-    					}
-    				}    				
-                }
-
-            case "stream":
-            	$o_pos = ftell($c->file)-strlen($c->buffer);
-		        $o_offset = $c->offset;
-		        
-		        $c->reset($startpos = $o_pos + $o_offset);
-		        
-		        $e = 0; // ensure line breaks in front of the stream
-		        if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13))
-		        	$e++;
-		        if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10))
-		        	$e++;
-		        
-		        if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) {
-		        	$tmp_c =& new pdf_context($this->f);
-		        	$tmp_length = $this->pdf_resolve_object($tmp_c,$this->actual_obj[1][1]['/Length']);
-		        	$length = $tmp_length[1][1];
-		        } else {
-		        	$length = $this->actual_obj[1][1]['/Length'][1];	
-		        }
-		        
-		        if ($length > 0) {
-    		        $c->reset($startpos+$e,$length);
-    		        $v = $c->buffer;
-		        } else {
-		            $v = '';   
-		        }
-		        $c->reset($startpos+$e+$length+9); // 9 = strlen("endstream")
-		        
-		        return array(PDF_TYPE_STREAM, $v);
-		        
-    		default	:
-            	if (is_numeric ($token)) {
-                    // A numeric token. Make sure that
-    				// it is not part of something else.
-    				if (($tok2 = $this->pdf_read_token ($c)) !== false) {
-                        if (is_numeric ($tok2)) {
-
-    						// Two numeric tokens in a row.
-    						// In this case, we're probably in
-    						// front of either an object reference
-    						// or an object specification.
-    						// Determine the case and return the data
-    						if (($tok3 = $this->pdf_read_token ($c)) !== false) {
-                                switch ($tok3) {
-    								case	'obj'	:
-                                        return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2);
-    								case	'R'		:
-    									return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2);
-    							}
-    							// If we get to this point, that numeric value up
-    							// there was just a numeric value. Push the extra
-    							// tokens back into the stack and return the value.
-    							array_push ($c->stack, $tok3);
-    						}
-    					}
-
-    					array_push ($c->stack, $tok2);
-    				}
-
-    				return array (PDF_TYPE_NUMERIC, $token);
-    			} else {
-
-                    // Just a token. Return it.
-    				return array (PDF_TYPE_TOKEN, $token);
-    			}
-
-         }
-    }
-    
-    /**
-     * Resolve an object
-     *
-     * @param object $c pdf_context
-     * @param array $obj_spec The object-data
-     * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para
-     */
-    function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) {
-        // Exit if we get invalid data
-    	if (!is_array($obj_spec)) {
-            return false;
-    	}
-
-    	if ($obj_spec[0] == PDF_TYPE_OBJREF) {
-
-    		// This is a reference, resolve it
-    		if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) {
-
-    			// Save current file position
-    			// This is needed if you want to resolve
-    			// references while you're reading another object
-    			// (e.g.: if you need to determine the length
-    			// of a stream)
-
-    			$old_pos = ftell($c->file);
-
-    			// Reposition the file pointer and
-    			// load the object header.
-				
-    			$c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]);
-
-    			$header = $this->pdf_read_value($c,null,true);
-
-    			if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) {
-    				$this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location");
-    			}
-
-    			// If we're being asked to store all the information
-    			// about the object, we add the object ID and generation
-    			// number for later use
-				$this->actual_obj =& $result;
-    			if ($encapsulate) {
-    				$result = array (
-    					PDF_TYPE_OBJECT,
-    					'obj' => $obj_spec[1],
-    					'gen' => $obj_spec[2]
-    				);
-    			} else {
-    				$result = array();
-    			}
-
-    			// Now simply read the object data until
-    			// we encounter an end-of-object marker
-    			while(1) {
-                    $value = $this->pdf_read_value($c);
-					if ($value === false || count($result) > 4) {
-						// in this case the parser coudn't find an endobj so we break here
-						break;
-    				}
-
-    				if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') {
-    					break;
-    				}
-
-                    $result[] = $value;
-    			}
-
-    			$c->reset($old_pos);
-
-                if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) {
-                    $result[0] = PDF_TYPE_STREAM;
-                }
-
-    			return $result;
-    		}
-    	} else {
-    		return $obj_spec;
-    	}
-    }
-
-    
-    
-    /**
-     * Reads a token from the file
-     *
-     * @param object $c pdf_context
-     * @return mixed
-     */
-    function pdf_read_token(&$c)
-    {
-    	// If there is a token available
-    	// on the stack, pop it out and
-    	// return it.
-
-    	if (count($c->stack)) {
-    		return array_pop($c->stack);
-    	}
-
-    	// Strip away any whitespace
-
-    	do {
-    		if (!$c->ensure_content()) {
-    			return false;
-    		}
-    		$c->offset += _strspn($c->buffer, " \n\r\t", $c->offset);
-    	} while ($c->offset >= $c->length - 1);
-
-    	// Get the first character in the stream
-
-    	$char = $c->buffer[$c->offset++];
-
-    	switch ($char) {
-
-    		case '['	:
-    		case ']'	:
-    		case '('	:
-    		case ')'	:
-
-    			// This is either an array or literal string
-    			// delimiter, Return it
-
-    			return $char;
-
-    		case '<'	:
-    		case '>'	:
-
-    			// This could either be a hex string or
-    			// dictionary delimiter. Determine the
-    			// appropriate case and return the token
-
-    			if ($c->buffer[$c->offset] == $char) {
-    				if (!$c->ensure_content()) {
-    				    return false;
-    				}
-    				$c->offset++;
-    				return $char . $char;
-    			} else {
-    				return $char;
-    			}
-
-    		default		:
-
-    			// This is "another" type of token (probably
-    			// a dictionary entry or a numeric value)
-    			// Find the end and return it.
-
-    			if (!$c->ensure_content()) {
-    				return false;
-    			}
-
-    			while(1) {
-
-    				// Determine the length of the token
-
-    				$pos = _strcspn($c->buffer, " []<>()\r\n\t/", $c->offset);
-    				if ($c->offset + $pos <= $c->length - 1) {
-    					break;
-    				} else {
-    					// If the script reaches this point,
-    					// the token may span beyond the end
-    					// of the current buffer. Therefore,
-    					// we increase the size of the buffer
-    					// and try again--just to be safe.
-
-    					$c->increase_length();
-    				}
-    			}
-
-    			$result = substr($c->buffer, $c->offset - 1, $pos + 1);
-
-    			$c->offset += $pos;
-    			return $result;
-    	}
-    }
-
-	
-}
-
+<?php
+//
+//  FPDI - Version 1.2
+//
+//    Copyright 2004-2007 Setasign - Jan Slabon
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+if (!defined ('PDF_TYPE_NULL'))
+    define ('PDF_TYPE_NULL', 0);
+if (!defined ('PDF_TYPE_NUMERIC'))
+    define ('PDF_TYPE_NUMERIC', 1);
+if (!defined ('PDF_TYPE_TOKEN'))
+    define ('PDF_TYPE_TOKEN', 2);
+if (!defined ('PDF_TYPE_HEX'))
+    define ('PDF_TYPE_HEX', 3);
+if (!defined ('PDF_TYPE_STRING'))
+    define ('PDF_TYPE_STRING', 4);
+if (!defined ('PDF_TYPE_DICTIONARY'))
+    define ('PDF_TYPE_DICTIONARY', 5);
+if (!defined ('PDF_TYPE_ARRAY'))
+    define ('PDF_TYPE_ARRAY', 6);
+if (!defined ('PDF_TYPE_OBJDEC'))
+    define ('PDF_TYPE_OBJDEC', 7);
+if (!defined ('PDF_TYPE_OBJREF'))
+    define ('PDF_TYPE_OBJREF', 8);
+if (!defined ('PDF_TYPE_OBJECT'))
+    define ('PDF_TYPE_OBJECT', 9);
+if (!defined ('PDF_TYPE_STREAM'))
+    define ('PDF_TYPE_STREAM', 10);
+
+require_once("pdf_context.php");
+require_once("wrapper_functions.php");
+
+class pdf_parser {
+	
+	/**
+     * Filename
+     * @var string
+     */
+    var $filename;
+    
+    /**
+     * File resource
+     * @var resource
+     */
+    var $f;
+    
+    /**
+     * PDF Context
+     * @var object pdf_context-Instance
+     */
+    var $c;
+    
+    /**
+     * xref-Data
+     * @var array
+     */
+    var $xref;
+
+    /**
+     * root-Object
+     * @var array
+     */
+    var $root;
+	
+    
+    /**
+     * Constructor
+     *
+     * @param string $filename  Source-Filename
+     */
+	function pdf_parser($filename) {
+        $this->filename = $filename;
+        
+        $this->f = @fopen($this->filename, "rb");
+
+        if (!$this->f)
+            $this->error(sprintf("Cannot open %s !", $filename));
+
+        $this->getPDFVersion();
+
+        $this->c =& new pdf_context($this->f);
+        // Read xref-Data
+        $this->pdf_read_xref($this->xref, $this->pdf_find_xref());
+
+        // Check for Encryption
+        $this->getEncryption();
+
+        // Read root
+        $this->pdf_read_root();
+    }
+    
+    /**
+     * Close the opened file
+     */
+    function closeFile() {
+    	if (isset($this->f)) {
+    	    fclose($this->f);	
+    		unset($this->f);
+    	}	
+    }
+    
+    /**
+     * Print Error and die
+     *
+     * @param string $msg  Error-Message
+     */
+    function error($msg) {
+    	die("<b>PDF-Parser Error:</b> ".$msg);	
+    }
+    
+    /**
+     * Check Trailer for Encryption
+     */
+    function getEncryption() {
+        if (isset($this->xref['trailer'][1]['/Encrypt'])) {
+            $this->error("File is encrypted!");
+        }
+    }
+    
+	/**
+     * Find/Return /Root
+     *
+     * @return array
+     */
+    function pdf_find_root() {
+        if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) {
+            $this->error("Wrong Type of Root-Element! Must be an indirect reference");
+        }
+        return $this->xref['trailer'][1]['/Root'];
+    }
+
+    /**
+     * Read the /Root
+     */
+    function pdf_read_root() {
+        // read root
+        $this->root = $this->pdf_resolve_object($this->c, $this->pdf_find_root());
+    }
+    
+    /**
+     * Get PDF-Version
+     *
+     * And reset the PDF Version used in FPDI if needed
+     */
+    function getPDFVersion() {
+        fseek($this->f, 0);
+        preg_match("/\d\.\d/",fread($this->f,16),$m);
+        $this->pdfVersion = $m[0];
+    }
+    
+    /**
+     * Find the xref-Table
+     */
+    function pdf_find_xref() {
+       	fseek ($this->f, -min(filesize($this->filename),1500), SEEK_END);
+        $data = fread($this->f, 1500);
+        
+        $pos = strlen($data) - strpos(strrev($data), strrev('startxref')); 
+        $data = substr($data, $pos);
+        
+        if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) {
+            $this->error("Unable to find pointer to xref table");
+    	}
+
+    	return (int) $matches[1];
+    }
+
+    /**
+     * Read xref-table
+     *
+     * @param array $result Array of xref-table
+     * @param integer $offset of xref-table
+     * @param integer $start start-position in xref-table
+     * @param integer $end end-position in xref-table
+     */
+    function pdf_read_xref(&$result, $offset, $start = null, $end = null) {
+        if (is_null ($start) || is_null ($end)) {
+		    fseek($this->f, $o_pos = $offset);
+            $data = trim(fgets($this->f,1024));
+            	        
+            if (strlen($data) == 0) 
+                $data = trim(fgets($this->f,1024));
+            		
+            if ($data !== 'xref') {
+            	fseek($this->f, $o_pos);
+            	$data = trim(_fgets($this->f, true));
+            	if ($data !== 'xref') {
+            	    if (preg_match('/(.*xref)(.*)/m', $data, $m)) { // xref 0 128 - in one line
+                        fseek($this->f, $o_pos+strlen($m[1]));            	        
+            	    } elseif (preg_match('/(x|r|e|f)+/', $data, $m)) { // correct invalid xref-pointer
+            	        $tmpOffset = $offset-4+strlen($m[0]);
+            	        $this->pdf_read_xref($result, $tmpOffset, $start, $end);
+            	        return;
+                    } else {
+                        $this->error("Unable to find xref table - Maybe a Problem with 'auto_detect_line_endings'");
+            	    }
+            	}
+    		}
+
+    		$o_pos = ftell($this->f);
+    	    $data = explode(' ', trim(fgets($this->f,1024)));
+			if (count($data) != 2) {
+    	        fseek($this->f, $o_pos);
+    	        $data = explode(' ', trim(_fgets($this->f, true)));
+			
+            	if (count($data) != 2) {
+            	    if (count($data) > 2) { // no lineending
+            	        $n_pos = $o_pos+strlen($data[0])+strlen($data[1])+2;
+            	        fseek($this->f, $n_pos);
+            	    } else {
+                        $this->error("Unexpected header in xref table");
+            	    }
+            	}
+            }
+            $start = $data[0];
+            $end = $start + $data[1];
+        }
+
+        if (!isset($result['xref_location'])) {
+            $result['xref_location'] = $offset;
+    	}
+
+    	if (!isset($result['max_object']) || $end > $result['max_object']) {
+    	    $result['max_object'] = $end;
+    	}
+
+    	for (; $start < $end; $start++) {
+    		$data = ltrim(fread($this->f, 20)); // Spezifications says: 20 bytes including newlines
+    		$offset = substr($data, 0, 10);
+    		$generation = substr($data, 11, 5);
+
+    	    if (!isset ($result['xref'][$start][(int) $generation])) {
+    	    	$result['xref'][$start][(int) $generation] = (int) $offset;
+    	    }
+    	}
+
+    	$o_pos = ftell($this->f);
+        $data = fgets($this->f,1024);
+		if (strlen(trim($data)) == 0) 
+		    $data = fgets($this->f, 1024);
+        
+        if (preg_match("/trailer/",$data)) {
+            if (preg_match("/(.*trailer[ \n\r]*)/",$data,$m)) {
+            	fseek($this->f, $o_pos+strlen($m[1]));
+    		}
+    		
+			$c =&  new pdf_context($this->f);
+    	    $trailer = $this->pdf_read_value($c);
+    	    
+    	    if (isset($trailer[1]['/Prev'])) {
+    	    	$this->pdf_read_xref($result, $trailer[1]['/Prev'][1]);
+    		    $result['trailer'][1] = array_merge($result['trailer'][1], $trailer[1]);
+    	    } else {
+    	        $result['trailer'] = $trailer;
+            }
+    	} else {
+    	    $data = explode(' ', trim($data));
+            
+    		if (count($data) != 2) {
+            	fseek($this->f, $o_pos);
+        		$data = explode(' ', trim (_fgets ($this->f, true)));
+
+        		if (count($data) != 2) {
+        		    $this->error("Unexpected data in xref table");
+        		}
+		    }
+		    
+		    $this->pdf_read_xref($result, null, (int) $data[0], (int) $data[0] + (int) $data[1]);
+    	}
+    }
+
+
+    /**
+     * Reads an Value
+     *
+     * @param object $c pdf_context
+     * @param string $token a Token
+     * @return mixed
+     */
+    function pdf_read_value(&$c, $token = null) {
+    	if (is_null($token)) {
+    	    $token = $this->pdf_read_token($c);
+    	}
+    	
+        if ($token === false) {
+    	    return false;
+    	}
+
+       	switch ($token) {
+            case	'<':
+    			// This is a hex string.
+    			// Read the value, then the terminator
+
+                $pos = $c->offset;
+
+    			while(1) {
+
+                    $match = strpos ($c->buffer, '>', $pos);
+				
+    				// If you can't find it, try
+    				// reading more data from the stream
+
+    				if ($match === false) {
+    					if (!$c->increase_length()) {
+    						return false;
+    					} else {
+                        	continue;
+                    	}
+    				}
+
+    				$result = substr ($c->buffer, $c->offset, $match - $c->offset);
+    				$c->offset = $match+1;
+    				
+    				return array (PDF_TYPE_HEX, $result);
+                }
+                
+                break;
+    		case	'<<':
+    			// This is a dictionary.
+
+    			$result = array();
+
+    			// Recurse into this function until we reach
+    			// the end of the dictionary.
+    			while (($key = $this->pdf_read_token($c)) !== '>>') {
+    				if ($key === false) {
+    					return false;
+    				}
+					
+    				if (($value =   $this->pdf_read_value($c)) === false) {
+    					return false;
+    				}
+                    $result[$key] = $value;
+    			}
+				
+    			return array (PDF_TYPE_DICTIONARY, $result);
+
+    		case	'[':
+    			// This is an array.
+
+    			$result = array();
+
+    			// Recurse into this function until we reach
+    			// the end of the array.
+    			while (($token = $this->pdf_read_token($c)) !== ']') {
+                    if ($token === false) {
+    					return false;
+    				}
+					
+    				if (($value = $this->pdf_read_value($c, $token)) === false) {
+                        return false;
+    				}
+					
+    				$result[] = $value;
+    			}
+    			
+                return array (PDF_TYPE_ARRAY, $result);
+
+    		case	'('		:
+                // This is a string
+
+    			$pos = $c->offset;
+
+    			while(1) {
+
+                    // Start by finding the next closed
+    				// parenthesis
+
+    				$match = strpos ($c->buffer, ')', $pos);
+
+    				// If you can't find it, try
+    				// reading more data from the stream
+
+    				if ($match === false) {
+    					if (!$c->increase_length()) {
+                            return false;
+    					} else {
+                            continue;
+                        }
+    				}
+
+    				// Make sure that there is no backslash
+    				// before the parenthesis. If there is,
+    				// move on. Otherwise, return the string.
+                    $esc = preg_match('/([\\\\]+)$/', $tmpresult = substr($c->buffer, $c->offset, $match - $c->offset), $m);
+                    
+                    if ($esc === 0 || strlen($m[1]) % 2 == 0) {
+    				    $result = $tmpresult;
+                        $c->offset = $match + 1;
+                        return array (PDF_TYPE_STRING, $result);
+    				} else {
+    					$pos = $match + 1;
+
+    					if ($pos > $c->offset + $c->length) {
+    						$c->increase_length();
+    					}
+    				}    				
+                }
+
+            case "stream":
+            	$o_pos = ftell($c->file)-strlen($c->buffer);
+		        $o_offset = $c->offset;
+		        
+		        $c->reset($startpos = $o_pos + $o_offset);
+		        
+		        $e = 0; // ensure line breaks in front of the stream
+		        if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13))
+		        	$e++;
+		        if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10))
+		        	$e++;
+		        
+		        if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) {
+		        	$tmp_c =& new pdf_context($this->f);
+		        	$tmp_length = $this->pdf_resolve_object($tmp_c,$this->actual_obj[1][1]['/Length']);
+		        	$length = $tmp_length[1][1];
+		        } else {
+		        	$length = $this->actual_obj[1][1]['/Length'][1];	
+		        }
+		        
+		        if ($length > 0) {
+    		        $c->reset($startpos+$e,$length);
+    		        $v = $c->buffer;
+		        } else {
+		            $v = '';   
+		        }
+		        $c->reset($startpos+$e+$length+9); // 9 = strlen("endstream")
+		        
+		        return array(PDF_TYPE_STREAM, $v);
+		        
+    		default	:
+            	if (is_numeric ($token)) {
+                    // A numeric token. Make sure that
+    				// it is not part of something else.
+    				if (($tok2 = $this->pdf_read_token ($c)) !== false) {
+                        if (is_numeric ($tok2)) {
+
+    						// Two numeric tokens in a row.
+    						// In this case, we're probably in
+    						// front of either an object reference
+    						// or an object specification.
+    						// Determine the case and return the data
+    						if (($tok3 = $this->pdf_read_token ($c)) !== false) {
+                                switch ($tok3) {
+    								case	'obj'	:
+                                        return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2);
+    								case	'R'		:
+    									return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2);
+    							}
+    							// If we get to this point, that numeric value up
+    							// there was just a numeric value. Push the extra
+    							// tokens back into the stack and return the value.
+    							array_push ($c->stack, $tok3);
+    						}
+    					}
+
+    					array_push ($c->stack, $tok2);
+    				}
+
+    				return array (PDF_TYPE_NUMERIC, $token);
+    			} else {
+
+                    // Just a token. Return it.
+    				return array (PDF_TYPE_TOKEN, $token);
+    			}
+
+         }
+    }
+    
+    /**
+     * Resolve an object
+     *
+     * @param object $c pdf_context
+     * @param array $obj_spec The object-data
+     * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para
+     */
+    function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) {
+        // Exit if we get invalid data
+    	if (!is_array($obj_spec)) {
+            return false;
+    	}
+
+    	if ($obj_spec[0] == PDF_TYPE_OBJREF) {
+
+    		// This is a reference, resolve it
+    		if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) {
+
+    			// Save current file position
+    			// This is needed if you want to resolve
+    			// references while you're reading another object
+    			// (e.g.: if you need to determine the length
+    			// of a stream)
+
+    			$old_pos = ftell($c->file);
+
+    			// Reposition the file pointer and
+    			// load the object header.
+				
+    			$c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]);
+
+    			$header = $this->pdf_read_value($c,null,true);
+
+    			if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) {
+    				$this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location");
+    			}
+
+    			// If we're being asked to store all the information
+    			// about the object, we add the object ID and generation
+    			// number for later use
+				$this->actual_obj =& $result;
+    			if ($encapsulate) {
+    				$result = array (
+    					PDF_TYPE_OBJECT,
+    					'obj' => $obj_spec[1],
+    					'gen' => $obj_spec[2]
+    				);
+    			} else {
+    				$result = array();
+    			}
+
+    			// Now simply read the object data until
+    			// we encounter an end-of-object marker
+    			while(1) {
+                    $value = $this->pdf_read_value($c);
+					if ($value === false || count($result) > 4) {
+						// in this case the parser coudn't find an endobj so we break here
+						break;
+    				}
+
+    				if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') {
+    					break;
+    				}
+
+                    $result[] = $value;
+    			}
+
+    			$c->reset($old_pos);
+
+                if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) {
+                    $result[0] = PDF_TYPE_STREAM;
+                }
+
+    			return $result;
+    		}
+    	} else {
+    		return $obj_spec;
+    	}
+    }
+
+    
+    
+    /**
+     * Reads a token from the file
+     *
+     * @param object $c pdf_context
+     * @return mixed
+     */
+    function pdf_read_token(&$c)
+    {
+    	// If there is a token available
+    	// on the stack, pop it out and
+    	// return it.
+
+    	if (count($c->stack)) {
+    		return array_pop($c->stack);
+    	}
+
+    	// Strip away any whitespace
+
+    	do {
+    		if (!$c->ensure_content()) {
+    			return false;
+    		}
+    		$c->offset += _strspn($c->buffer, " \n\r\t", $c->offset);
+    	} while ($c->offset >= $c->length - 1);
+
+    	// Get the first character in the stream
+
+    	$char = $c->buffer[$c->offset++];
+
+    	switch ($char) {
+
+    		case '['	:
+    		case ']'	:
+    		case '('	:
+    		case ')'	:
+
+    			// This is either an array or literal string
+    			// delimiter, Return it
+
+    			return $char;
+
+    		case '<'	:
+    		case '>'	:
+
+    			// This could either be a hex string or
+    			// dictionary delimiter. Determine the
+    			// appropriate case and return the token
+
+    			if ($c->buffer[$c->offset] == $char) {
+    				if (!$c->ensure_content()) {
+    				    return false;
+    				}
+    				$c->offset++;
+    				return $char . $char;
+    			} else {
+    				return $char;
+    			}
+
+    		default		:
+
+    			// This is "another" type of token (probably
+    			// a dictionary entry or a numeric value)
+    			// Find the end and return it.
+
+    			if (!$c->ensure_content()) {
+    				return false;
+    			}
+
+    			while(1) {
+
+    				// Determine the length of the token
+
+    				$pos = _strcspn($c->buffer, " []<>()\r\n\t/", $c->offset);
+    				if ($c->offset + $pos <= $c->length - 1) {
+    					break;
+    				} else {
+    					// If the script reaches this point,
+    					// the token may span beyond the end
+    					// of the current buffer. Therefore,
+    					// we increase the size of the buffer
+    					// and try again--just to be safe.
+
+    					$c->increase_length();
+    				}
+    			}
+
+    			$result = substr($c->buffer, $c->offset - 1, $pos + 1);
+
+    			$c->offset += $pos;
+    			return $result;
+    	}
+    }
+
+	
+}
+
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/fpdf/fpdfi/wrapper_functions.php b/htdocs/includes/fpdf/fpdfi/wrapper_functions.php
index e069526f781dfbf596fc5ad60eb746263bf1339f..25706ca610a2d0594ccde598631432c3dcb2ba8d 100644
--- a/htdocs/includes/fpdf/fpdfi/wrapper_functions.php
+++ b/htdocs/includes/fpdf/fpdfi/wrapper_functions.php
@@ -1,88 +1,88 @@
-<?php
-//
-//  FPDI - Version 1.2
-//
-//    Copyright 2004-2007 Setasign - Jan Slabon
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-
-if (!defined("PHP_VER_LOWER43")) 
-	define("PHP_VER_LOWER43", version_compare(PHP_VERSION, "4.3", "<"));
-
-
-/**
- * ensure that strspn works correct if php-version < 4.3
- */
-function _strspn($str1, $str2, $start=null, $length=null) {
-    $numargs = func_num_args();
-
-    if (PHP_VER_LOWER43 == 1) {
-        if (isset($length)) {
-            $str1 = substr($str1, $start, $length);
-        } else {
-            $str1 = substr($str1, $start);
-        }
-    }
-
-    if ($numargs == 2 || PHP_VER_LOWER43 == 1) {
-        return strspn($str1, $str2);
-    } else if ($numargs == 3) {
-        return strspn($str1, $str2, $start);
-    } else {
-        return strspn($str1, $str2, $start, $length);
-    }
-}
-
-
-/**
- * ensure that strcspn works correct if php-version < 4.3
- */
-function _strcspn($str1, $str2, $start=null, $length=null) {
-    $numargs = func_num_args();
-
-    if (PHP_VER_LOWER43 == 1) {
-        if (isset($length)) {
-            $str1 = substr($str1, $start, $length);
-        } else {
-            $str1 = substr($str1, $start);
-        }
-    }
-
-    if ($numargs == 2 || PHP_VER_LOWER43 == 1) {
-        return strcspn($str1, $str2);
-    } else if ($numargs == 3) {
-        return strcspn($str1, $str2, $start);
-    } else {
-        return strcspn($str1, $str2, $start, $length);
-    }
-}
-
-
-/**
- * ensure that fgets works correct if php-version < 4.3
- */
-function _fgets (&$h, $force=false) {
-    $startpos = ftell($h);
-	$s = fgets($h, 1024);
-    
-    if ((PHP_VER_LOWER43 == 1 || $force) && preg_match("/^([^\r\n]*[\r\n]{1,2})(.)/",trim($s), $ns)) {
-		$s = $ns[1];
-		fseek($h,$startpos+strlen($s));
-	}
-	
-	return $s;
-}
-
+<?php
+//
+//  FPDI - Version 1.2
+//
+//    Copyright 2004-2007 Setasign - Jan Slabon
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+
+if (!defined("PHP_VER_LOWER43")) 
+	define("PHP_VER_LOWER43", version_compare(PHP_VERSION, "4.3", "<"));
+
+
+/**
+ * ensure that strspn works correct if php-version < 4.3
+ */
+function _strspn($str1, $str2, $start=null, $length=null) {
+    $numargs = func_num_args();
+
+    if (PHP_VER_LOWER43 == 1) {
+        if (isset($length)) {
+            $str1 = substr($str1, $start, $length);
+        } else {
+            $str1 = substr($str1, $start);
+        }
+    }
+
+    if ($numargs == 2 || PHP_VER_LOWER43 == 1) {
+        return strspn($str1, $str2);
+    } else if ($numargs == 3) {
+        return strspn($str1, $str2, $start);
+    } else {
+        return strspn($str1, $str2, $start, $length);
+    }
+}
+
+
+/**
+ * ensure that strcspn works correct if php-version < 4.3
+ */
+function _strcspn($str1, $str2, $start=null, $length=null) {
+    $numargs = func_num_args();
+
+    if (PHP_VER_LOWER43 == 1) {
+        if (isset($length)) {
+            $str1 = substr($str1, $start, $length);
+        } else {
+            $str1 = substr($str1, $start);
+        }
+    }
+
+    if ($numargs == 2 || PHP_VER_LOWER43 == 1) {
+        return strcspn($str1, $str2);
+    } else if ($numargs == 3) {
+        return strcspn($str1, $str2, $start);
+    } else {
+        return strcspn($str1, $str2, $start, $length);
+    }
+}
+
+
+/**
+ * ensure that fgets works correct if php-version < 4.3
+ */
+function _fgets (&$h, $force=false) {
+    $startpos = ftell($h);
+	$s = fgets($h, 1024);
+    
+    if ((PHP_VER_LOWER43 == 1 || $force) && preg_match("/^([^\r\n]*[\r\n]{1,2})(.)/",trim($s), $ns)) {
+		$s = $ns[1];
+		fseek($h,$startpos+strlen($s));
+	}
+	
+	return $s;
+}
+
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/login/functions_dolibarr.php b/htdocs/includes/login/functions_dolibarr.php
index aa56cf80aab0a19d0e66fa780d5633b8aeeaf4d0..482f968e7b8197edc135e024cd1c9233303303c6 100644
--- a/htdocs/includes/login/functions_dolibarr.php
+++ b/htdocs/includes/login/functions_dolibarr.php
@@ -1,115 +1,115 @@
-<?php
-/* Copyright (C) 2007-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/**
-        \file       htdocs/includes/login/functions_dolibarr.php
-        \ingroup    core
-        \brief      Authentication functions for Dolibarr mode
-		\version	$Id$
-*/
-
-
-/**
-        \brief		Check user and password
-        \param		usertotest		Login
-        \param		passwordtotest	Password
-        \return		string			Login if ok, '' if ko.
-*/
-function check_user_password_dolibarr($usertotest,$passwordtotest)
-{
-	global $_POST,$db,$conf,$langs;
-	
-	dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr usertotest=".$usertotest);
-
-	$login='';
-	
-	if (! empty($_POST["username"])) 
-	{
-		// If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko
-		$table = MAIN_DB_PREFIX."user";
-		$usernamecol = 'login';
-		
-		$sql ='SELECT pass, pass_crypted';
-		$sql.=' from '.$table;
-		$sql.=' where '.$usernamecol." = '".addslashes($_POST["username"])."'";
-
-		dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr sql=".$sql);
-		$resql=$db->query($sql);
-		if ($resql)
-		{
-			$obj=$db->fetch_object($resql);
-			if ($obj)
-			{
-				$passclear=$obj->pass;
-				$passcrypted=$obj->pass_crypted;
-				$passtyped=$_POST["password"];
-
-				$passok=false;
-				
-				// Check crypted password
-				$cryptType='';
-				if ($conf->global->DATABASE_PWD_ENCRYPTED) $cryptType='md5';
-				if ($cryptType == 'md5') 
-				{
-					if (md5($passtyped) == $passcrypted) $passok=true;
-				}
-
-				// For compatibility with old versions
-				if (! $passok)
-				{
-					if ((! $passcrypted || $passtyped) 
-						&& ($passtyped == $passclear)) $passok=true;
-				}
-				
-				// Password ok ?
-				if ($passok)
-				{
-					dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ok");
-					$login=$_POST["username"];
-				}
-				else
-				{
-					dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko bad password pour '".$_POST["username"]."'");
-					sleep(1);
-					$langs->load('main');
-					$langs->load('other');
-					$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
-				}
-			}
-			else
-			{
-				dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko user not found pour '".$_POST["username"]."'");
-				sleep(1);
-				$langs->load('main');
-				$langs->load('other');
-				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
-			}
-		}
-		else
-		{
-			dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko db error pour '".$_POST["username"]."' error=".$db->lasterror());
-			sleep(1);
-			$_SESSION["dol_loginmesg"]=$db->lasterror();
-		}
-	}
-
-	return $login;
-}
-
-
+<?php
+/* Copyright (C) 2007-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+        \file       htdocs/includes/login/functions_dolibarr.php
+        \ingroup    core
+        \brief      Authentication functions for Dolibarr mode
+		\version	$Id$
+*/
+
+
+/**
+        \brief		Check user and password
+        \param		usertotest		Login
+        \param		passwordtotest	Password
+        \return		string			Login if ok, '' if ko.
+*/
+function check_user_password_dolibarr($usertotest,$passwordtotest)
+{
+	global $_POST,$db,$conf,$langs;
+	
+	dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr usertotest=".$usertotest);
+
+	$login='';
+	
+	if (! empty($_POST["username"])) 
+	{
+		// If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko
+		$table = MAIN_DB_PREFIX."user";
+		$usernamecol = 'login';
+		
+		$sql ='SELECT pass, pass_crypted';
+		$sql.=' from '.$table;
+		$sql.=' where '.$usernamecol." = '".addslashes($_POST["username"])."'";
+
+		dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr sql=".$sql);
+		$resql=$db->query($sql);
+		if ($resql)
+		{
+			$obj=$db->fetch_object($resql);
+			if ($obj)
+			{
+				$passclear=$obj->pass;
+				$passcrypted=$obj->pass_crypted;
+				$passtyped=$_POST["password"];
+
+				$passok=false;
+				
+				// Check crypted password
+				$cryptType='';
+				if ($conf->global->DATABASE_PWD_ENCRYPTED) $cryptType='md5';
+				if ($cryptType == 'md5') 
+				{
+					if (md5($passtyped) == $passcrypted) $passok=true;
+				}
+
+				// For compatibility with old versions
+				if (! $passok)
+				{
+					if ((! $passcrypted || $passtyped) 
+						&& ($passtyped == $passclear)) $passok=true;
+				}
+				
+				// Password ok ?
+				if ($passok)
+				{
+					dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ok");
+					$login=$_POST["username"];
+				}
+				else
+				{
+					dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko bad password pour '".$_POST["username"]."'");
+					sleep(1);
+					$langs->load('main');
+					$langs->load('other');
+					$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
+				}
+			}
+			else
+			{
+				dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko user not found pour '".$_POST["username"]."'");
+				sleep(1);
+				$langs->load('main');
+				$langs->load('other');
+				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
+			}
+		}
+		else
+		{
+			dolibarr_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko db error pour '".$_POST["username"]."' error=".$db->lasterror());
+			sleep(1);
+			$_SESSION["dol_loginmesg"]=$db->lasterror();
+		}
+	}
+
+	return $login;
+}
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/login/functions_forceuser.php b/htdocs/includes/login/functions_forceuser.php
index 3b9158c936cd777080c3f60322612e9d9927deeb..8dfa652f50e6f81aac35475f180aaa59af9d552e 100644
--- a/htdocs/includes/login/functions_forceuser.php
+++ b/htdocs/includes/login/functions_forceuser.php
@@ -1,50 +1,50 @@
-<?php
-/* Copyright (C) 2007 Laurent Destailleur  <eldy@users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Id$
- */
-
-/**
-        \file       htdocs/includes/login/functions_forceuser.php
-        \ingroup    core
-        \brief      Authentication functions for forceuser
-*/
-
-
-/**
-        \brief		Check user and password
-        \param		usertotest		Login
-        \param		passwordtotest	Password
-        \return		string			Login if ok, '' if ko.
-*/
-function check_user_password_forceuser($usertotest,$passwordtotest)
-{
-	// Variable dolibarr_auto_user must be defined in conf.php file
-	global $dolibarr_auto_user;
-	
-	dolibarr_syslog("functions_forceuser::check_user_password_forceuser");
-
-	$login=$dolibarr_auto_user;
-	if (empty($login)) $login='auto';
-	
-	if ($_SESSION["dol_loginmesg"]) $login='';
-	
-	return $login;
-}
-
-
+<?php
+/* Copyright (C) 2007 Laurent Destailleur  <eldy@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+/**
+        \file       htdocs/includes/login/functions_forceuser.php
+        \ingroup    core
+        \brief      Authentication functions for forceuser
+*/
+
+
+/**
+        \brief		Check user and password
+        \param		usertotest		Login
+        \param		passwordtotest	Password
+        \return		string			Login if ok, '' if ko.
+*/
+function check_user_password_forceuser($usertotest,$passwordtotest)
+{
+	// Variable dolibarr_auto_user must be defined in conf.php file
+	global $dolibarr_auto_user;
+	
+	dolibarr_syslog("functions_forceuser::check_user_password_forceuser");
+
+	$login=$dolibarr_auto_user;
+	if (empty($login)) $login='auto';
+	
+	if ($_SESSION["dol_loginmesg"]) $login='';
+	
+	return $login;
+}
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/includes/treemenu/.cvsignore b/htdocs/includes/treemenu/.cvsignore
index da121b4f91cef0187935107bd78b50eace21955b..fb160255aec1f3c609c562a4e081a8cea06ba3e1 100644
--- a/htdocs/includes/treemenu/.cvsignore
+++ b/htdocs/includes/treemenu/.cvsignore
@@ -1,4 +1,4 @@
-docs
-imagesAlt
-imagesAlt2
-images
+docs
+imagesAlt
+imagesAlt2
+images
diff --git a/htdocs/oscommerce_ws/.cvsignore b/htdocs/oscommerce_ws/.cvsignore
index 42fa186ac90cfd749517addaf890fa84109b61d7..00a8138321363a9f5428e9b29bc2a097344d925c 100644
--- a/htdocs/oscommerce_ws/.cvsignore
+++ b/htdocs/oscommerce_ws/.cvsignore
@@ -1 +1 @@
-ws_client_demo
+ws_client_demo
diff --git a/htdocs/oscommerce_ws/ws_server/lib/changelog b/htdocs/oscommerce_ws/ws_server/lib/changelog
index fe8c5ca59f12020b347720a636b19a3634f9c1f1..b59d38c6d27d782608345ced01e46090fd028377 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/changelog
+++ b/htdocs/oscommerce_ws/ws_server/lib/changelog
@@ -1,438 +1,438 @@
-2003-07-21, version 0.6.5
-- soap_transport_http: SOAPAction header is quoted again, fixes problem w/ Weblogic Server
-- applied Jason Levitt patch for proper array serialization, fixes problem w/ Amazon shopping cart services
-- fixed null value serialization
-- applied patch from "BZC ToOn'S" - fixes wsdl serialization when no parameters
-- applied John's patch, implementing compression for the server
-
-2003-07-22, version 0.6.5
-- soap_server: fixed bug causing charset encoding not to be passed to the parser
-- soap_fault: added default encoding to the fault serialization
-- soap_parser: changed the parser to pre-load the parent's result array when processing scalar values. This increases parsing speed.
-
-2003-07-23, version 0.6.5
-- soap_base: fix code that overwrites user-supplied attributes in serialize_val
-- soap_base: use arrays-of-arrays rather than attempting multi-dimensional in serialize_val
-- xmlschema: emit import statements and qualify all elements with prefix in serializeSchema (better interop with validation tools)
-- soapclient: get xml character encoding from HTTP Content-Type header if provided, e.g. text/xml;charset="UTF-8"
-- soapclient: use headers in call if provided (previously ignored this parameter)
-- soap_server: in parse_request, if neither getallheaders nor $_SERVER are available, use $HTTP_SERVER_VARS to get SOAPAction and xml encoding
-
-2003-07-24, version 0.6.5
-- soap_transport_http: apply patch from Steven Brown "if the server closes connection prematurely, nusoap would spin trying to read data that isn't there"
-
-2003-07-25, version 0.6.5
-- wsdl: apply patch from Sven to workaround single schema limitation
-- wsdl: apply a variant of the patch from Holger to handle empty values for array by serializing an array with 0 elements
-- xmlschema: remove the redundant default namespace attribute on the schema element; everything in xsd is explicitly specified as being from xsd
-- soap_transport_http: fix setCredentials and add TODO comments in sendHTTPS about what to change if this setCredentials stays
-
-2003-07-30, version 0.6.5
-- nusoap_base: change documentation of soap_defencoding to specify it is the encoding for outgoing messages
-- nusoap_base: only change &, <, > to entities, not all HTML entities
-- soap_transport_http: update the Content-Type header in sendRequest, since soap_defencoding could be changed after ctor is called
-- soap_server: use soap_defencoding instead of charset_encoding
-- soap_server: read encoding from _SERVER if available
-- nusoap_base: do entity translation for string parameters with an xsd type specified (thanks David Derr)
-
-2003-07-31, version 0.6.5
-- soap_transport_http: add proxy authentication
-- soap_transport_http: build payload the same way for http and https
-- wsdl: add proxy authentication
-- soapclient: add proxy authentication
-- soapclient: allow proxy information in ctor, so that it can be used for wsdl
-
-2003-08-01, version 0.6.5
-- soap_transport_http: close a persistent connection that's at EOF
-- soap_transport_http: prevent conflicts between setEncoding and usePersistentConnection
-- soap_transport_http: fix use of $headers instead of $this->incoming_headers in getResponse
-- soapclient: improve handling of persistent connections
-- soapclient: force xml_encoding to upper case
-- soap_server: let the Web server decide whether to close the connection (no Connection: close header)
-- soap_server: force xml_encoding to upper case
-
-2003-08-04, version 0.6.5
-- soap_parser: use XML type information to pick a PHP data type; also decode base64
-- soap_server: read all HTTP headers when using _SERVER or HTTP_SERVER_VARS
-- soap_server: add gzip encoding support for outgoing messages
-- soap_transport_http: deflate is gzcompress/gzuncompress (cf. http://archive.develooper.com/libwww@perl.org/msg04650.html)
-- soap_transport_http: clean use of persistentConnection so it's always a set boolean
-- soapclient: add responseData member to access deflated/gunzipped payload
-
-2003-08-05, version 0.6.5
-- soap_server: look multiple places when setting debug_flag
-
-2003-08-07, version 0.6.5
-- nusoap_base: serialize specified type (e.g. ArrayOfString) even for simple array
-- wsdl: only specify encodingStyle in the input/output soap bindings when it is not empty (thanks Guillaume)
-
-2003-08-15, version 0.6.5
-- soap_parser: fix parsing of elements with no XSD type specified
-- soap_parser: use PHP string type for XSD long and unsignedLong types
-
-2003-08-16, version 0.6.5
-- soap_parser: fix code generating warning (thanks Torsten)
-
-2003-08-19, version 0.6.5
-- soap_parser: fix another line of code generating a warning (thanks Torsten)
-
-2003-08-22, version 0.6.5
-- soap_server: remove all '--' from debug_str; previous code changed '---' to '- --'
-- wsdl, soapclient, soap_parser: patch submitted by Mark Spavin as described by
-                                 the following...
-> Changes for the multiple/nested imports from the wsdl file. This builds an
-> array of files not just the last one and also checks for relative paths to
-> the parent. This will then get the imported files from the remote site
-> instead of your local disk. Local wsdl files should still work (untested).
->
-> Changes for multiple encoding sytles as previously posted
-
-2003-08-24, version 0.6.5
-- wsdl, soapclient: fix some PHP notices from previous update
-
-2003-08-26, version 0.6.5
-- wsdl: support multiple SOAP ports
-- soapclient, soap_server: when no charset is specified, use UTF-8, even though HTTP specifies US-ASCII.
-- soap_transport_http: do not prepend $host with 'ssl://' for https (is this required for older cURL versions?)
-
-2003-08-27, version 0.6.5
-- soap_server: support compressed request messages (thanks John Huong)
-- soap_parser: deserialize Apache Vector as an array
-- xmlschema: use $this->typemap in getPHPType (which is not used)
-- soapclient, wsdl: check for WSDL errors after serializing parameters
-- nusoap_base: add serialization of Apache Map (when not using WSDL)
-- wsdl: add serialization of Apache Map (when using WSDL)
-- wsdl: only change &, <, > to entities, not all HTML entities
-
-2003-08-28, version 0.6.5
-- soap_transport_http: disable cURL verification of peer and server (formerly the cURL default)
-- soap_transport_http: mingle cURL code with straight http, so sendHTTP is no longer needed
-
-2003-08-29, version 0.6.6
-- soap_transport_http: add setContentType
-- soapclient: call setContentType using new getHTTPContentType and getHTTPContentTypeCharset
-
-2003-09-05, version 0.6.6
-- wsdl: add some more code to handle null/nil values (but there's still a way to go)
-
-2003-10-21, version 0.6.6
-- soap_transport_http: only include port in Host header if it was specified in the URL
-- soap_transport_http: add some code to use OpenSSL for PHP ssl:// scheme, but comment out since it's not ready
-- soap_server: use $_SERVER['PHP_SELF'] if $GLOBALS['PHP_SELF'] is not set
-- wsdl: add WSDL request and response and transport debug to debug
-- wsdl: handle custom type extending xmlschema namespace (GLUE ... Thanks Matt)
-- soap_parser: add param to docs
-- soapclient: add getHTTPBody, getHTTPContentType, getHTTPContentTypeCharset (anticipating MIME subclass)
-
-2003-10-28, version 0.6.6
-- nusoap_base: add expandEntities method
-- wsdl: use expandEntities
-- soap_fault: use expandEntities
-- soap_transport_http: Allow credentials to be included in URL, rather than requiring setCredentials
-- soap_transport_http: Merge HTTP headers that span multiple lines
-- soap_parser: Properly set errors in ctor
-- soapclient: Pass headers to parseResponse and parse them in that method
-
-2003-10-30, version 0.6.6
-- xmlschema: Add some information for the related type to an element
-
-2003-12-09, version 0.6.6
-- nusoap_base: Add some namespace methods previously in xmlschema
-- xmlschema: Improve parsing of complexType, element and simpleType
-- xmlschema: Improve serialization
-- xmlschema: Track imports
-- xmlschema: Track elementFormDefault and form attributes
-- wsdl: Support multiple <schema> (note that setting $server->wsdl->schemaTargetNamespace no longer does anything!  Use configureWSDL instead.)
-- wsdl: Use form attribute of element to control namespace specification
-- wsdl: Support chained imports (A imports B which imports C)
-- wsdl: Include port in endpoint address when serializing
-- soap_server: Fix use of style (rpc|document) and use (encoded|literal)
-- soap_server: Support _SERVER[CONTENT_TYPE] in addition to _SERVER[HTTP_CONTENT_TYPE]
-- soap_server: Support wsdl with multiple <schema>
-- soap_client: Remove a var_dump
-- soap_client: Add style and use parameters to call method to support doc/lit without WSDL
-- soap_transport_http: Check that $this->fp exists when doing persistent connections
-
-2003-12-17, version 0.6.6
-- soap_server: pass namespaces to xmlschema constructor
-- wsdl: post-process after all imports
-- wsdl: remove some debug, add some error handling
-- xmlschema: allow enclosing namespaces to be specified in constructor
-- xmlschema: improve handling of compositors and simple types
-
-2004-01-08, version 0.6.6
-- soap_server: when requested WSDL is in a file, return to client using passthru (thanks Ingo Fischer)
-- soapclient: have proxy inherit more client state
-- soapclient: allow timeout and response timeout to be specified in the constructor
-- wsdl: allow timeout and response timeout to be specified in the constructor
-- soap_transport_http: allow response timeout to be specified in send and sendHTTPS
-
-2004-01-28, version 0.6.6
-- wsdl: add namespace for array and scalar when form is qualified
-- wsdl: fix a bug in which data type of complexType elements were ignored in serialization
-- wsdl: enhance handling of URLs with file scheme
-- wsdl: add addSimpleType
-- xmlschema: add addSimpleType
-- xmlschema: always set phpType elements
-- soapclient: allow a wsdl instance to be specified in constructor
-- soap_server: allow a wsdl instance to be specified in constructor (not tested!)
-- soap_server: fix default SOAPAction created in register method
-- soap_transport_http: accept chunking with LF separators in addition to CRLF.
-- wsdlcache: added class
-- nusoapmime: fix comments
-
-2004-02-23, version 0.6.6
-- soap_transport_http: don't try to unchunk cURL data, since cURL already does it
-- soap_transport_http: append CVS revision to version in User-Agent
-- wsdl: serialize boolean as true|false, not 1|0, to agree with XML Schema
-- soap_server: always exit() after returning WSDL
-- soap_server: use the WSDL URL scheme as the default endpoint URL scheme
-- soap_server: append CVS revision to version in X-SOAP-Server
-- nusoap_base: add (CVS) revision
-- wsdlcache: synchronize using a per-WSDL lock file (Thanks Ingo)
-- wsdlcache: add cache lifetime, after which cache contents are invalidated (Thanks Ingo)
-
-2004-03-15, version 0.6.6
-- nusoap_base: add isArraySimpleOrStruct method
-- soap_server: improve WSDL URL scheme determination
-- soap_server: only deflate/gzip payloads > 1024 bytes
-- soap_server: fix parameter order in fault method (always used as faultcode, faultstring)
-- soap_server: refactor parse_request into multiple functions (for sanity)
-- soap_server: set the namespace on the Response element to the same as the request
-- soap_server: name the return value element 'return' by default
-- soap_server: added and documented data fields, so that service programmers can use them if desired
-- soap_parser: standardize parsing error message
-- soap_parser: fix document and responseHeaders so they are the correct XML text (as documented)
-- soap_transport_http: fix read from persistent connection
-- soapclient: clean up debugging for persistent connection
-- wsdl: enforce correct naming of messages parts when an associative array is used for parameters
-- wsdl: better serialization of null values
-- wsdl: standardize parsing error message
-- xmlschema: standardize parsing error message
-
-2004-03-24, version 0.6.7
-- soap_transport_http: add digest authentication (based on code by Kevin A. Miller)
-- xmlschema: improve parsing of import elements
-- wsdl: do schema imports even if there are no wsdl imports
-
-2004-04-12, version 0.6.7
-- wsdl: serialize multiple elements when maxOccurs="unbounded" and value is an array
-- wsdl: serialize soapval values (used to force an XML type, e.g. when WSDL uses an abstract type)
-- nusoapmime: do not require nusoap.php (it is now the programmer's responsibility)
-
-2004-04-21, version 0.6.7
-- soap_parser: parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element)
-- soap_server: do not wrap response in a response element for a document style service
-
-2004-04-30, version 0.6.7
-- soap_transport_http: allow digest auth params to be separated by "," as well as ", "
-- soap_transport_http: re-initialize incoming headers for each response
-- soap_server: add methodreturnisliteralxml property to allow service function to return XML as a string
-- soapclient: improve rpc/literal support
-- soapclient: allow XML string as call params in addition to array
-- soapclient: support document style and literal encoding when not using WSDL
-
-2004-05-05, version 0.6.7
-- wsdl: serialize PHP objects for WSDL XML Schema complexTypes, in addition to associative arrays
-- wsdl: fix WSDL generation when there is no encodingStyle
-- soap_transport_http: suppress fsockopen warnings
-- soap_transport_http: detect socket timeouts when reading (0 bytes returned)
-- soap_transport_http: read chunked content "in-line" so it works on a persistent connection
-- nusoap_base: serialize boolean as true|false, not 1|0, to agree with XML Schema
-- nusoap_base: serialize array of struct differently than array of array
-
-2004-06-25, version 0.6.8
-- soap_server: prefer gzip to deflate, since IE does not like our deflate
-- soap_server: move webDescription to the wsdl class
-- soap_server: allow class and instance method calls for service (thanks Ingo Fischer and Roland Knall)
-- wsdl: get webDescription from the soap_server class
-- wsdl: allow compression from the server
-- wsdl: fix serialization of soapval without a type
-- wsdl: propagate debug value from query string to SOAP endpoint in programmatic WSDL generation
-- nusoap_base: add anyType, anySimpleType for 2001 XML Schema
-- nusoap_base: provide additional debug functions
-- soap_transport_http: ignore Content-Length when chunked encoding is used
-- soap_transport_http: remove ':' from username for Basic authentication (cf. RFC 2617)
-- soap_transport_http: urldecode username and password taken from URL
-- soap_transport_http: use raw inflate/deflate for IE/IIS compatibility, rather than having Zlib headers according to HTTP 1.1 spec
-- soap_transport_http: attempt to handle the case when both the service application and Web server compress the response
-- soapclient: when creating proxy methods, replace '.' in operation name with '__' in function name
-- soapclient: initialize requestHeaders in proxy
-- general: use new debug methods; never access debug_str directly
-
-2004-09-30, version 0.6.8
-- soapclient: do not allow getProxy call when WSDL is not used
-- soapclient: use ISO-8859-1 as the charset if not specified in the Content-Type header
-- soapclient: when an empty string is specified for the call namespace, do not put the method element in a namespace
-- soapclient: let soap_transport_http check for SSL support
-- soapclient: have proxy inherit soap_defencoding from the client from which it is generated
-- soapclient: do not assume that 'ns1' is an unused namespace prefix; always generate namespace prefixes randomly
-- soap_parser: compare any encoding in the XML declaration to the charset from the HTTP Content-Type header (thanks Ingo Fischer)
-- soap_parser: improve parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element)
-- soap_server: use ISO-8859-1 as the charset if not specified in the Content-Type header
-- soap_server: allow suppression of automatic UTF-8 decoding
-- soap_server: fix a bug when call_user_func_array() is used
-- soap_transport_http: correct digest authentication through a proxy
-- wsdl: serialize SOAP-ENC types similarly to XSD types
-- xmlschema: force unprefixed type into default namespace
-- xmlschema: fix serialization of definition of simple types
-
-2004-10-01, version 0.6.8
-- soap_parser: handle default namespace attributes
-- soap_server: add default_utf8 field
-- soap_server: support literal encoding (with RPC style)
-- soap_transport_http: parse HTTP status and generate error for 300, 302-307, 400, 401-417, 501-505 (thanks for the idea Ghislain)
-- soap_transport_http: follow HTTP redirection (HTTP status 301 and Location header) (thanks for the idea Ghislain)
-- xmlschema: allow any attributes to be specified in an element of a complexType, e.g., abstract, default, form, minOccurs, maxOccurs, nillable (thanks Jirka Pech for the original patch)
-
-2004-10-02, version 0.6.8
-- soapclient: read/write cookies (thanks Ingo)
-- soap_server: change faultcode on non-resendable faults to Client
-- soap_transport_http: read/write cookies (thanks Ingo)
-
-2004-10-05, version 0.6.8
-- wsdl: add addElement method
-- wsdl: support the document style in the register method
-- xmlschema: parse unnamed simpleTypes, rather than ignoring them
-- xmlschema: include untyped elements when parsing a complexType
-- xmlschema: add addElement method
-
-2004-10-14, version 0.6.8
-- soapclient: support client certificates
-- soap_parser: deserialize attributes, prefixing names with "!"
-- soap_server: notify the client with HTML when WSDL is requested but not supported by service
-- soap_transport_http: support client certificates
-- wsdl: support defaults for elements of a complexType
-- wsdl: serialize elements from complexType extension base
-- wsdl: serialize data (associative array elements) as attributes according to XML Schema
-- xmlschema: record extension base if present for a complexType
-
-2004-12-15, version 0.6.8
-- nusoap_base: add 2000 XML Schema (rare, but used by Akamai)
-- soap_parser: avoid deserializing more common attributes that are not data
-- soap_parser: be lax when HTTP specifies ISO-8859-1 (the default) and XML specifies UTF-8 (the norm)
-- soap_server: account for the fact that get_class_methods returns methods in all lower case (thanks Steve Haldane)
-- soap_transport_http: parse digest info that includes '=' in the data (thanks Jinsuk Kim)
-- wsdl: feably handle some cases for literal serialization of form="unqualified" elements
-- wsdl: don't serialize the decimal portion of a PHP double when the XML type is long
-- wsdl: fix serialization of attributes for complexType that is an extension
-- wsdlcache: enhance diagnostics
-- xmlschema: handle untyped elements
-- xmlschema: handle WSDL for SOAP Array that uses the base attribute plus a sequence of element
-
-2005-01-22, version 0.6.8
-- wsdl: allow an element in one schema to have a type from another schema
-
-2005-01-24, version 0.6.8
-- xmlschema: correctly parse nested complexType definitions
-
-2005-02-14, version 0.6.8
-- nusoap_base: fix a bug in which attributes were sometimes not serialized with a value
-- nusoap_base: improve serialization of null values (thanks Dominique Stender)
-- soap_parser: parse null values by handling the nil attribute (thanks Dominique Stender)
-- soap_server: set character encoding for a fault to be the same as for the server (thanks Mark Scott)
-- soap_server: correctly check for null value returned from method when WSDL is used (without WSDL, cannot distinguish whether NULL or void return is desired)
-- soapclient: for document style, call should always return an array rooted at the response part (all bets are off when there are multiple parts)
-- xmlschema: save enumeration values parsed from WSDL
-
-2005-02-10, version 0.6.9
-- soapclient: only set SOAP headers when they are specified in call params (so setHeaders still works)
-
-2005-04-04, version 0.6.9
-- soap_server: use get_class instead of is_a (thanks Thomas Noel)
-- soapclient: use get_class instead of is_a (thanks Thomas Noel)
-- soapclient: add setEndpoint method
-- soap_transport_http: fix client certificates (thanks Doug Anarino and Eryan Eriobowo)
-
-2005-04-29, version 0.6.9
-- nusoap_base: add global variable and methods for setting debug level
-- nusoap_base: use xsd:anyType instead of xsd:ur-type to serialize arrays with multiple element types (thanks Ingo Fischer)
-- nusoap_base: expand entities in attributes (thanks Gaetano Giunta)
-- soapclient: call parent constructor
-- soapval: call parent constructor
-- soap_fault: call parent constructor
-- soap_parser: call parent constructor
-- soap_server: assume get_class_methods always returns lower case for PHP 4.x only
-- soap_server: call parent constructor
-- soap_transport_http: do nothing in setEncoding if gzdeflate is not present (thanks Franck Touanen for pointing this out)
-- soap_transport_http: fix check for server request for digest authentication (thanks Mark Spavin)
-- soap_transport_http: call parent constructor
-- wsdl: fix documentation page popup of one method after another (thanks Owen)
-- wsdl: call parent constructor
-- wsdl: expand entities in attributes (thanks Gaetano Giunta)
-- xmlschema: call parent constructor
-
-2005-06-03, version 0.6.9
-- nusoap_base: serialize empty arrays as having elements xsd:anyType[0]
-- nusoap_base: add encodingStyle parameter to serializeEnvelope
-- nusoap_base: serialize xsi:type with nil values
-- nusoap_base: improve debug and comments
-- soap_parser: correctly parse an empty array to an empty array, not an empty string
-- soap_parser: improve debug and comments
-- soap_server: specify encodingStyle for envelope when WSDL is used
-- soapclient: factor out new getProxyClassCode method
-- soapclient: specify encodingStyle for envelope
-- soapclient: improve debug and comments
-- wsdl: add namespace for Apache SOAP types if a variable of such type is serialized
-- wsdl: serialize nil value for nillable elements when no value is provided
-- wsdl: serialize xsi:type with nil values
-- wsdl: copy attributes as well as elements to an element from its complexType
-- wsdl: specify encodingStyle for operations
-- wsdl: improve debug and comments
-- xmlschema: improve debug and comments
-
-2005-06-03, version 0.7.0
-- nusoap_base: improve debug and comments
-- nusoap_base: fix version, which should have been 0.7.0 since 2005-03-04
-
-2005-06-06, version 0.7.1
-- nusoap_base: adjust numeric element names for serialization, instead of forcing them to 'soapVal'
-- nusoapmime: add type=text/xml to multipart/related (thanks Emmanuel Cordonnier)
-- soap_fault: fix serialization of detail
-- soap_server: check required parameters for register method
-- soap_server: when getallheaders is used, massage header names
-- soap_server: use SOAPAction to determine operation when doc/lit service does not wrap parameters in an element with the method name (thanks Peter Hrastnik)
-- soap_transport_http: correctly handle multiple HTTP/1.1 100 responses for https (thanks Jan Slabon)
-- wsdl: fixed documentation for addComplexType (thanks Csintalan �d�m)
-- wsdl: serialize array data when maxOccurs = 'unbounded' OR maxOccurs > 1 (thanks Dominique Schreckling)
-- wsdl: when serializing a string == 'false' as a boolean, set the value to false
-- wsdl: when serializing a complexType, require the PHP value supplied to be an array
-
-2005-07-01, version 0.7.1
-- nusoap_base: Allow SOAP headers to be supplied as an array like parameters
-- soap_parser: de-serialize simpleContent that accompanies complexContent
-- soap_server: append debug information when programmatically-defined WSDL is returned
-- soap_transport_http: Add debug when an outgoing header is set
-- soapclient: Allow SOAP headers to be supplied as an array like parameters
-- xmlschema: serialize attributes more generally, rather than assuming they are for SOAP 1.1 Array
-- wsdl: when serializing, look up types by namespace, not prefix (simple programmatic doc/lit WSDL now seems to work)
-- wsdl: process namespace declarations first when parsing an element
-
-2005-07-27, version 0.7.1
-- nusoap_base: do not override supplied element name with class name when serializing an object in serialize_val
-- nusoap_base: remove http://soapinterop.org/xsd (si) from namespaces array
-- nusoapmime: add nusoapservermime class to implement MIME attachments on the server
-- soap_fault: improve documentation
-- soap_server: improve documentation
-- soap_server: make consistent use of _SERVER and HTTP_SERVER_VARS
-- soap_server: make all incoming HTTP header keys lower case
-- soap_server: add hook functions to support subclassing for MIME attachments
-- soap_transport_http: remove an unnecessary global statement
-- soapclient: when creating a proxy, make $params within each function an associative array
-- soapval: improve documentation
-- wsdl: when serializing complexType elements, used typed serialization if there is either a type or a reference for the element
-- wsdl: allow PHP objects to be serialized as SOAP structs in serializeType
-- wsdl: for WSDL and XML Schema imports, don't forget to use the TCP port number (thanks Luca GIOPPO)
-- wsdl: make consistent use of _SERVER and HTTP_SERVER_VARS
-- xmlschema: improve documentation
-
-2005-07-31, version 0.7.2
-- nusoap_base: correctly serialize attributes in serialize_val (thanks Hidran Arias)
-- soap_parser: when resolving references, do not assume that buildVal returns an array (thanks Akshell)
-- soap_parser: removed decode_entities, which does not work (thanks Martin Sarsale)
-- soap_server: fix a bug parsing headers from _SERVER and HTTP_SERVER_VARS (thanks Bert Catsburg)
-- soap_server: parse all "headers" from HTTP_SERVER_VARS (not just HTTP_*)
-- soap_server: use PHP_SELF instead of SCRIPT_NAME for WSDL endpoint
-- soap_server: when generating a fault while debug_flag is true, put debug into faultdetail
-- wsdl: add enumeration parameter to addSimpleType
-- xmlschema: add enumeration parameter to addSimpleType
+2003-07-21, version 0.6.5
+- soap_transport_http: SOAPAction header is quoted again, fixes problem w/ Weblogic Server
+- applied Jason Levitt patch for proper array serialization, fixes problem w/ Amazon shopping cart services
+- fixed null value serialization
+- applied patch from "BZC ToOn'S" - fixes wsdl serialization when no parameters
+- applied John's patch, implementing compression for the server
+
+2003-07-22, version 0.6.5
+- soap_server: fixed bug causing charset encoding not to be passed to the parser
+- soap_fault: added default encoding to the fault serialization
+- soap_parser: changed the parser to pre-load the parent's result array when processing scalar values. This increases parsing speed.
+
+2003-07-23, version 0.6.5
+- soap_base: fix code that overwrites user-supplied attributes in serialize_val
+- soap_base: use arrays-of-arrays rather than attempting multi-dimensional in serialize_val
+- xmlschema: emit import statements and qualify all elements with prefix in serializeSchema (better interop with validation tools)
+- soapclient: get xml character encoding from HTTP Content-Type header if provided, e.g. text/xml;charset="UTF-8"
+- soapclient: use headers in call if provided (previously ignored this parameter)
+- soap_server: in parse_request, if neither getallheaders nor $_SERVER are available, use $HTTP_SERVER_VARS to get SOAPAction and xml encoding
+
+2003-07-24, version 0.6.5
+- soap_transport_http: apply patch from Steven Brown "if the server closes connection prematurely, nusoap would spin trying to read data that isn't there"
+
+2003-07-25, version 0.6.5
+- wsdl: apply patch from Sven to workaround single schema limitation
+- wsdl: apply a variant of the patch from Holger to handle empty values for array by serializing an array with 0 elements
+- xmlschema: remove the redundant default namespace attribute on the schema element; everything in xsd is explicitly specified as being from xsd
+- soap_transport_http: fix setCredentials and add TODO comments in sendHTTPS about what to change if this setCredentials stays
+
+2003-07-30, version 0.6.5
+- nusoap_base: change documentation of soap_defencoding to specify it is the encoding for outgoing messages
+- nusoap_base: only change &, <, > to entities, not all HTML entities
+- soap_transport_http: update the Content-Type header in sendRequest, since soap_defencoding could be changed after ctor is called
+- soap_server: use soap_defencoding instead of charset_encoding
+- soap_server: read encoding from _SERVER if available
+- nusoap_base: do entity translation for string parameters with an xsd type specified (thanks David Derr)
+
+2003-07-31, version 0.6.5
+- soap_transport_http: add proxy authentication
+- soap_transport_http: build payload the same way for http and https
+- wsdl: add proxy authentication
+- soapclient: add proxy authentication
+- soapclient: allow proxy information in ctor, so that it can be used for wsdl
+
+2003-08-01, version 0.6.5
+- soap_transport_http: close a persistent connection that's at EOF
+- soap_transport_http: prevent conflicts between setEncoding and usePersistentConnection
+- soap_transport_http: fix use of $headers instead of $this->incoming_headers in getResponse
+- soapclient: improve handling of persistent connections
+- soapclient: force xml_encoding to upper case
+- soap_server: let the Web server decide whether to close the connection (no Connection: close header)
+- soap_server: force xml_encoding to upper case
+
+2003-08-04, version 0.6.5
+- soap_parser: use XML type information to pick a PHP data type; also decode base64
+- soap_server: read all HTTP headers when using _SERVER or HTTP_SERVER_VARS
+- soap_server: add gzip encoding support for outgoing messages
+- soap_transport_http: deflate is gzcompress/gzuncompress (cf. http://archive.develooper.com/libwww@perl.org/msg04650.html)
+- soap_transport_http: clean use of persistentConnection so it's always a set boolean
+- soapclient: add responseData member to access deflated/gunzipped payload
+
+2003-08-05, version 0.6.5
+- soap_server: look multiple places when setting debug_flag
+
+2003-08-07, version 0.6.5
+- nusoap_base: serialize specified type (e.g. ArrayOfString) even for simple array
+- wsdl: only specify encodingStyle in the input/output soap bindings when it is not empty (thanks Guillaume)
+
+2003-08-15, version 0.6.5
+- soap_parser: fix parsing of elements with no XSD type specified
+- soap_parser: use PHP string type for XSD long and unsignedLong types
+
+2003-08-16, version 0.6.5
+- soap_parser: fix code generating warning (thanks Torsten)
+
+2003-08-19, version 0.6.5
+- soap_parser: fix another line of code generating a warning (thanks Torsten)
+
+2003-08-22, version 0.6.5
+- soap_server: remove all '--' from debug_str; previous code changed '---' to '- --'
+- wsdl, soapclient, soap_parser: patch submitted by Mark Spavin as described by
+                                 the following...
+> Changes for the multiple/nested imports from the wsdl file. This builds an
+> array of files not just the last one and also checks for relative paths to
+> the parent. This will then get the imported files from the remote site
+> instead of your local disk. Local wsdl files should still work (untested).
+>
+> Changes for multiple encoding sytles as previously posted
+
+2003-08-24, version 0.6.5
+- wsdl, soapclient: fix some PHP notices from previous update
+
+2003-08-26, version 0.6.5
+- wsdl: support multiple SOAP ports
+- soapclient, soap_server: when no charset is specified, use UTF-8, even though HTTP specifies US-ASCII.
+- soap_transport_http: do not prepend $host with 'ssl://' for https (is this required for older cURL versions?)
+
+2003-08-27, version 0.6.5
+- soap_server: support compressed request messages (thanks John Huong)
+- soap_parser: deserialize Apache Vector as an array
+- xmlschema: use $this->typemap in getPHPType (which is not used)
+- soapclient, wsdl: check for WSDL errors after serializing parameters
+- nusoap_base: add serialization of Apache Map (when not using WSDL)
+- wsdl: add serialization of Apache Map (when using WSDL)
+- wsdl: only change &, <, > to entities, not all HTML entities
+
+2003-08-28, version 0.6.5
+- soap_transport_http: disable cURL verification of peer and server (formerly the cURL default)
+- soap_transport_http: mingle cURL code with straight http, so sendHTTP is no longer needed
+
+2003-08-29, version 0.6.6
+- soap_transport_http: add setContentType
+- soapclient: call setContentType using new getHTTPContentType and getHTTPContentTypeCharset
+
+2003-09-05, version 0.6.6
+- wsdl: add some more code to handle null/nil values (but there's still a way to go)
+
+2003-10-21, version 0.6.6
+- soap_transport_http: only include port in Host header if it was specified in the URL
+- soap_transport_http: add some code to use OpenSSL for PHP ssl:// scheme, but comment out since it's not ready
+- soap_server: use $_SERVER['PHP_SELF'] if $GLOBALS['PHP_SELF'] is not set
+- wsdl: add WSDL request and response and transport debug to debug
+- wsdl: handle custom type extending xmlschema namespace (GLUE ... Thanks Matt)
+- soap_parser: add param to docs
+- soapclient: add getHTTPBody, getHTTPContentType, getHTTPContentTypeCharset (anticipating MIME subclass)
+
+2003-10-28, version 0.6.6
+- nusoap_base: add expandEntities method
+- wsdl: use expandEntities
+- soap_fault: use expandEntities
+- soap_transport_http: Allow credentials to be included in URL, rather than requiring setCredentials
+- soap_transport_http: Merge HTTP headers that span multiple lines
+- soap_parser: Properly set errors in ctor
+- soapclient: Pass headers to parseResponse and parse them in that method
+
+2003-10-30, version 0.6.6
+- xmlschema: Add some information for the related type to an element
+
+2003-12-09, version 0.6.6
+- nusoap_base: Add some namespace methods previously in xmlschema
+- xmlschema: Improve parsing of complexType, element and simpleType
+- xmlschema: Improve serialization
+- xmlschema: Track imports
+- xmlschema: Track elementFormDefault and form attributes
+- wsdl: Support multiple <schema> (note that setting $server->wsdl->schemaTargetNamespace no longer does anything!  Use configureWSDL instead.)
+- wsdl: Use form attribute of element to control namespace specification
+- wsdl: Support chained imports (A imports B which imports C)
+- wsdl: Include port in endpoint address when serializing
+- soap_server: Fix use of style (rpc|document) and use (encoded|literal)
+- soap_server: Support _SERVER[CONTENT_TYPE] in addition to _SERVER[HTTP_CONTENT_TYPE]
+- soap_server: Support wsdl with multiple <schema>
+- soap_client: Remove a var_dump
+- soap_client: Add style and use parameters to call method to support doc/lit without WSDL
+- soap_transport_http: Check that $this->fp exists when doing persistent connections
+
+2003-12-17, version 0.6.6
+- soap_server: pass namespaces to xmlschema constructor
+- wsdl: post-process after all imports
+- wsdl: remove some debug, add some error handling
+- xmlschema: allow enclosing namespaces to be specified in constructor
+- xmlschema: improve handling of compositors and simple types
+
+2004-01-08, version 0.6.6
+- soap_server: when requested WSDL is in a file, return to client using passthru (thanks Ingo Fischer)
+- soapclient: have proxy inherit more client state
+- soapclient: allow timeout and response timeout to be specified in the constructor
+- wsdl: allow timeout and response timeout to be specified in the constructor
+- soap_transport_http: allow response timeout to be specified in send and sendHTTPS
+
+2004-01-28, version 0.6.6
+- wsdl: add namespace for array and scalar when form is qualified
+- wsdl: fix a bug in which data type of complexType elements were ignored in serialization
+- wsdl: enhance handling of URLs with file scheme
+- wsdl: add addSimpleType
+- xmlschema: add addSimpleType
+- xmlschema: always set phpType elements
+- soapclient: allow a wsdl instance to be specified in constructor
+- soap_server: allow a wsdl instance to be specified in constructor (not tested!)
+- soap_server: fix default SOAPAction created in register method
+- soap_transport_http: accept chunking with LF separators in addition to CRLF.
+- wsdlcache: added class
+- nusoapmime: fix comments
+
+2004-02-23, version 0.6.6
+- soap_transport_http: don't try to unchunk cURL data, since cURL already does it
+- soap_transport_http: append CVS revision to version in User-Agent
+- wsdl: serialize boolean as true|false, not 1|0, to agree with XML Schema
+- soap_server: always exit() after returning WSDL
+- soap_server: use the WSDL URL scheme as the default endpoint URL scheme
+- soap_server: append CVS revision to version in X-SOAP-Server
+- nusoap_base: add (CVS) revision
+- wsdlcache: synchronize using a per-WSDL lock file (Thanks Ingo)
+- wsdlcache: add cache lifetime, after which cache contents are invalidated (Thanks Ingo)
+
+2004-03-15, version 0.6.6
+- nusoap_base: add isArraySimpleOrStruct method
+- soap_server: improve WSDL URL scheme determination
+- soap_server: only deflate/gzip payloads > 1024 bytes
+- soap_server: fix parameter order in fault method (always used as faultcode, faultstring)
+- soap_server: refactor parse_request into multiple functions (for sanity)
+- soap_server: set the namespace on the Response element to the same as the request
+- soap_server: name the return value element 'return' by default
+- soap_server: added and documented data fields, so that service programmers can use them if desired
+- soap_parser: standardize parsing error message
+- soap_parser: fix document and responseHeaders so they are the correct XML text (as documented)
+- soap_transport_http: fix read from persistent connection
+- soapclient: clean up debugging for persistent connection
+- wsdl: enforce correct naming of messages parts when an associative array is used for parameters
+- wsdl: better serialization of null values
+- wsdl: standardize parsing error message
+- xmlschema: standardize parsing error message
+
+2004-03-24, version 0.6.7
+- soap_transport_http: add digest authentication (based on code by Kevin A. Miller)
+- xmlschema: improve parsing of import elements
+- wsdl: do schema imports even if there are no wsdl imports
+
+2004-04-12, version 0.6.7
+- wsdl: serialize multiple elements when maxOccurs="unbounded" and value is an array
+- wsdl: serialize soapval values (used to force an XML type, e.g. when WSDL uses an abstract type)
+- nusoapmime: do not require nusoap.php (it is now the programmer's responsibility)
+
+2004-04-21, version 0.6.7
+- soap_parser: parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element)
+- soap_server: do not wrap response in a response element for a document style service
+
+2004-04-30, version 0.6.7
+- soap_transport_http: allow digest auth params to be separated by "," as well as ", "
+- soap_transport_http: re-initialize incoming headers for each response
+- soap_server: add methodreturnisliteralxml property to allow service function to return XML as a string
+- soapclient: improve rpc/literal support
+- soapclient: allow XML string as call params in addition to array
+- soapclient: support document style and literal encoding when not using WSDL
+
+2004-05-05, version 0.6.7
+- wsdl: serialize PHP objects for WSDL XML Schema complexTypes, in addition to associative arrays
+- wsdl: fix WSDL generation when there is no encodingStyle
+- soap_transport_http: suppress fsockopen warnings
+- soap_transport_http: detect socket timeouts when reading (0 bytes returned)
+- soap_transport_http: read chunked content "in-line" so it works on a persistent connection
+- nusoap_base: serialize boolean as true|false, not 1|0, to agree with XML Schema
+- nusoap_base: serialize array of struct differently than array of array
+
+2004-06-25, version 0.6.8
+- soap_server: prefer gzip to deflate, since IE does not like our deflate
+- soap_server: move webDescription to the wsdl class
+- soap_server: allow class and instance method calls for service (thanks Ingo Fischer and Roland Knall)
+- wsdl: get webDescription from the soap_server class
+- wsdl: allow compression from the server
+- wsdl: fix serialization of soapval without a type
+- wsdl: propagate debug value from query string to SOAP endpoint in programmatic WSDL generation
+- nusoap_base: add anyType, anySimpleType for 2001 XML Schema
+- nusoap_base: provide additional debug functions
+- soap_transport_http: ignore Content-Length when chunked encoding is used
+- soap_transport_http: remove ':' from username for Basic authentication (cf. RFC 2617)
+- soap_transport_http: urldecode username and password taken from URL
+- soap_transport_http: use raw inflate/deflate for IE/IIS compatibility, rather than having Zlib headers according to HTTP 1.1 spec
+- soap_transport_http: attempt to handle the case when both the service application and Web server compress the response
+- soapclient: when creating proxy methods, replace '.' in operation name with '__' in function name
+- soapclient: initialize requestHeaders in proxy
+- general: use new debug methods; never access debug_str directly
+
+2004-09-30, version 0.6.8
+- soapclient: do not allow getProxy call when WSDL is not used
+- soapclient: use ISO-8859-1 as the charset if not specified in the Content-Type header
+- soapclient: when an empty string is specified for the call namespace, do not put the method element in a namespace
+- soapclient: let soap_transport_http check for SSL support
+- soapclient: have proxy inherit soap_defencoding from the client from which it is generated
+- soapclient: do not assume that 'ns1' is an unused namespace prefix; always generate namespace prefixes randomly
+- soap_parser: compare any encoding in the XML declaration to the charset from the HTTP Content-Type header (thanks Ingo Fischer)
+- soap_parser: improve parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element)
+- soap_server: use ISO-8859-1 as the charset if not specified in the Content-Type header
+- soap_server: allow suppression of automatic UTF-8 decoding
+- soap_server: fix a bug when call_user_func_array() is used
+- soap_transport_http: correct digest authentication through a proxy
+- wsdl: serialize SOAP-ENC types similarly to XSD types
+- xmlschema: force unprefixed type into default namespace
+- xmlschema: fix serialization of definition of simple types
+
+2004-10-01, version 0.6.8
+- soap_parser: handle default namespace attributes
+- soap_server: add default_utf8 field
+- soap_server: support literal encoding (with RPC style)
+- soap_transport_http: parse HTTP status and generate error for 300, 302-307, 400, 401-417, 501-505 (thanks for the idea Ghislain)
+- soap_transport_http: follow HTTP redirection (HTTP status 301 and Location header) (thanks for the idea Ghislain)
+- xmlschema: allow any attributes to be specified in an element of a complexType, e.g., abstract, default, form, minOccurs, maxOccurs, nillable (thanks Jirka Pech for the original patch)
+
+2004-10-02, version 0.6.8
+- soapclient: read/write cookies (thanks Ingo)
+- soap_server: change faultcode on non-resendable faults to Client
+- soap_transport_http: read/write cookies (thanks Ingo)
+
+2004-10-05, version 0.6.8
+- wsdl: add addElement method
+- wsdl: support the document style in the register method
+- xmlschema: parse unnamed simpleTypes, rather than ignoring them
+- xmlschema: include untyped elements when parsing a complexType
+- xmlschema: add addElement method
+
+2004-10-14, version 0.6.8
+- soapclient: support client certificates
+- soap_parser: deserialize attributes, prefixing names with "!"
+- soap_server: notify the client with HTML when WSDL is requested but not supported by service
+- soap_transport_http: support client certificates
+- wsdl: support defaults for elements of a complexType
+- wsdl: serialize elements from complexType extension base
+- wsdl: serialize data (associative array elements) as attributes according to XML Schema
+- xmlschema: record extension base if present for a complexType
+
+2004-12-15, version 0.6.8
+- nusoap_base: add 2000 XML Schema (rare, but used by Akamai)
+- soap_parser: avoid deserializing more common attributes that are not data
+- soap_parser: be lax when HTTP specifies ISO-8859-1 (the default) and XML specifies UTF-8 (the norm)
+- soap_server: account for the fact that get_class_methods returns methods in all lower case (thanks Steve Haldane)
+- soap_transport_http: parse digest info that includes '=' in the data (thanks Jinsuk Kim)
+- wsdl: feably handle some cases for literal serialization of form="unqualified" elements
+- wsdl: don't serialize the decimal portion of a PHP double when the XML type is long
+- wsdl: fix serialization of attributes for complexType that is an extension
+- wsdlcache: enhance diagnostics
+- xmlschema: handle untyped elements
+- xmlschema: handle WSDL for SOAP Array that uses the base attribute plus a sequence of element
+
+2005-01-22, version 0.6.8
+- wsdl: allow an element in one schema to have a type from another schema
+
+2005-01-24, version 0.6.8
+- xmlschema: correctly parse nested complexType definitions
+
+2005-02-14, version 0.6.8
+- nusoap_base: fix a bug in which attributes were sometimes not serialized with a value
+- nusoap_base: improve serialization of null values (thanks Dominique Stender)
+- soap_parser: parse null values by handling the nil attribute (thanks Dominique Stender)
+- soap_server: set character encoding for a fault to be the same as for the server (thanks Mark Scott)
+- soap_server: correctly check for null value returned from method when WSDL is used (without WSDL, cannot distinguish whether NULL or void return is desired)
+- soapclient: for document style, call should always return an array rooted at the response part (all bets are off when there are multiple parts)
+- xmlschema: save enumeration values parsed from WSDL
+
+2005-02-10, version 0.6.9
+- soapclient: only set SOAP headers when they are specified in call params (so setHeaders still works)
+
+2005-04-04, version 0.6.9
+- soap_server: use get_class instead of is_a (thanks Thomas Noel)
+- soapclient: use get_class instead of is_a (thanks Thomas Noel)
+- soapclient: add setEndpoint method
+- soap_transport_http: fix client certificates (thanks Doug Anarino and Eryan Eriobowo)
+
+2005-04-29, version 0.6.9
+- nusoap_base: add global variable and methods for setting debug level
+- nusoap_base: use xsd:anyType instead of xsd:ur-type to serialize arrays with multiple element types (thanks Ingo Fischer)
+- nusoap_base: expand entities in attributes (thanks Gaetano Giunta)
+- soapclient: call parent constructor
+- soapval: call parent constructor
+- soap_fault: call parent constructor
+- soap_parser: call parent constructor
+- soap_server: assume get_class_methods always returns lower case for PHP 4.x only
+- soap_server: call parent constructor
+- soap_transport_http: do nothing in setEncoding if gzdeflate is not present (thanks Franck Touanen for pointing this out)
+- soap_transport_http: fix check for server request for digest authentication (thanks Mark Spavin)
+- soap_transport_http: call parent constructor
+- wsdl: fix documentation page popup of one method after another (thanks Owen)
+- wsdl: call parent constructor
+- wsdl: expand entities in attributes (thanks Gaetano Giunta)
+- xmlschema: call parent constructor
+
+2005-06-03, version 0.6.9
+- nusoap_base: serialize empty arrays as having elements xsd:anyType[0]
+- nusoap_base: add encodingStyle parameter to serializeEnvelope
+- nusoap_base: serialize xsi:type with nil values
+- nusoap_base: improve debug and comments
+- soap_parser: correctly parse an empty array to an empty array, not an empty string
+- soap_parser: improve debug and comments
+- soap_server: specify encodingStyle for envelope when WSDL is used
+- soapclient: factor out new getProxyClassCode method
+- soapclient: specify encodingStyle for envelope
+- soapclient: improve debug and comments
+- wsdl: add namespace for Apache SOAP types if a variable of such type is serialized
+- wsdl: serialize nil value for nillable elements when no value is provided
+- wsdl: serialize xsi:type with nil values
+- wsdl: copy attributes as well as elements to an element from its complexType
+- wsdl: specify encodingStyle for operations
+- wsdl: improve debug and comments
+- xmlschema: improve debug and comments
+
+2005-06-03, version 0.7.0
+- nusoap_base: improve debug and comments
+- nusoap_base: fix version, which should have been 0.7.0 since 2005-03-04
+
+2005-06-06, version 0.7.1
+- nusoap_base: adjust numeric element names for serialization, instead of forcing them to 'soapVal'
+- nusoapmime: add type=text/xml to multipart/related (thanks Emmanuel Cordonnier)
+- soap_fault: fix serialization of detail
+- soap_server: check required parameters for register method
+- soap_server: when getallheaders is used, massage header names
+- soap_server: use SOAPAction to determine operation when doc/lit service does not wrap parameters in an element with the method name (thanks Peter Hrastnik)
+- soap_transport_http: correctly handle multiple HTTP/1.1 100 responses for https (thanks Jan Slabon)
+- wsdl: fixed documentation for addComplexType (thanks Csintalan �d�m)
+- wsdl: serialize array data when maxOccurs = 'unbounded' OR maxOccurs > 1 (thanks Dominique Schreckling)
+- wsdl: when serializing a string == 'false' as a boolean, set the value to false
+- wsdl: when serializing a complexType, require the PHP value supplied to be an array
+
+2005-07-01, version 0.7.1
+- nusoap_base: Allow SOAP headers to be supplied as an array like parameters
+- soap_parser: de-serialize simpleContent that accompanies complexContent
+- soap_server: append debug information when programmatically-defined WSDL is returned
+- soap_transport_http: Add debug when an outgoing header is set
+- soapclient: Allow SOAP headers to be supplied as an array like parameters
+- xmlschema: serialize attributes more generally, rather than assuming they are for SOAP 1.1 Array
+- wsdl: when serializing, look up types by namespace, not prefix (simple programmatic doc/lit WSDL now seems to work)
+- wsdl: process namespace declarations first when parsing an element
+
+2005-07-27, version 0.7.1
+- nusoap_base: do not override supplied element name with class name when serializing an object in serialize_val
+- nusoap_base: remove http://soapinterop.org/xsd (si) from namespaces array
+- nusoapmime: add nusoapservermime class to implement MIME attachments on the server
+- soap_fault: improve documentation
+- soap_server: improve documentation
+- soap_server: make consistent use of _SERVER and HTTP_SERVER_VARS
+- soap_server: make all incoming HTTP header keys lower case
+- soap_server: add hook functions to support subclassing for MIME attachments
+- soap_transport_http: remove an unnecessary global statement
+- soapclient: when creating a proxy, make $params within each function an associative array
+- soapval: improve documentation
+- wsdl: when serializing complexType elements, used typed serialization if there is either a type or a reference for the element
+- wsdl: allow PHP objects to be serialized as SOAP structs in serializeType
+- wsdl: for WSDL and XML Schema imports, don't forget to use the TCP port number (thanks Luca GIOPPO)
+- wsdl: make consistent use of _SERVER and HTTP_SERVER_VARS
+- xmlschema: improve documentation
+
+2005-07-31, version 0.7.2
+- nusoap_base: correctly serialize attributes in serialize_val (thanks Hidran Arias)
+- soap_parser: when resolving references, do not assume that buildVal returns an array (thanks Akshell)
+- soap_parser: removed decode_entities, which does not work (thanks Martin Sarsale)
+- soap_server: fix a bug parsing headers from _SERVER and HTTP_SERVER_VARS (thanks Bert Catsburg)
+- soap_server: parse all "headers" from HTTP_SERVER_VARS (not just HTTP_*)
+- soap_server: use PHP_SELF instead of SCRIPT_NAME for WSDL endpoint
+- soap_server: when generating a fault while debug_flag is true, put debug into faultdetail
+- wsdl: add enumeration parameter to addSimpleType
+- xmlschema: add enumeration parameter to addSimpleType
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.nusoap_base.php b/htdocs/oscommerce_ws/ws_server/lib/class.nusoap_base.php
index fdf7fb7771daaeace3031f3972cd2cd5aada8d77..a74e83e0e03104217d48be0b145139291461be9a 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.nusoap_base.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.nusoap_base.php
@@ -1,905 +1,905 @@
-<?php
-
-/*
-$Id$
-
-NuSOAP - Web Services Toolkit for PHP
-
-Copyright (c) 2002 NuSphere Corporation
-
-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
-
-If you have any questions or comments, please email:
-
-Dietrich Ayala
-dietrich@ganx4.com
-http://dietrich.ganx4.com/nusoap
-
-NuSphere Corporation
-http://www.nusphere.com
-
-*/
-
-/* load classes
-
-// necessary classes
-require_once('class.soapclient.php');
-require_once('class.soap_val.php');
-require_once('class.soap_parser.php');
-require_once('class.soap_fault.php');
-
-// transport classes
-require_once('class.soap_transport_http.php');
-
-// optional add-on classes
-require_once('class.xmlschema.php');
-require_once('class.wsdl.php');
-
-// server class
-require_once('class.soap_server.php');*/
-
-// class variable emulation
-// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
-$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
-
-/**
-*
-* nusoap_base
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class nusoap_base {
-	/**
-	 * Identification for HTTP headers.
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $title = 'NuSOAP';
-	/**
-	 * Version for HTTP headers.
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $version = '0.7.2';
-	/**
-	 * CVS revision for HTTP headers.
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $revision = '$Revision$';
-    /**
-     * Current error string (manipulated by getError/setError)
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $error_str = '';
-    /**
-     * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
-	 *
-	 * @var string
-	 * @access private
-	 */
-    var $debug_str = '';
-    /**
-	 * toggles automatic encoding of special characters as entities
-	 * (should always be true, I think)
-	 *
-	 * @var boolean
-	 * @access private
-	 */
-	var $charencoding = true;
-	/**
-	 * the debug level for this instance
-	 *
-	 * @var	integer
-	 * @access private
-	 */
-	var $debugLevel;
-
-    /**
-	* set schema version
-	*
-	* @var      string
-	* @access   public
-	*/
-	var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
-	
-    /**
-	* charset encoding for outgoing messages
-	*
-	* @var      string
-	* @access   public
-	*/
-    var $soap_defencoding = 'ISO-8859-1';
-	//var $soap_defencoding = 'UTF-8';
-
-	/**
-	* namespaces in an array of prefix => uri
-	*
-	* this is "seeded" by a set of constants, but it may be altered by code
-	*
-	* @var      array
-	* @access   public
-	*/
-	var $namespaces = array(
-		'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
-		'xsd' => 'http://www.w3.org/2001/XMLSchema',
-		'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
-		'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
-		);
-
-	/**
-	* namespaces used in the current context, e.g. during serialization
-	*
-	* @var      array
-	* @access   private
-	*/
-	var $usedNamespaces = array();
-
-	/**
-	* XML Schema types in an array of uri => (array of xml type => php type)
-	* is this legacy yet?
-	* no, this is used by the xmlschema class to verify type => namespace mappings.
-	* @var      array
-	* @access   public
-	*/
-	var $typemap = array(
-	'http://www.w3.org/2001/XMLSchema' => array(
-		'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
-		'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
-		'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
-		// abstract "any" types
-		'anyType'=>'string','anySimpleType'=>'string',
-		// derived datatypes
-		'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
-		'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
-		'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
-		'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
-	'http://www.w3.org/2000/10/XMLSchema' => array(
-		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
-		'float'=>'double','dateTime'=>'string',
-		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
-	'http://www.w3.org/1999/XMLSchema' => array(
-		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
-		'float'=>'double','dateTime'=>'string',
-		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
-	'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
-	'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
-    'http://xml.apache.org/xml-soap' => array('Map')
-	);
-
-	/**
-	* XML entities to convert
-	*
-	* @var      array
-	* @access   public
-	* @deprecated
-	* @see	expandEntities
-	*/
-	var $xmlEntities = array('quot' => '"','amp' => '&',
-		'lt' => '<','gt' => '>','apos' => "'");
-
-	/**
-	* constructor
-	*
-	* @access	public
-	*/
-	function nusoap_base() {
-		$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
-	}
-
-	/**
-	* gets the global debug level, which applies to future instances
-	*
-	* @return	integer	Debug level 0-9, where 0 turns off
-	* @access	public
-	*/
-	function getGlobalDebugLevel() {
-		return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
-	}
-
-	/**
-	* sets the global debug level, which applies to future instances
-	*
-	* @param	int	$level	Debug level 0-9, where 0 turns off
-	* @access	public
-	*/
-	function setGlobalDebugLevel($level) {
-		$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
-	}
-
-	/**
-	* gets the debug level for this instance
-	*
-	* @return	int	Debug level 0-9, where 0 turns off
-	* @access	public
-	*/
-	function getDebugLevel() {
-		return $this->debugLevel;
-	}
-
-	/**
-	* sets the debug level for this instance
-	*
-	* @param	int	$level	Debug level 0-9, where 0 turns off
-	* @access	public
-	*/
-	function setDebugLevel($level) {
-		$this->debugLevel = $level;
-	}
-
-	/**
-	* adds debug data to the instance debug string with formatting
-	*
-	* @param    string $string debug data
-	* @access   private
-	*/
-	function debug($string){
-		if ($this->debugLevel > 0) {
-			$this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
-		}
-	}
-
-	/**
-	* adds debug data to the instance debug string without formatting
-	*
-	* @param    string $string debug data
-	* @access   public
-	*/
-	function appendDebug($string){
-		if ($this->debugLevel > 0) {
-			// it would be nice to use a memory stream here to use
-			// memory more efficiently
-			$this->debug_str .= $string;
-		}
-	}
-
-	/**
-	* clears the current debug data for this instance
-	*
-	* @access   public
-	*/
-	function clearDebug() {
-		// it would be nice to use a memory stream here to use
-		// memory more efficiently
-		$this->debug_str = '';
-	}
-
-	/**
-	* gets the current debug data for this instance
-	*
-	* @return   debug data
-	* @access   public
-	*/
-	function &getDebug() {
-		// it would be nice to use a memory stream here to use
-		// memory more efficiently
-		return $this->debug_str;
-	}
-
-	/**
-	* gets the current debug data for this instance as an XML comment
-	* this may change the contents of the debug data
-	*
-	* @return   debug data as an XML comment
-	* @access   public
-	*/
-	function &getDebugAsXMLComment() {
-		// it would be nice to use a memory stream here to use
-		// memory more efficiently
-		while (strpos($this->debug_str, '--')) {
-			$this->debug_str = str_replace('--', '- -', $this->debug_str);
-		}
-    	return "<!--\n" . $this->debug_str . "\n-->";
-	}
-
-	/**
-	* expands entities, e.g. changes '<' to '&lt;'.
-	*
-	* @param	string	$val	The string in which to expand entities.
-	* @access	private
-	*/
-	function expandEntities($val) {
-		if ($this->charencoding) {
-	    	$val = str_replace('&', '&amp;', $val);
-	    	$val = str_replace("'", '&apos;', $val);
-	    	$val = str_replace('"', '&quot;', $val);
-	    	$val = str_replace('<', '&lt;', $val);
-	    	$val = str_replace('>', '&gt;', $val);
-	    }
-	    return $val;
-	}
-
-	/**
-	* returns error string if present
-	*
-	* @return   mixed error string or false
-	* @access   public
-	*/
-	function getError(){
-		if($this->error_str != ''){
-			return $this->error_str;
-		}
-		return false;
-	}
-
-	/**
-	* sets error string
-	*
-	* @return   boolean $string error string
-	* @access   private
-	*/
-	function setError($str){
-		$this->error_str = $str;
-	}
-
-	/**
-	* detect if array is a simple array or a struct (associative array)
-	*
-	* @param	mixed	$val	The PHP array
-	* @return	string	(arraySimple|arrayStruct)
-	* @access	private
-	*/
-	function isArraySimpleOrStruct($val) {
-        $keyList = array_keys($val);
-		foreach ($keyList as $keyListValue) {
-			if (!is_int($keyListValue)) {
-				return 'arrayStruct';
-			}
-		}
-		return 'arraySimple';
-	}
-
-	/**
-	* serializes PHP values in accordance w/ section 5. Type information is
-	* not serialized if $use == 'literal'.
-	*
-	* @param	mixed	$val	The value to serialize
-	* @param	string	$name	The name (local part) of the XML element
-	* @param	string	$type	The XML schema type (local part) for the element
-	* @param	string	$name_ns	The namespace for the name of the XML element
-	* @param	string	$type_ns	The namespace for the type of the element
-	* @param	array	$attributes	The attributes to serialize as name=>value pairs
-	* @param	string	$use	The WSDL "use" (encoded|literal)
-	* @return	string	The serialized element, possibly with child elements
-    * @access	public
-	*/
-	function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){
-		$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use");
-		$this->appendDebug('value=' . $this->varDump($val));
-		$this->appendDebug('attributes=' . $this->varDump($attributes));
-		
-    	if(is_object($val) && get_class($val) == 'soapval'){
-        	return $val->serialize($use);
-        }
-		// force valid name if necessary
-		if (is_numeric($name)) {
-			$name = '__numeric_' . $name;
-		} elseif (! $name) {
-			$name = 'noname';
-		}
-		// if name has ns, add ns prefix to name
-		$xmlns = '';
-        if($name_ns){
-			$prefix = 'nu'.rand(1000,9999);
-			$name = $prefix.':'.$name;
-			$xmlns .= " xmlns:$prefix=\"$name_ns\"";
-		}
-		// if type is prefixed, create type prefix
-		if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
-			// need to fix this. shouldn't default to xsd if no ns specified
-		    // w/o checking against typemap
-			$type_prefix = 'xsd';
-		} elseif($type_ns){
-			$type_prefix = 'ns'.rand(1000,9999);
-			$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
-		}
-		// serialize attributes if present
-		$atts = '';
-		if($attributes){
-			foreach($attributes as $k => $v){
-				$atts .= " $k=\"".$this->expandEntities($v).'"';
-			}
-		}
-		// serialize null value
-		if (is_null($val)) {
-			if ($use == 'literal') {
-				// TODO: depends on minOccurs
-	        	return "<$name$xmlns $atts/>";
-        	} else {
-				if (isset($type) && isset($type_prefix)) {
-					$type_str = " xsi:type=\"$type_prefix:$type\"";
-				} else {
-					$type_str = '';
-				}
-	        	return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>";
-        	}
-		}
-        // serialize if an xsd built-in primitive type
-        if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
-        	if (is_bool($val)) {
-        		if ($type == 'boolean') {
-	        		$val = $val ? 'true' : 'false';
-	        	} elseif (! $val) {
-	        		$val = 0;
-	        	}
-			} else if (is_string($val)) {
-				$val = $this->expandEntities($val);
-			}
-			if ($use == 'literal') {
-	        	return "<$name$xmlns $atts>$val</$name>";
-        	} else {
-	        	return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>";
-        	}
-        }
-		// detect type and serialize
-		$xml = '';
-		switch(true) {
-			case (is_bool($val) || $type == 'boolean'):
-        		if ($type == 'boolean') {
-	        		$val = $val ? 'true' : 'false';
-	        	} elseif (! $val) {
-	        		$val = 0;
-	        	}
-				if ($use == 'literal') {
-					$xml .= "<$name$xmlns $atts>$val</$name>";
-				} else {
-					$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
-				}
-				break;
-			case (is_int($val) || is_long($val) || $type == 'int'):
-				if ($use == 'literal') {
-					$xml .= "<$name$xmlns $atts>$val</$name>";
-				} else {
-					$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
-				}
-				break;
-			case (is_float($val)|| is_double($val) || $type == 'float'):
-				if ($use == 'literal') {
-					$xml .= "<$name$xmlns $atts>$val</$name>";
-				} else {
-					$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
-				}
-				break;
-			case (is_string($val) || $type == 'string'):
-				$val = $this->expandEntities($val);
-				if ($use == 'literal') {
-					$xml .= "<$name$xmlns $atts>$val</$name>";
-				} else {
-					$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
-				}
-				break;
-			case is_object($val):
-				if (! $name) {
-					$name = get_class($val);
-					$this->debug("In serialize_val, used class name $name as element name");
-				} else {
-					$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
-				}
-				foreach(get_object_vars($val) as $k => $v){
-					$pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
-				}
-				$xml .= '<'.$name.'>'.$pXml.'</'.$name.'>';
-				break;
-			break;
-			case (is_array($val) || $type):
-				// detect if struct or array
-				$valueType = $this->isArraySimpleOrStruct($val);
-                if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
-					$i = 0;
-					if(is_array($val) && count($val)> 0){
-						foreach($val as $v){
-	                    	if(is_object($v) && get_class($v) ==  'soapval'){
-								$tt_ns = $v->type_ns;
-								$tt = $v->type;
-							} elseif (is_array($v)) {
-								$tt = $this->isArraySimpleOrStruct($v);
-							} else {
-								$tt = gettype($v);
-	                        }
-							$array_types[$tt] = 1;
-							// TODO: for literal, the name should be $name
-							$xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
-							++$i;
-						}
-						if(count($array_types) > 1){
-							$array_typename = 'xsd:anyType';
-						} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
-							if ($tt == 'integer') {
-								$tt = 'int';
-							}
-							$array_typename = 'xsd:'.$tt;
-						} elseif(isset($tt) && $tt == 'arraySimple'){
-							$array_typename = 'SOAP-ENC:Array';
-						} elseif(isset($tt) && $tt == 'arrayStruct'){
-							$array_typename = 'unnamed_struct_use_soapval';
-						} else {
-							// if type is prefixed, create type prefix
-							if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
-								 $array_typename = 'xsd:' . $tt;
-							} elseif ($tt_ns) {
-								$tt_prefix = 'ns' . rand(1000, 9999);
-								$array_typename = "$tt_prefix:$tt";
-								$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
-							} else {
-								$array_typename = $tt;
-							}
-						}
-						$array_type = $i;
-						if ($use == 'literal') {
-							$type_str = '';
-						} else if (isset($type) && isset($type_prefix)) {
-							$type_str = " xsi:type=\"$type_prefix:$type\"";
-						} else {
-							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
-						}
-					// empty array
-					} else {
-						if ($use == 'literal') {
-							$type_str = '';
-						} else if (isset($type) && isset($type_prefix)) {
-							$type_str = " xsi:type=\"$type_prefix:$type\"";
-						} else {
-							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
-						}
-					}
-					// TODO: for array in literal, there is no wrapper here
-					$xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
-				} else {
-					// got a struct
-					if(isset($type) && isset($type_prefix)){
-						$type_str = " xsi:type=\"$type_prefix:$type\"";
-					} else {
-						$type_str = '';
-					}
-					if ($use == 'literal') {
-						$xml .= "<$name$xmlns $atts>";
-					} else {
-						$xml .= "<$name$xmlns$type_str$atts>";
-					}
-					foreach($val as $k => $v){
-						// Apache Map
-						if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
-							$xml .= '<item>';
-							$xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
-							$xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
-							$xml .= '</item>';
-						} else {
-							$xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
-						}
-					}
-					$xml .= "</$name>";
-				}
-				break;
-			default:
-				$xml .= 'not detected, got '.gettype($val).' for '.$val;
-				break;
-		}
-		return $xml;
-	}
-
-    /**
-    * serializes a message
-    *
-    * @param string $body the XML of the SOAP body
-    * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
-    * @param array $namespaces optional the namespaces used in generating the body and headers
-    * @param string $style optional (rpc|document)
-    * @param string $use optional (encoded|literal)
-    * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
-    * @return string the message
-    * @access public
-    */
-    function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
-    // TODO: add an option to automatically run utf8_encode on $body and $headers
-    // if $this->soap_defencoding is UTF-8.  Not doing this automatically allows
-    // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
-
-	$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
-	$this->debug("headers:");
-	$this->appendDebug($this->varDump($headers));
-	$this->debug("namespaces:");
-	$this->appendDebug($this->varDump($namespaces));
-
-	// serialize namespaces
-    $ns_string = '';
-	foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
-		$ns_string .= " xmlns:$k=\"$v\"";
-	}
-	if($encodingStyle) {
-		$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
-	}
-
-	// serialize headers
-	if($headers){
-		if (is_array($headers)) {
-			$xml = '';
-			foreach ($headers as $header) {
-				$xml .= $this->serialize_val($header, false, false, false, false, false, $use);
-			}
-			$headers = $xml;
-			$this->debug("In serializeEnvelope, serialzied array of headers to $headers");
-		}
-		$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
-	}
-	// serialize envelope
-	return
-	'<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
-	'<SOAP-ENV:Envelope'.$ns_string.">".
-	$headers.
-	"<SOAP-ENV:Body>".
-		$body.
-	"</SOAP-ENV:Body>".
-	"</SOAP-ENV:Envelope>";
-    }
-
-	/**
-	 * formats a string to be inserted into an HTML stream
-	 *
-	 * @param string $str The string to format
-	 * @return string The formatted string
-	 * @access public
-	 * @deprecated
-	 */
-    function formatDump($str){
-		$str = htmlspecialchars($str);
-		return nl2br($str);
-    }
-
-	/**
-	* contracts (changes namespace to prefix) a qualified name
-	*
-	* @param    string $qname qname
-	* @return	string contracted qname
-	* @access   private
-	*/
-	function contractQname($qname){
-		// get element namespace
-		//$this->xdebug("Contract $qname");
-		if (strrpos($qname, ':')) {
-			// get unqualified name
-			$name = substr($qname, strrpos($qname, ':') + 1);
-			// get ns
-			$ns = substr($qname, 0, strrpos($qname, ':'));
-			$p = $this->getPrefixFromNamespace($ns);
-			if ($p) {
-				return $p . ':' . $name;
-			}
-			return $qname;
-		} else {
-			return $qname;
-		}
-	}
-
-	/**
-	* expands (changes prefix to namespace) a qualified name
-	*
-	* @param    string $string qname
-	* @return	string expanded qname
-	* @access   private
-	*/
-	function expandQname($qname){
-		// get element prefix
-		if(strpos($qname,':') && !ereg('^http://',$qname)){
-			// get unqualified name
-			$name = substr(strstr($qname,':'),1);
-			// get ns prefix
-			$prefix = substr($qname,0,strpos($qname,':'));
-			if(isset($this->namespaces[$prefix])){
-				return $this->namespaces[$prefix].':'.$name;
-			} else {
-				return $qname;
-			}
-		} else {
-			return $qname;
-		}
-	}
-
-    /**
-    * returns the local part of a prefixed string
-    * returns the original string, if not prefixed
-    *
-    * @param string $str The prefixed string
-    * @return string The local part
-    * @access public
-    */
-	function getLocalPart($str){
-		if($sstr = strrchr($str,':')){
-			// get unqualified name
-			return substr( $sstr, 1 );
-		} else {
-			return $str;
-		}
-	}
-
-	/**
-    * returns the prefix part of a prefixed string
-    * returns false, if not prefixed
-    *
-    * @param string $str The prefixed string
-    * @return mixed The prefix or false if there is no prefix
-    * @access public
-    */
-	function getPrefix($str){
-		if($pos = strrpos($str,':')){
-			// get prefix
-			return substr($str,0,$pos);
-		}
-		return false;
-	}
-
-	/**
-    * pass it a prefix, it returns a namespace
-    *
-    * @param string $prefix The prefix
-    * @return mixed The namespace, false if no namespace has the specified prefix
-    * @access public
-    */
-	function getNamespaceFromPrefix($prefix){
-		if (isset($this->namespaces[$prefix])) {
-			return $this->namespaces[$prefix];
-		}
-		//$this->setError("No namespace registered for prefix '$prefix'");
-		return false;
-	}
-
-	/**
-    * returns the prefix for a given namespace (or prefix)
-    * or false if no prefixes registered for the given namespace
-    *
-    * @param string $ns The namespace
-    * @return mixed The prefix, false if the namespace has no prefixes
-    * @access public
-    */
-	function getPrefixFromNamespace($ns) {
-		foreach ($this->namespaces as $p => $n) {
-			if ($ns == $n || $ns == $p) {
-			    $this->usedNamespaces[$p] = $n;
-				return $p;
-			}
-		}
-		return false;
-	}
-
-	/**
-    * returns the time in ODBC canonical form with microseconds
-    *
-    * @return string The time in ODBC canonical form with microseconds
-    * @access public
-    */
-	function getmicrotime() {
-		if (function_exists('gettimeofday')) {
-			$tod = gettimeofday();
-			$sec = $tod['sec'];
-			$usec = $tod['usec'];
-		} else {
-			$sec = time();
-			$usec = 0;
-		}
-		return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
-	}
-
-	/**
-	 * Returns a string with the output of var_dump
-	 *
-	 * @param mixed $data The variable to var_dump
-	 * @return string The output of var_dump
-	 * @access public
-	 */
-    function varDump($data) {
-		ob_start();
-		var_dump($data);
-		$ret_val = ob_get_contents();
-		ob_end_clean();
-		return $ret_val;
-	}
-}
-
-// XML Schema Datatype Helper Functions
-
-//xsd:dateTime helpers
-
-/**
-* convert unix timestamp to ISO 8601 compliant date string
-*
-* @param    string $timestamp Unix time stamp
-* @access   public
-*/
-function timestamp_to_iso8601($timestamp,$utc=true){
-	$datestr = date('Y-m-d\TH:i:sO',$timestamp);
-	if($utc){
-		$eregStr =
-		'([0-9]{4})-'.	// centuries & years CCYY-
-		'([0-9]{2})-'.	// months MM-
-		'([0-9]{2})'.	// days DD
-		'T'.			// separator T
-		'([0-9]{2}):'.	// hours hh:
-		'([0-9]{2}):'.	// minutes mm:
-		'([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
-		'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
-
-		if(ereg($eregStr,$datestr,$regs)){
-			return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
-		}
-		return false;
-	} else {
-		return $datestr;
-	}
-}
-
-/**
-* convert ISO 8601 compliant date string to unix timestamp
-*
-* @param    string $datestr ISO 8601 compliant date string
-* @access   public
-*/
-function iso8601_to_timestamp($datestr){
-	$eregStr =
-	'([0-9]{4})-'.	// centuries & years CCYY-
-	'([0-9]{2})-'.	// months MM-
-	'([0-9]{2})'.	// days DD
-	'T'.			// separator T
-	'([0-9]{2}):'.	// hours hh:
-	'([0-9]{2}):'.	// minutes mm:
-	'([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
-	'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
-	if(ereg($eregStr,$datestr,$regs)){
-		// not utc
-		if($regs[8] != 'Z'){
-			$op = substr($regs[8],0,1);
-			$h = substr($regs[8],1,2);
-			$m = substr($regs[8],strlen($regs[8])-2,2);
-			if($op == '-'){
-				$regs[4] = $regs[4] + $h;
-				$regs[5] = $regs[5] + $m;
-			} elseif($op == '+'){
-				$regs[4] = $regs[4] - $h;
-				$regs[5] = $regs[5] - $m;
-			}
-		}
-		return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
-	} else {
-		return false;
-	}
-}
-
-/**
-* sleeps some number of microseconds
-*
-* @param    string $usec the number of microseconds to sleep
-* @access   public
-* @deprecated
-*/
-function usleepWindows($usec)
-{
-	$start = gettimeofday();
-	
-	do
-	{
-		$stop = gettimeofday();
-		$timePassed = 1000000 * ($stop['sec'] - $start['sec'])
-		+ $stop['usec'] - $start['usec'];
-	}
-	while ($timePassed < $usec);
-}
-
-
+<?php
+
+/*
+$Id$
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+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
+
+If you have any questions or comments, please email:
+
+Dietrich Ayala
+dietrich@ganx4.com
+http://dietrich.ganx4.com/nusoap
+
+NuSphere Corporation
+http://www.nusphere.com
+
+*/
+
+/* load classes
+
+// necessary classes
+require_once('class.soapclient.php');
+require_once('class.soap_val.php');
+require_once('class.soap_parser.php');
+require_once('class.soap_fault.php');
+
+// transport classes
+require_once('class.soap_transport_http.php');
+
+// optional add-on classes
+require_once('class.xmlschema.php');
+require_once('class.wsdl.php');
+
+// server class
+require_once('class.soap_server.php');*/
+
+// class variable emulation
+// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
+$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
+
+/**
+*
+* nusoap_base
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class nusoap_base {
+	/**
+	 * Identification for HTTP headers.
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $title = 'NuSOAP';
+	/**
+	 * Version for HTTP headers.
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $version = '0.7.2';
+	/**
+	 * CVS revision for HTTP headers.
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $revision = '$Revision$';
+    /**
+     * Current error string (manipulated by getError/setError)
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $error_str = '';
+    /**
+     * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
+	 *
+	 * @var string
+	 * @access private
+	 */
+    var $debug_str = '';
+    /**
+	 * toggles automatic encoding of special characters as entities
+	 * (should always be true, I think)
+	 *
+	 * @var boolean
+	 * @access private
+	 */
+	var $charencoding = true;
+	/**
+	 * the debug level for this instance
+	 *
+	 * @var	integer
+	 * @access private
+	 */
+	var $debugLevel;
+
+    /**
+	* set schema version
+	*
+	* @var      string
+	* @access   public
+	*/
+	var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
+	
+    /**
+	* charset encoding for outgoing messages
+	*
+	* @var      string
+	* @access   public
+	*/
+    var $soap_defencoding = 'ISO-8859-1';
+	//var $soap_defencoding = 'UTF-8';
+
+	/**
+	* namespaces in an array of prefix => uri
+	*
+	* this is "seeded" by a set of constants, but it may be altered by code
+	*
+	* @var      array
+	* @access   public
+	*/
+	var $namespaces = array(
+		'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
+		'xsd' => 'http://www.w3.org/2001/XMLSchema',
+		'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
+		'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
+		);
+
+	/**
+	* namespaces used in the current context, e.g. during serialization
+	*
+	* @var      array
+	* @access   private
+	*/
+	var $usedNamespaces = array();
+
+	/**
+	* XML Schema types in an array of uri => (array of xml type => php type)
+	* is this legacy yet?
+	* no, this is used by the xmlschema class to verify type => namespace mappings.
+	* @var      array
+	* @access   public
+	*/
+	var $typemap = array(
+	'http://www.w3.org/2001/XMLSchema' => array(
+		'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
+		'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
+		'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
+		// abstract "any" types
+		'anyType'=>'string','anySimpleType'=>'string',
+		// derived datatypes
+		'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
+		'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
+		'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
+		'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
+	'http://www.w3.org/2000/10/XMLSchema' => array(
+		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
+		'float'=>'double','dateTime'=>'string',
+		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
+	'http://www.w3.org/1999/XMLSchema' => array(
+		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
+		'float'=>'double','dateTime'=>'string',
+		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
+	'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
+	'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
+    'http://xml.apache.org/xml-soap' => array('Map')
+	);
+
+	/**
+	* XML entities to convert
+	*
+	* @var      array
+	* @access   public
+	* @deprecated
+	* @see	expandEntities
+	*/
+	var $xmlEntities = array('quot' => '"','amp' => '&',
+		'lt' => '<','gt' => '>','apos' => "'");
+
+	/**
+	* constructor
+	*
+	* @access	public
+	*/
+	function nusoap_base() {
+		$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
+	}
+
+	/**
+	* gets the global debug level, which applies to future instances
+	*
+	* @return	integer	Debug level 0-9, where 0 turns off
+	* @access	public
+	*/
+	function getGlobalDebugLevel() {
+		return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
+	}
+
+	/**
+	* sets the global debug level, which applies to future instances
+	*
+	* @param	int	$level	Debug level 0-9, where 0 turns off
+	* @access	public
+	*/
+	function setGlobalDebugLevel($level) {
+		$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
+	}
+
+	/**
+	* gets the debug level for this instance
+	*
+	* @return	int	Debug level 0-9, where 0 turns off
+	* @access	public
+	*/
+	function getDebugLevel() {
+		return $this->debugLevel;
+	}
+
+	/**
+	* sets the debug level for this instance
+	*
+	* @param	int	$level	Debug level 0-9, where 0 turns off
+	* @access	public
+	*/
+	function setDebugLevel($level) {
+		$this->debugLevel = $level;
+	}
+
+	/**
+	* adds debug data to the instance debug string with formatting
+	*
+	* @param    string $string debug data
+	* @access   private
+	*/
+	function debug($string){
+		if ($this->debugLevel > 0) {
+			$this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
+		}
+	}
+
+	/**
+	* adds debug data to the instance debug string without formatting
+	*
+	* @param    string $string debug data
+	* @access   public
+	*/
+	function appendDebug($string){
+		if ($this->debugLevel > 0) {
+			// it would be nice to use a memory stream here to use
+			// memory more efficiently
+			$this->debug_str .= $string;
+		}
+	}
+
+	/**
+	* clears the current debug data for this instance
+	*
+	* @access   public
+	*/
+	function clearDebug() {
+		// it would be nice to use a memory stream here to use
+		// memory more efficiently
+		$this->debug_str = '';
+	}
+
+	/**
+	* gets the current debug data for this instance
+	*
+	* @return   debug data
+	* @access   public
+	*/
+	function &getDebug() {
+		// it would be nice to use a memory stream here to use
+		// memory more efficiently
+		return $this->debug_str;
+	}
+
+	/**
+	* gets the current debug data for this instance as an XML comment
+	* this may change the contents of the debug data
+	*
+	* @return   debug data as an XML comment
+	* @access   public
+	*/
+	function &getDebugAsXMLComment() {
+		// it would be nice to use a memory stream here to use
+		// memory more efficiently
+		while (strpos($this->debug_str, '--')) {
+			$this->debug_str = str_replace('--', '- -', $this->debug_str);
+		}
+    	return "<!--\n" . $this->debug_str . "\n-->";
+	}
+
+	/**
+	* expands entities, e.g. changes '<' to '&lt;'.
+	*
+	* @param	string	$val	The string in which to expand entities.
+	* @access	private
+	*/
+	function expandEntities($val) {
+		if ($this->charencoding) {
+	    	$val = str_replace('&', '&amp;', $val);
+	    	$val = str_replace("'", '&apos;', $val);
+	    	$val = str_replace('"', '&quot;', $val);
+	    	$val = str_replace('<', '&lt;', $val);
+	    	$val = str_replace('>', '&gt;', $val);
+	    }
+	    return $val;
+	}
+
+	/**
+	* returns error string if present
+	*
+	* @return   mixed error string or false
+	* @access   public
+	*/
+	function getError(){
+		if($this->error_str != ''){
+			return $this->error_str;
+		}
+		return false;
+	}
+
+	/**
+	* sets error string
+	*
+	* @return   boolean $string error string
+	* @access   private
+	*/
+	function setError($str){
+		$this->error_str = $str;
+	}
+
+	/**
+	* detect if array is a simple array or a struct (associative array)
+	*
+	* @param	mixed	$val	The PHP array
+	* @return	string	(arraySimple|arrayStruct)
+	* @access	private
+	*/
+	function isArraySimpleOrStruct($val) {
+        $keyList = array_keys($val);
+		foreach ($keyList as $keyListValue) {
+			if (!is_int($keyListValue)) {
+				return 'arrayStruct';
+			}
+		}
+		return 'arraySimple';
+	}
+
+	/**
+	* serializes PHP values in accordance w/ section 5. Type information is
+	* not serialized if $use == 'literal'.
+	*
+	* @param	mixed	$val	The value to serialize
+	* @param	string	$name	The name (local part) of the XML element
+	* @param	string	$type	The XML schema type (local part) for the element
+	* @param	string	$name_ns	The namespace for the name of the XML element
+	* @param	string	$type_ns	The namespace for the type of the element
+	* @param	array	$attributes	The attributes to serialize as name=>value pairs
+	* @param	string	$use	The WSDL "use" (encoded|literal)
+	* @return	string	The serialized element, possibly with child elements
+    * @access	public
+	*/
+	function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){
+		$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use");
+		$this->appendDebug('value=' . $this->varDump($val));
+		$this->appendDebug('attributes=' . $this->varDump($attributes));
+		
+    	if(is_object($val) && get_class($val) == 'soapval'){
+        	return $val->serialize($use);
+        }
+		// force valid name if necessary
+		if (is_numeric($name)) {
+			$name = '__numeric_' . $name;
+		} elseif (! $name) {
+			$name = 'noname';
+		}
+		// if name has ns, add ns prefix to name
+		$xmlns = '';
+        if($name_ns){
+			$prefix = 'nu'.rand(1000,9999);
+			$name = $prefix.':'.$name;
+			$xmlns .= " xmlns:$prefix=\"$name_ns\"";
+		}
+		// if type is prefixed, create type prefix
+		if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
+			// need to fix this. shouldn't default to xsd if no ns specified
+		    // w/o checking against typemap
+			$type_prefix = 'xsd';
+		} elseif($type_ns){
+			$type_prefix = 'ns'.rand(1000,9999);
+			$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
+		}
+		// serialize attributes if present
+		$atts = '';
+		if($attributes){
+			foreach($attributes as $k => $v){
+				$atts .= " $k=\"".$this->expandEntities($v).'"';
+			}
+		}
+		// serialize null value
+		if (is_null($val)) {
+			if ($use == 'literal') {
+				// TODO: depends on minOccurs
+	        	return "<$name$xmlns $atts/>";
+        	} else {
+				if (isset($type) && isset($type_prefix)) {
+					$type_str = " xsi:type=\"$type_prefix:$type\"";
+				} else {
+					$type_str = '';
+				}
+	        	return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>";
+        	}
+		}
+        // serialize if an xsd built-in primitive type
+        if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
+        	if (is_bool($val)) {
+        		if ($type == 'boolean') {
+	        		$val = $val ? 'true' : 'false';
+	        	} elseif (! $val) {
+	        		$val = 0;
+	        	}
+			} else if (is_string($val)) {
+				$val = $this->expandEntities($val);
+			}
+			if ($use == 'literal') {
+	        	return "<$name$xmlns $atts>$val</$name>";
+        	} else {
+	        	return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>";
+        	}
+        }
+		// detect type and serialize
+		$xml = '';
+		switch(true) {
+			case (is_bool($val) || $type == 'boolean'):
+        		if ($type == 'boolean') {
+	        		$val = $val ? 'true' : 'false';
+	        	} elseif (! $val) {
+	        		$val = 0;
+	        	}
+				if ($use == 'literal') {
+					$xml .= "<$name$xmlns $atts>$val</$name>";
+				} else {
+					$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
+				}
+				break;
+			case (is_int($val) || is_long($val) || $type == 'int'):
+				if ($use == 'literal') {
+					$xml .= "<$name$xmlns $atts>$val</$name>";
+				} else {
+					$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
+				}
+				break;
+			case (is_float($val)|| is_double($val) || $type == 'float'):
+				if ($use == 'literal') {
+					$xml .= "<$name$xmlns $atts>$val</$name>";
+				} else {
+					$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
+				}
+				break;
+			case (is_string($val) || $type == 'string'):
+				$val = $this->expandEntities($val);
+				if ($use == 'literal') {
+					$xml .= "<$name$xmlns $atts>$val</$name>";
+				} else {
+					$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
+				}
+				break;
+			case is_object($val):
+				if (! $name) {
+					$name = get_class($val);
+					$this->debug("In serialize_val, used class name $name as element name");
+				} else {
+					$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
+				}
+				foreach(get_object_vars($val) as $k => $v){
+					$pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
+				}
+				$xml .= '<'.$name.'>'.$pXml.'</'.$name.'>';
+				break;
+			break;
+			case (is_array($val) || $type):
+				// detect if struct or array
+				$valueType = $this->isArraySimpleOrStruct($val);
+                if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
+					$i = 0;
+					if(is_array($val) && count($val)> 0){
+						foreach($val as $v){
+	                    	if(is_object($v) && get_class($v) ==  'soapval'){
+								$tt_ns = $v->type_ns;
+								$tt = $v->type;
+							} elseif (is_array($v)) {
+								$tt = $this->isArraySimpleOrStruct($v);
+							} else {
+								$tt = gettype($v);
+	                        }
+							$array_types[$tt] = 1;
+							// TODO: for literal, the name should be $name
+							$xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
+							++$i;
+						}
+						if(count($array_types) > 1){
+							$array_typename = 'xsd:anyType';
+						} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
+							if ($tt == 'integer') {
+								$tt = 'int';
+							}
+							$array_typename = 'xsd:'.$tt;
+						} elseif(isset($tt) && $tt == 'arraySimple'){
+							$array_typename = 'SOAP-ENC:Array';
+						} elseif(isset($tt) && $tt == 'arrayStruct'){
+							$array_typename = 'unnamed_struct_use_soapval';
+						} else {
+							// if type is prefixed, create type prefix
+							if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
+								 $array_typename = 'xsd:' . $tt;
+							} elseif ($tt_ns) {
+								$tt_prefix = 'ns' . rand(1000, 9999);
+								$array_typename = "$tt_prefix:$tt";
+								$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
+							} else {
+								$array_typename = $tt;
+							}
+						}
+						$array_type = $i;
+						if ($use == 'literal') {
+							$type_str = '';
+						} else if (isset($type) && isset($type_prefix)) {
+							$type_str = " xsi:type=\"$type_prefix:$type\"";
+						} else {
+							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
+						}
+					// empty array
+					} else {
+						if ($use == 'literal') {
+							$type_str = '';
+						} else if (isset($type) && isset($type_prefix)) {
+							$type_str = " xsi:type=\"$type_prefix:$type\"";
+						} else {
+							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
+						}
+					}
+					// TODO: for array in literal, there is no wrapper here
+					$xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
+				} else {
+					// got a struct
+					if(isset($type) && isset($type_prefix)){
+						$type_str = " xsi:type=\"$type_prefix:$type\"";
+					} else {
+						$type_str = '';
+					}
+					if ($use == 'literal') {
+						$xml .= "<$name$xmlns $atts>";
+					} else {
+						$xml .= "<$name$xmlns$type_str$atts>";
+					}
+					foreach($val as $k => $v){
+						// Apache Map
+						if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
+							$xml .= '<item>';
+							$xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
+							$xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
+							$xml .= '</item>';
+						} else {
+							$xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
+						}
+					}
+					$xml .= "</$name>";
+				}
+				break;
+			default:
+				$xml .= 'not detected, got '.gettype($val).' for '.$val;
+				break;
+		}
+		return $xml;
+	}
+
+    /**
+    * serializes a message
+    *
+    * @param string $body the XML of the SOAP body
+    * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
+    * @param array $namespaces optional the namespaces used in generating the body and headers
+    * @param string $style optional (rpc|document)
+    * @param string $use optional (encoded|literal)
+    * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
+    * @return string the message
+    * @access public
+    */
+    function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
+    // TODO: add an option to automatically run utf8_encode on $body and $headers
+    // if $this->soap_defencoding is UTF-8.  Not doing this automatically allows
+    // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
+
+	$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
+	$this->debug("headers:");
+	$this->appendDebug($this->varDump($headers));
+	$this->debug("namespaces:");
+	$this->appendDebug($this->varDump($namespaces));
+
+	// serialize namespaces
+    $ns_string = '';
+	foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
+		$ns_string .= " xmlns:$k=\"$v\"";
+	}
+	if($encodingStyle) {
+		$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
+	}
+
+	// serialize headers
+	if($headers){
+		if (is_array($headers)) {
+			$xml = '';
+			foreach ($headers as $header) {
+				$xml .= $this->serialize_val($header, false, false, false, false, false, $use);
+			}
+			$headers = $xml;
+			$this->debug("In serializeEnvelope, serialzied array of headers to $headers");
+		}
+		$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
+	}
+	// serialize envelope
+	return
+	'<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
+	'<SOAP-ENV:Envelope'.$ns_string.">".
+	$headers.
+	"<SOAP-ENV:Body>".
+		$body.
+	"</SOAP-ENV:Body>".
+	"</SOAP-ENV:Envelope>";
+    }
+
+	/**
+	 * formats a string to be inserted into an HTML stream
+	 *
+	 * @param string $str The string to format
+	 * @return string The formatted string
+	 * @access public
+	 * @deprecated
+	 */
+    function formatDump($str){
+		$str = htmlspecialchars($str);
+		return nl2br($str);
+    }
+
+	/**
+	* contracts (changes namespace to prefix) a qualified name
+	*
+	* @param    string $qname qname
+	* @return	string contracted qname
+	* @access   private
+	*/
+	function contractQname($qname){
+		// get element namespace
+		//$this->xdebug("Contract $qname");
+		if (strrpos($qname, ':')) {
+			// get unqualified name
+			$name = substr($qname, strrpos($qname, ':') + 1);
+			// get ns
+			$ns = substr($qname, 0, strrpos($qname, ':'));
+			$p = $this->getPrefixFromNamespace($ns);
+			if ($p) {
+				return $p . ':' . $name;
+			}
+			return $qname;
+		} else {
+			return $qname;
+		}
+	}
+
+	/**
+	* expands (changes prefix to namespace) a qualified name
+	*
+	* @param    string $string qname
+	* @return	string expanded qname
+	* @access   private
+	*/
+	function expandQname($qname){
+		// get element prefix
+		if(strpos($qname,':') && !ereg('^http://',$qname)){
+			// get unqualified name
+			$name = substr(strstr($qname,':'),1);
+			// get ns prefix
+			$prefix = substr($qname,0,strpos($qname,':'));
+			if(isset($this->namespaces[$prefix])){
+				return $this->namespaces[$prefix].':'.$name;
+			} else {
+				return $qname;
+			}
+		} else {
+			return $qname;
+		}
+	}
+
+    /**
+    * returns the local part of a prefixed string
+    * returns the original string, if not prefixed
+    *
+    * @param string $str The prefixed string
+    * @return string The local part
+    * @access public
+    */
+	function getLocalPart($str){
+		if($sstr = strrchr($str,':')){
+			// get unqualified name
+			return substr( $sstr, 1 );
+		} else {
+			return $str;
+		}
+	}
+
+	/**
+    * returns the prefix part of a prefixed string
+    * returns false, if not prefixed
+    *
+    * @param string $str The prefixed string
+    * @return mixed The prefix or false if there is no prefix
+    * @access public
+    */
+	function getPrefix($str){
+		if($pos = strrpos($str,':')){
+			// get prefix
+			return substr($str,0,$pos);
+		}
+		return false;
+	}
+
+	/**
+    * pass it a prefix, it returns a namespace
+    *
+    * @param string $prefix The prefix
+    * @return mixed The namespace, false if no namespace has the specified prefix
+    * @access public
+    */
+	function getNamespaceFromPrefix($prefix){
+		if (isset($this->namespaces[$prefix])) {
+			return $this->namespaces[$prefix];
+		}
+		//$this->setError("No namespace registered for prefix '$prefix'");
+		return false;
+	}
+
+	/**
+    * returns the prefix for a given namespace (or prefix)
+    * or false if no prefixes registered for the given namespace
+    *
+    * @param string $ns The namespace
+    * @return mixed The prefix, false if the namespace has no prefixes
+    * @access public
+    */
+	function getPrefixFromNamespace($ns) {
+		foreach ($this->namespaces as $p => $n) {
+			if ($ns == $n || $ns == $p) {
+			    $this->usedNamespaces[$p] = $n;
+				return $p;
+			}
+		}
+		return false;
+	}
+
+	/**
+    * returns the time in ODBC canonical form with microseconds
+    *
+    * @return string The time in ODBC canonical form with microseconds
+    * @access public
+    */
+	function getmicrotime() {
+		if (function_exists('gettimeofday')) {
+			$tod = gettimeofday();
+			$sec = $tod['sec'];
+			$usec = $tod['usec'];
+		} else {
+			$sec = time();
+			$usec = 0;
+		}
+		return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
+	}
+
+	/**
+	 * Returns a string with the output of var_dump
+	 *
+	 * @param mixed $data The variable to var_dump
+	 * @return string The output of var_dump
+	 * @access public
+	 */
+    function varDump($data) {
+		ob_start();
+		var_dump($data);
+		$ret_val = ob_get_contents();
+		ob_end_clean();
+		return $ret_val;
+	}
+}
+
+// XML Schema Datatype Helper Functions
+
+//xsd:dateTime helpers
+
+/**
+* convert unix timestamp to ISO 8601 compliant date string
+*
+* @param    string $timestamp Unix time stamp
+* @access   public
+*/
+function timestamp_to_iso8601($timestamp,$utc=true){
+	$datestr = date('Y-m-d\TH:i:sO',$timestamp);
+	if($utc){
+		$eregStr =
+		'([0-9]{4})-'.	// centuries & years CCYY-
+		'([0-9]{2})-'.	// months MM-
+		'([0-9]{2})'.	// days DD
+		'T'.			// separator T
+		'([0-9]{2}):'.	// hours hh:
+		'([0-9]{2}):'.	// minutes mm:
+		'([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
+		'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
+
+		if(ereg($eregStr,$datestr,$regs)){
+			return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
+		}
+		return false;
+	} else {
+		return $datestr;
+	}
+}
+
+/**
+* convert ISO 8601 compliant date string to unix timestamp
+*
+* @param    string $datestr ISO 8601 compliant date string
+* @access   public
+*/
+function iso8601_to_timestamp($datestr){
+	$eregStr =
+	'([0-9]{4})-'.	// centuries & years CCYY-
+	'([0-9]{2})-'.	// months MM-
+	'([0-9]{2})'.	// days DD
+	'T'.			// separator T
+	'([0-9]{2}):'.	// hours hh:
+	'([0-9]{2}):'.	// minutes mm:
+	'([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
+	'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
+	if(ereg($eregStr,$datestr,$regs)){
+		// not utc
+		if($regs[8] != 'Z'){
+			$op = substr($regs[8],0,1);
+			$h = substr($regs[8],1,2);
+			$m = substr($regs[8],strlen($regs[8])-2,2);
+			if($op == '-'){
+				$regs[4] = $regs[4] + $h;
+				$regs[5] = $regs[5] + $m;
+			} elseif($op == '+'){
+				$regs[4] = $regs[4] - $h;
+				$regs[5] = $regs[5] - $m;
+			}
+		}
+		return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
+	} else {
+		return false;
+	}
+}
+
+/**
+* sleeps some number of microseconds
+*
+* @param    string $usec the number of microseconds to sleep
+* @access   public
+* @deprecated
+*/
+function usleepWindows($usec)
+{
+	$start = gettimeofday();
+	
+	do
+	{
+		$stop = gettimeofday();
+		$timePassed = 1000000 * ($stop['sec'] - $start['sec'])
+		+ $stop['usec'] - $start['usec'];
+	}
+	while ($timePassed < $usec);
+}
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.soap_fault.php b/htdocs/oscommerce_ws/ws_server/lib/class.soap_fault.php
index d6859084e2bf03dc8eb35293727a71aa2026344f..62509a24fb22345c7d3cac67366440b460e9f099 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.soap_fault.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.soap_fault.php
@@ -1,86 +1,86 @@
-<?php
-
-
-
-
-/**
-* Contains information for a SOAP fault.
-* Mainly used for returning faults from deployed functions
-* in a server instance.
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access public
-*/
-class soap_fault extends nusoap_base {
-	/**
-	 * The fault code (client|server)
-	 * @var string
-	 * @access private
-	 */
-	var $faultcode;
-	/**
-	 * The fault actor
-	 * @var string
-	 * @access private
-	 */
-	var $faultactor;
-	/**
-	 * The fault string, a description of the fault
-	 * @var string
-	 * @access private
-	 */
-	var $faultstring;
-	/**
-	 * The fault detail, typically a string or array of string
-	 * @var mixed
-	 * @access private
-	 */
-	var $faultdetail;
-
-	/**
-	* constructor
-    *
-    * @param string $faultcode (client | server)
-    * @param string $faultactor only used when msg routed between multiple actors
-    * @param string $faultstring human readable error message
-    * @param mixed $faultdetail detail, typically a string or array of string
-	*/
-	function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
-		parent::nusoap_base();
-		$this->faultcode = $faultcode;
-		$this->faultactor = $faultactor;
-		$this->faultstring = $faultstring;
-		$this->faultdetail = $faultdetail;
-	}
-
-	/**
-	* serialize a fault
-	*
-	* @return	string	The serialization of the fault instance.
-	* @access   public
-	*/
-	function serialize(){
-		$ns_string = '';
-		foreach($this->namespaces as $k => $v){
-			$ns_string .= "\n  xmlns:$k=\"$v\"";
-		}
-		$return_msg =
-			'<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
-			'<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
-				'<SOAP-ENV:Body>'.
-				'<SOAP-ENV:Fault>'.
-					$this->serialize_val($this->faultcode, 'faultcode').
-					$this->serialize_val($this->faultactor, 'faultactor').
-					$this->serialize_val($this->faultstring, 'faultstring').
-					$this->serialize_val($this->faultdetail, 'detail').
-				'</SOAP-ENV:Fault>'.
-				'</SOAP-ENV:Body>'.
-			'</SOAP-ENV:Envelope>';
-		return $return_msg;
-	}
-}
-
-
-
-
+<?php
+
+
+
+
+/**
+* Contains information for a SOAP fault.
+* Mainly used for returning faults from deployed functions
+* in a server instance.
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access public
+*/
+class soap_fault extends nusoap_base {
+	/**
+	 * The fault code (client|server)
+	 * @var string
+	 * @access private
+	 */
+	var $faultcode;
+	/**
+	 * The fault actor
+	 * @var string
+	 * @access private
+	 */
+	var $faultactor;
+	/**
+	 * The fault string, a description of the fault
+	 * @var string
+	 * @access private
+	 */
+	var $faultstring;
+	/**
+	 * The fault detail, typically a string or array of string
+	 * @var mixed
+	 * @access private
+	 */
+	var $faultdetail;
+
+	/**
+	* constructor
+    *
+    * @param string $faultcode (client | server)
+    * @param string $faultactor only used when msg routed between multiple actors
+    * @param string $faultstring human readable error message
+    * @param mixed $faultdetail detail, typically a string or array of string
+	*/
+	function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
+		parent::nusoap_base();
+		$this->faultcode = $faultcode;
+		$this->faultactor = $faultactor;
+		$this->faultstring = $faultstring;
+		$this->faultdetail = $faultdetail;
+	}
+
+	/**
+	* serialize a fault
+	*
+	* @return	string	The serialization of the fault instance.
+	* @access   public
+	*/
+	function serialize(){
+		$ns_string = '';
+		foreach($this->namespaces as $k => $v){
+			$ns_string .= "\n  xmlns:$k=\"$v\"";
+		}
+		$return_msg =
+			'<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
+			'<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
+				'<SOAP-ENV:Body>'.
+				'<SOAP-ENV:Fault>'.
+					$this->serialize_val($this->faultcode, 'faultcode').
+					$this->serialize_val($this->faultactor, 'faultactor').
+					$this->serialize_val($this->faultstring, 'faultstring').
+					$this->serialize_val($this->faultdetail, 'detail').
+				'</SOAP-ENV:Fault>'.
+				'</SOAP-ENV:Body>'.
+			'</SOAP-ENV:Envelope>';
+		return $return_msg;
+	}
+}
+
+
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.soap_parser.php b/htdocs/oscommerce_ws/ws_server/lib/class.soap_parser.php
index 37b1920fc0e9a153a5ee9f5b201291e3c00d1daa..1c70a8cbdc123b714aed65348e385b438e44b8c0 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.soap_parser.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.soap_parser.php
@@ -1,599 +1,599 @@
-<?php
-
-
-
-
-/**
-*
-* soap_parser class parses SOAP XML messages into native PHP values
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class soap_parser extends nusoap_base {
-
-	var $xml = '';
-	var $xml_encoding = '';
-	var $method = '';
-	var $root_struct = '';
-	var $root_struct_name = '';
-	var $root_struct_namespace = '';
-	var $root_header = '';
-    var $document = '';			// incoming SOAP body (text)
-	// determines where in the message we are (envelope,header,body,method)
-	var $status = '';
-	var $position = 0;
-	var $depth = 0;
-	var $default_namespace = '';
-	var $namespaces = array();
-	var $message = array();
-    var $parent = '';
-	var $fault = false;
-	var $fault_code = '';
-	var $fault_str = '';
-	var $fault_detail = '';
-	var $depth_array = array();
-	var $debug_flag = true;
-	var $soapresponse = NULL;
-	var $responseHeaders = '';	// incoming SOAP headers (text)
-	var $body_position = 0;
-	// for multiref parsing:
-	// array of id => pos
-	var $ids = array();
-	// array of id => hrefs => pos
-	var $multirefs = array();
-	// toggle for auto-decoding element content
-	var $decode_utf8 = true;
-
-	/**
-	* constructor that actually does the parsing
-	*
-	* @param    string $xml SOAP message
-	* @param    string $encoding character encoding scheme of message
-	* @param    string $method method for which XML is parsed (unused?)
-	* @param    string $decode_utf8 whether to decode UTF-8 to ISO-8859-1
-	* @access   public
-	*/
-	function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
-		parent::nusoap_base();
-		$this->xml = $xml;
-		$this->xml_encoding = $encoding;
-		$this->method = $method;
-		$this->decode_utf8 = $decode_utf8;
-
-		// Check whether content has been read.
-		if(!empty($xml)){
-			// Check XML encoding
-			$pos_xml = strpos($xml, '<?xml');
-			if ($pos_xml !== FALSE) {
-				$xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
-				if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
-					$xml_encoding = $res[1];
-					if (strtoupper($xml_encoding) != $encoding) {
-						$err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
-						$this->debug($err);
-						if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
-							$this->setError($err);
-							return;
-						}
-						// when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
-					} else {
-						$this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
-					}
-				} else {
-					$this->debug('No encoding specified in XML declaration');
-				}
-			} else {
-				$this->debug('No XML declaration');
-			}
-			$this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding);
-			// Create an XML parser - why not xml_parser_create_ns?
-			$this->parser = xml_parser_create($this->xml_encoding);
-			// Set the options for parsing the XML data.
-			//xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
-			xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
-			xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
-			// Set the object for the parser.
-			xml_set_object($this->parser, $this);
-			// Set the element handlers for the parser.
-			xml_set_element_handler($this->parser, 'start_element','end_element');
-			xml_set_character_data_handler($this->parser,'character_data');
-
-			// Parse the XML file.
-			if(!xml_parse($this->parser,$xml,true)){
-			    // Display an error message.
-			    $err = sprintf('XML error parsing SOAP payload on line %d: %s',
-			    xml_get_current_line_number($this->parser),
-			    xml_error_string(xml_get_error_code($this->parser)));
-				$this->debug($err);
-				$this->debug("XML payload:\n" . $xml);
-				$this->setError($err);
-			} else {
-				$this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
-				// get final value
-				$this->soapresponse = $this->message[$this->root_struct]['result'];
-				// get header value: no, because this is documented as XML string
-//				if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
-//					$this->responseHeaders = $this->message[$this->root_header]['result'];
-//				}
-				// resolve hrefs/ids
-				if(sizeof($this->multirefs) > 0){
-					foreach($this->multirefs as $id => $hrefs){
-						$this->debug('resolving multirefs for id: '.$id);
-						$idVal = $this->buildVal($this->ids[$id]);
-						if (is_array($idVal) && isset($idVal['!id'])) {
-							unset($idVal['!id']);
-						}
-						foreach($hrefs as $refPos => $ref){
-							$this->debug('resolving href at pos '.$refPos);
-							$this->multirefs[$id][$refPos] = $idVal;
-						}
-					}
-				}
-			}
-			xml_parser_free($this->parser);
-		} else {
-			$this->debug('xml was empty, didn\'t parse!');
-			$this->setError('xml was empty, didn\'t parse!');
-		}
-	}
-
-	/**
-	* start-element handler
-	*
-	* @param    resource $parser XML parser object
-	* @param    string $name element name
-	* @param    array $attrs associative array of attributes
-	* @access   private
-	*/
-	function start_element($parser, $name, $attrs) {
-		// position in a total number of elements, starting from 0
-		// update class level pos
-		$pos = $this->position++;
-		// and set mine
-		$this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
-		// depth = how many levels removed from root?
-		// set mine as current global depth and increment global depth value
-		$this->message[$pos]['depth'] = $this->depth++;
-
-		// else add self as child to whoever the current parent is
-		if($pos != 0){
-			$this->message[$this->parent]['children'] .= '|'.$pos;
-		}
-		// set my parent
-		$this->message[$pos]['parent'] = $this->parent;
-		// set self as current parent
-		$this->parent = $pos;
-		// set self as current value for this depth
-		$this->depth_array[$this->depth] = $pos;
-		// get element prefix
-		if(strpos($name,':')){
-			// get ns prefix
-			$prefix = substr($name,0,strpos($name,':'));
-			// get unqualified name
-			$name = substr(strstr($name,':'),1);
-		}
-		// set status
-		if($name == 'Envelope'){
-			$this->status = 'envelope';
-		} elseif($name == 'Header'){
-			$this->root_header = $pos;
-			$this->status = 'header';
-		} elseif($name == 'Body'){
-			$this->status = 'body';
-			$this->body_position = $pos;
-		// set method
-		} elseif($this->status == 'body' && $pos == ($this->body_position+1)){
-			$this->status = 'method';
-			$this->root_struct_name = $name;
-			$this->root_struct = $pos;
-			$this->message[$pos]['type'] = 'struct';
-			$this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
-		}
-		// set my status
-		$this->message[$pos]['status'] = $this->status;
-		// set name
-		$this->message[$pos]['name'] = htmlspecialchars($name);
-		// set attrs
-		$this->message[$pos]['attrs'] = $attrs;
-
-		// loop through atts, logging ns and type declarations
-        $attstr = '';
-		foreach($attrs as $key => $value){
-        	$key_prefix = $this->getPrefix($key);
-			$key_localpart = $this->getLocalPart($key);
-			// if ns declarations, add to class level array of valid namespaces
-            if($key_prefix == 'xmlns'){
-				if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){
-					$this->XMLSchemaVersion = $value;
-					$this->namespaces['xsd'] = $this->XMLSchemaVersion;
-					$this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
-				}
-                $this->namespaces[$key_localpart] = $value;
-				// set method namespace
-				if($name == $this->root_struct_name){
-					$this->methodNamespace = $value;
-				}
-			// if it's a type declaration, set type
-            } elseif($key_localpart == 'type'){
-            	$value_prefix = $this->getPrefix($value);
-                $value_localpart = $this->getLocalPart($value);
-				$this->message[$pos]['type'] = $value_localpart;
-				$this->message[$pos]['typePrefix'] = $value_prefix;
-                if(isset($this->namespaces[$value_prefix])){
-                	$this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
-                } else if(isset($attrs['xmlns:'.$value_prefix])) {
-					$this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
-                }
-				// should do something here with the namespace of specified type?
-			} elseif($key_localpart == 'arrayType'){
-				$this->message[$pos]['type'] = 'array';
-				/* do arrayType ereg here
-				[1]    arrayTypeValue    ::=    atype asize
-				[2]    atype    ::=    QName rank*
-				[3]    rank    ::=    '[' (',')* ']'
-				[4]    asize    ::=    '[' length~ ']'
-				[5]    length    ::=    nextDimension* Digit+
-				[6]    nextDimension    ::=    Digit+ ','
-				*/
-				$expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]';
-				if(ereg($expr,$value,$regs)){
-					$this->message[$pos]['typePrefix'] = $regs[1];
-					$this->message[$pos]['arrayTypePrefix'] = $regs[1];
-	                if (isset($this->namespaces[$regs[1]])) {
-	                	$this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
-	                } else if (isset($attrs['xmlns:'.$regs[1]])) {
-						$this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
-	                }
-					$this->message[$pos]['arrayType'] = $regs[2];
-					$this->message[$pos]['arraySize'] = $regs[3];
-					$this->message[$pos]['arrayCols'] = $regs[4];
-				}
-			// specifies nil value (or not)
-			} elseif ($key_localpart == 'nil'){
-				$this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
-			// some other attribute
-			} elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
-				$this->message[$pos]['xattrs']['!' . $key] = $value;
-			}
-
-			if ($key == 'xmlns') {
-				$this->default_namespace = $value;
-			}
-			// log id
-			if($key == 'id'){
-				$this->ids[$value] = $pos;
-			}
-			// root
-			if($key_localpart == 'root' && $value == 1){
-				$this->status = 'method';
-				$this->root_struct_name = $name;
-				$this->root_struct = $pos;
-				$this->debug("found root struct $this->root_struct_name, pos $pos");
-			}
-            // for doclit
-            $attstr .= " $key=\"$value\"";
-		}
-        // get namespace - must be done after namespace atts are processed
-		if(isset($prefix)){
-			$this->message[$pos]['namespace'] = $this->namespaces[$prefix];
-			$this->default_namespace = $this->namespaces[$prefix];
-		} else {
-			$this->message[$pos]['namespace'] = $this->default_namespace;
-		}
-        if($this->status == 'header'){
-        	if ($this->root_header != $pos) {
-	        	$this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
-	        }
-        } elseif($this->root_struct_name != ''){
-        	$this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
-        }
-	}
-
-	/**
-	* end-element handler
-	*
-	* @param    resource $parser XML parser object
-	* @param    string $name element name
-	* @access   private
-	*/
-	function end_element($parser, $name) {
-		// position of current element is equal to the last value left in depth_array for my depth
-		$pos = $this->depth_array[$this->depth--];
-
-        // get element prefix
-		if(strpos($name,':')){
-			// get ns prefix
-			$prefix = substr($name,0,strpos($name,':'));
-			// get unqualified name
-			$name = substr(strstr($name,':'),1);
-		}
-		
-		// build to native type
-		if(isset($this->body_position) && $pos > $this->body_position){
-			// deal w/ multirefs
-			if(isset($this->message[$pos]['attrs']['href'])){
-				// get id
-				$id = substr($this->message[$pos]['attrs']['href'],1);
-				// add placeholder to href array
-				$this->multirefs[$id][$pos] = 'placeholder';
-				// add set a reference to it as the result value
-				$this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
-            // build complexType values
-			} elseif($this->message[$pos]['children'] != ''){
-				// if result has already been generated (struct/array)
-				if(!isset($this->message[$pos]['result'])){
-					$this->message[$pos]['result'] = $this->buildVal($pos);
-				}
-			// build complexType values of attributes and possibly simpleContent
-			} elseif (isset($this->message[$pos]['xattrs'])) {
-				if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
-					$this->message[$pos]['xattrs']['!'] = null;
-				} elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
-	            	if (isset($this->message[$pos]['type'])) {
-						$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
-					} else {
-						$parent = $this->message[$pos]['parent'];
-						if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
-							$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
-						} else {
-							$this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
-						}
-					}
-				}
-				$this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
-			// set value of simpleType (or nil complexType)
-			} else {
-            	//$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
-				if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
-					$this->message[$pos]['xattrs']['!'] = null;
-				} elseif (isset($this->message[$pos]['type'])) {
-					$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
-				} else {
-					$parent = $this->message[$pos]['parent'];
-					if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
-						$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
-					} else {
-						$this->message[$pos]['result'] = $this->message[$pos]['cdata'];
-					}
-				}
-
-				/* add value to parent's result, if parent is struct/array
-				$parent = $this->message[$pos]['parent'];
-				if($this->message[$parent]['type'] != 'map'){
-					if(strtolower($this->message[$parent]['type']) == 'array'){
-						$this->message[$parent]['result'][] = $this->message[$pos]['result'];
-					} else {
-						$this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
-					}
-				}
-				*/
-			}
-		}
-		
-        // for doclit
-        if($this->status == 'header'){
-        	if ($this->root_header != $pos) {
-	        	$this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
-	        }
-        } elseif($pos >= $this->root_struct){
-        	$this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
-        }
-		// switch status
-		if($pos == $this->root_struct){
-			$this->status = 'body';
-			$this->root_struct_namespace = $this->message[$pos]['namespace'];
-		} elseif($name == 'Body'){
-			$this->status = 'envelope';
-		 } elseif($name == 'Header'){
-			$this->status = 'envelope';
-		} elseif($name == 'Envelope'){
-			//
-		}
-		// set parent back to my parent
-		$this->parent = $this->message[$pos]['parent'];
-	}
-
-	/**
-	* element content handler
-	*
-	* @param    resource $parser XML parser object
-	* @param    string $data element content
-	* @access   private
-	*/
-	function character_data($parser, $data){
-		$pos = $this->depth_array[$this->depth];
-		if ($this->xml_encoding=='UTF-8'){
-			// TODO: add an option to disable this for folks who want
-			// raw UTF-8 that, e.g., might not map to iso-8859-1
-			// TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
-			if($this->decode_utf8){
-				$data = utf8_decode($data);
-			}
-		}
-        $this->message[$pos]['cdata'] .= $data;
-        // for doclit
-        if($this->status == 'header'){
-        	$this->responseHeaders .= $data;
-        } else {
-        	$this->document .= $data;
-        }
-	}
-
-	/**
-	* get the parsed message
-	*
-	* @return	mixed
-	* @access   public
-	*/
-	function get_response(){
-		return $this->soapresponse;
-	}
-
-	/**
-	* get the parsed headers
-	*
-	* @return	string XML or empty if no headers
-	* @access   public
-	*/
-	function getHeaders(){
-	    return $this->responseHeaders;
-	}
-
-	/**
-	* decodes simple types into PHP variables
-	*
-	* @param    string $value value to decode
-	* @param    string $type XML type to decode
-	* @param    string $typens XML type namespace to decode
-	* @return	mixed PHP value
-	* @access   private
-	*/
-	function decodeSimple($value, $type, $typens) {
-		// TODO: use the namespace!
-		if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
-			return (string) $value;
-		}
-		if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
-			return (int) $value;
-		}
-		if ($type == 'float' || $type == 'double' || $type == 'decimal') {
-			return (double) $value;
-		}
-		if ($type == 'boolean') {
-			if (strtolower($value) == 'false' || strtolower($value) == 'f') {
-				return false;
-			}
-			return (boolean) $value;
-		}
-		if ($type == 'base64' || $type == 'base64Binary') {
-			$this->debug('Decode base64 value');
-			return base64_decode($value);
-		}
-		// obscure numeric types
-		if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
-			|| $type == 'nonNegativeInteger' || $type == 'positiveInteger'
-			|| $type == 'unsignedInt'
-			|| $type == 'unsignedShort' || $type == 'unsignedByte') {
-			return (int) $value;
-		}
-		// bogus: parser treats array with no elements as a simple type
-		if ($type == 'array') {
-			return array();
-		}
-		// everything else
-		return (string) $value;
-	}
-
-	/**
-	* builds response structures for compound values (arrays/structs)
-	* and scalars
-	*
-	* @param    integer $pos position in node tree
-	* @return	mixed	PHP value
-	* @access   private
-	*/
-	function buildVal($pos){
-		if(!isset($this->message[$pos]['type'])){
-			$this->message[$pos]['type'] = '';
-		}
-		$this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
-		// if there are children...
-		if($this->message[$pos]['children'] != ''){
-			$this->debug('in buildVal, there are children');
-			$children = explode('|',$this->message[$pos]['children']);
-			array_shift($children); // knock off empty
-			// md array
-			if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
-            	$r=0; // rowcount
-            	$c=0; // colcount
-            	foreach($children as $child_pos){
-					$this->debug("in buildVal, got an MD array element: $r, $c");
-					$params[$r][] = $this->message[$child_pos]['result'];
-				    $c++;
-				    if($c == $this->message[$pos]['arrayCols']){
-				    	$c = 0;
-						$r++;
-				    }
-                }
-            // array
-			} elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
-                $this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
-                foreach($children as $child_pos){
-                	$params[] = &$this->message[$child_pos]['result'];
-                }
-            // apache Map type: java hashtable
-            } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
-                $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
-                foreach($children as $child_pos){
-                	$kv = explode("|",$this->message[$child_pos]['children']);
-                   	$params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
-                }
-            // generic compound type
-            //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
-		    } else {
-	    		// Apache Vector type: treat as an array
-                $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']);
-				if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
-					$notstruct = 1;
-				} else {
-					$notstruct = 0;
-	            }
-            	//
-            	foreach($children as $child_pos){
-            		if($notstruct){
-            			$params[] = &$this->message[$child_pos]['result'];
-            		} else {
-            			if (isset($params[$this->message[$child_pos]['name']])) {
-            				// de-serialize repeated element name into an array
-            				if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
-            					$params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
-            				}
-            				$params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
-            			} else {
-					    	$params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
-					    }
-                	}
-                }
-			}
-			if (isset($this->message[$pos]['xattrs'])) {
-                $this->debug('in buildVal, handling attributes');
-				foreach ($this->message[$pos]['xattrs'] as $n => $v) {
-					$params[$n] = $v;
-				}
-			}
-			// handle simpleContent
-			if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
-                $this->debug('in buildVal, handling simpleContent');
-            	if (isset($this->message[$pos]['type'])) {
-					$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
-				} else {
-					$parent = $this->message[$pos]['parent'];
-					if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
-						$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
-					} else {
-						$params['!'] = $this->message[$pos]['cdata'];
-					}
-				}
-			}
-			return is_array($params) ? $params : array();
-		} else {
-        	$this->debug('in buildVal, no children, building scalar');
-			$cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
-        	if (isset($this->message[$pos]['type'])) {
-				return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
-			}
-			$parent = $this->message[$pos]['parent'];
-			if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
-				return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
-			}
-           	return $this->message[$pos]['cdata'];
-		}
-	}
-}
-
-
-
-
+<?php
+
+
+
+
+/**
+*
+* soap_parser class parses SOAP XML messages into native PHP values
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class soap_parser extends nusoap_base {
+
+	var $xml = '';
+	var $xml_encoding = '';
+	var $method = '';
+	var $root_struct = '';
+	var $root_struct_name = '';
+	var $root_struct_namespace = '';
+	var $root_header = '';
+    var $document = '';			// incoming SOAP body (text)
+	// determines where in the message we are (envelope,header,body,method)
+	var $status = '';
+	var $position = 0;
+	var $depth = 0;
+	var $default_namespace = '';
+	var $namespaces = array();
+	var $message = array();
+    var $parent = '';
+	var $fault = false;
+	var $fault_code = '';
+	var $fault_str = '';
+	var $fault_detail = '';
+	var $depth_array = array();
+	var $debug_flag = true;
+	var $soapresponse = NULL;
+	var $responseHeaders = '';	// incoming SOAP headers (text)
+	var $body_position = 0;
+	// for multiref parsing:
+	// array of id => pos
+	var $ids = array();
+	// array of id => hrefs => pos
+	var $multirefs = array();
+	// toggle for auto-decoding element content
+	var $decode_utf8 = true;
+
+	/**
+	* constructor that actually does the parsing
+	*
+	* @param    string $xml SOAP message
+	* @param    string $encoding character encoding scheme of message
+	* @param    string $method method for which XML is parsed (unused?)
+	* @param    string $decode_utf8 whether to decode UTF-8 to ISO-8859-1
+	* @access   public
+	*/
+	function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
+		parent::nusoap_base();
+		$this->xml = $xml;
+		$this->xml_encoding = $encoding;
+		$this->method = $method;
+		$this->decode_utf8 = $decode_utf8;
+
+		// Check whether content has been read.
+		if(!empty($xml)){
+			// Check XML encoding
+			$pos_xml = strpos($xml, '<?xml');
+			if ($pos_xml !== FALSE) {
+				$xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
+				if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
+					$xml_encoding = $res[1];
+					if (strtoupper($xml_encoding) != $encoding) {
+						$err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
+						$this->debug($err);
+						if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
+							$this->setError($err);
+							return;
+						}
+						// when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
+					} else {
+						$this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
+					}
+				} else {
+					$this->debug('No encoding specified in XML declaration');
+				}
+			} else {
+				$this->debug('No XML declaration');
+			}
+			$this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding);
+			// Create an XML parser - why not xml_parser_create_ns?
+			$this->parser = xml_parser_create($this->xml_encoding);
+			// Set the options for parsing the XML data.
+			//xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+			xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+			xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
+			// Set the object for the parser.
+			xml_set_object($this->parser, $this);
+			// Set the element handlers for the parser.
+			xml_set_element_handler($this->parser, 'start_element','end_element');
+			xml_set_character_data_handler($this->parser,'character_data');
+
+			// Parse the XML file.
+			if(!xml_parse($this->parser,$xml,true)){
+			    // Display an error message.
+			    $err = sprintf('XML error parsing SOAP payload on line %d: %s',
+			    xml_get_current_line_number($this->parser),
+			    xml_error_string(xml_get_error_code($this->parser)));
+				$this->debug($err);
+				$this->debug("XML payload:\n" . $xml);
+				$this->setError($err);
+			} else {
+				$this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
+				// get final value
+				$this->soapresponse = $this->message[$this->root_struct]['result'];
+				// get header value: no, because this is documented as XML string
+//				if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
+//					$this->responseHeaders = $this->message[$this->root_header]['result'];
+//				}
+				// resolve hrefs/ids
+				if(sizeof($this->multirefs) > 0){
+					foreach($this->multirefs as $id => $hrefs){
+						$this->debug('resolving multirefs for id: '.$id);
+						$idVal = $this->buildVal($this->ids[$id]);
+						if (is_array($idVal) && isset($idVal['!id'])) {
+							unset($idVal['!id']);
+						}
+						foreach($hrefs as $refPos => $ref){
+							$this->debug('resolving href at pos '.$refPos);
+							$this->multirefs[$id][$refPos] = $idVal;
+						}
+					}
+				}
+			}
+			xml_parser_free($this->parser);
+		} else {
+			$this->debug('xml was empty, didn\'t parse!');
+			$this->setError('xml was empty, didn\'t parse!');
+		}
+	}
+
+	/**
+	* start-element handler
+	*
+	* @param    resource $parser XML parser object
+	* @param    string $name element name
+	* @param    array $attrs associative array of attributes
+	* @access   private
+	*/
+	function start_element($parser, $name, $attrs) {
+		// position in a total number of elements, starting from 0
+		// update class level pos
+		$pos = $this->position++;
+		// and set mine
+		$this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
+		// depth = how many levels removed from root?
+		// set mine as current global depth and increment global depth value
+		$this->message[$pos]['depth'] = $this->depth++;
+
+		// else add self as child to whoever the current parent is
+		if($pos != 0){
+			$this->message[$this->parent]['children'] .= '|'.$pos;
+		}
+		// set my parent
+		$this->message[$pos]['parent'] = $this->parent;
+		// set self as current parent
+		$this->parent = $pos;
+		// set self as current value for this depth
+		$this->depth_array[$this->depth] = $pos;
+		// get element prefix
+		if(strpos($name,':')){
+			// get ns prefix
+			$prefix = substr($name,0,strpos($name,':'));
+			// get unqualified name
+			$name = substr(strstr($name,':'),1);
+		}
+		// set status
+		if($name == 'Envelope'){
+			$this->status = 'envelope';
+		} elseif($name == 'Header'){
+			$this->root_header = $pos;
+			$this->status = 'header';
+		} elseif($name == 'Body'){
+			$this->status = 'body';
+			$this->body_position = $pos;
+		// set method
+		} elseif($this->status == 'body' && $pos == ($this->body_position+1)){
+			$this->status = 'method';
+			$this->root_struct_name = $name;
+			$this->root_struct = $pos;
+			$this->message[$pos]['type'] = 'struct';
+			$this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
+		}
+		// set my status
+		$this->message[$pos]['status'] = $this->status;
+		// set name
+		$this->message[$pos]['name'] = htmlspecialchars($name);
+		// set attrs
+		$this->message[$pos]['attrs'] = $attrs;
+
+		// loop through atts, logging ns and type declarations
+        $attstr = '';
+		foreach($attrs as $key => $value){
+        	$key_prefix = $this->getPrefix($key);
+			$key_localpart = $this->getLocalPart($key);
+			// if ns declarations, add to class level array of valid namespaces
+            if($key_prefix == 'xmlns'){
+				if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){
+					$this->XMLSchemaVersion = $value;
+					$this->namespaces['xsd'] = $this->XMLSchemaVersion;
+					$this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
+				}
+                $this->namespaces[$key_localpart] = $value;
+				// set method namespace
+				if($name == $this->root_struct_name){
+					$this->methodNamespace = $value;
+				}
+			// if it's a type declaration, set type
+            } elseif($key_localpart == 'type'){
+            	$value_prefix = $this->getPrefix($value);
+                $value_localpart = $this->getLocalPart($value);
+				$this->message[$pos]['type'] = $value_localpart;
+				$this->message[$pos]['typePrefix'] = $value_prefix;
+                if(isset($this->namespaces[$value_prefix])){
+                	$this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
+                } else if(isset($attrs['xmlns:'.$value_prefix])) {
+					$this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
+                }
+				// should do something here with the namespace of specified type?
+			} elseif($key_localpart == 'arrayType'){
+				$this->message[$pos]['type'] = 'array';
+				/* do arrayType ereg here
+				[1]    arrayTypeValue    ::=    atype asize
+				[2]    atype    ::=    QName rank*
+				[3]    rank    ::=    '[' (',')* ']'
+				[4]    asize    ::=    '[' length~ ']'
+				[5]    length    ::=    nextDimension* Digit+
+				[6]    nextDimension    ::=    Digit+ ','
+				*/
+				$expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]';
+				if(ereg($expr,$value,$regs)){
+					$this->message[$pos]['typePrefix'] = $regs[1];
+					$this->message[$pos]['arrayTypePrefix'] = $regs[1];
+	                if (isset($this->namespaces[$regs[1]])) {
+	                	$this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
+	                } else if (isset($attrs['xmlns:'.$regs[1]])) {
+						$this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
+	                }
+					$this->message[$pos]['arrayType'] = $regs[2];
+					$this->message[$pos]['arraySize'] = $regs[3];
+					$this->message[$pos]['arrayCols'] = $regs[4];
+				}
+			// specifies nil value (or not)
+			} elseif ($key_localpart == 'nil'){
+				$this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
+			// some other attribute
+			} elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
+				$this->message[$pos]['xattrs']['!' . $key] = $value;
+			}
+
+			if ($key == 'xmlns') {
+				$this->default_namespace = $value;
+			}
+			// log id
+			if($key == 'id'){
+				$this->ids[$value] = $pos;
+			}
+			// root
+			if($key_localpart == 'root' && $value == 1){
+				$this->status = 'method';
+				$this->root_struct_name = $name;
+				$this->root_struct = $pos;
+				$this->debug("found root struct $this->root_struct_name, pos $pos");
+			}
+            // for doclit
+            $attstr .= " $key=\"$value\"";
+		}
+        // get namespace - must be done after namespace atts are processed
+		if(isset($prefix)){
+			$this->message[$pos]['namespace'] = $this->namespaces[$prefix];
+			$this->default_namespace = $this->namespaces[$prefix];
+		} else {
+			$this->message[$pos]['namespace'] = $this->default_namespace;
+		}
+        if($this->status == 'header'){
+        	if ($this->root_header != $pos) {
+	        	$this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
+	        }
+        } elseif($this->root_struct_name != ''){
+        	$this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
+        }
+	}
+
+	/**
+	* end-element handler
+	*
+	* @param    resource $parser XML parser object
+	* @param    string $name element name
+	* @access   private
+	*/
+	function end_element($parser, $name) {
+		// position of current element is equal to the last value left in depth_array for my depth
+		$pos = $this->depth_array[$this->depth--];
+
+        // get element prefix
+		if(strpos($name,':')){
+			// get ns prefix
+			$prefix = substr($name,0,strpos($name,':'));
+			// get unqualified name
+			$name = substr(strstr($name,':'),1);
+		}
+		
+		// build to native type
+		if(isset($this->body_position) && $pos > $this->body_position){
+			// deal w/ multirefs
+			if(isset($this->message[$pos]['attrs']['href'])){
+				// get id
+				$id = substr($this->message[$pos]['attrs']['href'],1);
+				// add placeholder to href array
+				$this->multirefs[$id][$pos] = 'placeholder';
+				// add set a reference to it as the result value
+				$this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
+            // build complexType values
+			} elseif($this->message[$pos]['children'] != ''){
+				// if result has already been generated (struct/array)
+				if(!isset($this->message[$pos]['result'])){
+					$this->message[$pos]['result'] = $this->buildVal($pos);
+				}
+			// build complexType values of attributes and possibly simpleContent
+			} elseif (isset($this->message[$pos]['xattrs'])) {
+				if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
+					$this->message[$pos]['xattrs']['!'] = null;
+				} elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
+	            	if (isset($this->message[$pos]['type'])) {
+						$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+					} else {
+						$parent = $this->message[$pos]['parent'];
+						if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
+							$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+						} else {
+							$this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
+						}
+					}
+				}
+				$this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
+			// set value of simpleType (or nil complexType)
+			} else {
+            	//$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
+				if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
+					$this->message[$pos]['xattrs']['!'] = null;
+				} elseif (isset($this->message[$pos]['type'])) {
+					$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+				} else {
+					$parent = $this->message[$pos]['parent'];
+					if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
+						$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+					} else {
+						$this->message[$pos]['result'] = $this->message[$pos]['cdata'];
+					}
+				}
+
+				/* add value to parent's result, if parent is struct/array
+				$parent = $this->message[$pos]['parent'];
+				if($this->message[$parent]['type'] != 'map'){
+					if(strtolower($this->message[$parent]['type']) == 'array'){
+						$this->message[$parent]['result'][] = $this->message[$pos]['result'];
+					} else {
+						$this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
+					}
+				}
+				*/
+			}
+		}
+		
+        // for doclit
+        if($this->status == 'header'){
+        	if ($this->root_header != $pos) {
+	        	$this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
+	        }
+        } elseif($pos >= $this->root_struct){
+        	$this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
+        }
+		// switch status
+		if($pos == $this->root_struct){
+			$this->status = 'body';
+			$this->root_struct_namespace = $this->message[$pos]['namespace'];
+		} elseif($name == 'Body'){
+			$this->status = 'envelope';
+		 } elseif($name == 'Header'){
+			$this->status = 'envelope';
+		} elseif($name == 'Envelope'){
+			//
+		}
+		// set parent back to my parent
+		$this->parent = $this->message[$pos]['parent'];
+	}
+
+	/**
+	* element content handler
+	*
+	* @param    resource $parser XML parser object
+	* @param    string $data element content
+	* @access   private
+	*/
+	function character_data($parser, $data){
+		$pos = $this->depth_array[$this->depth];
+		if ($this->xml_encoding=='UTF-8'){
+			// TODO: add an option to disable this for folks who want
+			// raw UTF-8 that, e.g., might not map to iso-8859-1
+			// TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
+			if($this->decode_utf8){
+				$data = utf8_decode($data);
+			}
+		}
+        $this->message[$pos]['cdata'] .= $data;
+        // for doclit
+        if($this->status == 'header'){
+        	$this->responseHeaders .= $data;
+        } else {
+        	$this->document .= $data;
+        }
+	}
+
+	/**
+	* get the parsed message
+	*
+	* @return	mixed
+	* @access   public
+	*/
+	function get_response(){
+		return $this->soapresponse;
+	}
+
+	/**
+	* get the parsed headers
+	*
+	* @return	string XML or empty if no headers
+	* @access   public
+	*/
+	function getHeaders(){
+	    return $this->responseHeaders;
+	}
+
+	/**
+	* decodes simple types into PHP variables
+	*
+	* @param    string $value value to decode
+	* @param    string $type XML type to decode
+	* @param    string $typens XML type namespace to decode
+	* @return	mixed PHP value
+	* @access   private
+	*/
+	function decodeSimple($value, $type, $typens) {
+		// TODO: use the namespace!
+		if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
+			return (string) $value;
+		}
+		if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
+			return (int) $value;
+		}
+		if ($type == 'float' || $type == 'double' || $type == 'decimal') {
+			return (double) $value;
+		}
+		if ($type == 'boolean') {
+			if (strtolower($value) == 'false' || strtolower($value) == 'f') {
+				return false;
+			}
+			return (boolean) $value;
+		}
+		if ($type == 'base64' || $type == 'base64Binary') {
+			$this->debug('Decode base64 value');
+			return base64_decode($value);
+		}
+		// obscure numeric types
+		if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
+			|| $type == 'nonNegativeInteger' || $type == 'positiveInteger'
+			|| $type == 'unsignedInt'
+			|| $type == 'unsignedShort' || $type == 'unsignedByte') {
+			return (int) $value;
+		}
+		// bogus: parser treats array with no elements as a simple type
+		if ($type == 'array') {
+			return array();
+		}
+		// everything else
+		return (string) $value;
+	}
+
+	/**
+	* builds response structures for compound values (arrays/structs)
+	* and scalars
+	*
+	* @param    integer $pos position in node tree
+	* @return	mixed	PHP value
+	* @access   private
+	*/
+	function buildVal($pos){
+		if(!isset($this->message[$pos]['type'])){
+			$this->message[$pos]['type'] = '';
+		}
+		$this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
+		// if there are children...
+		if($this->message[$pos]['children'] != ''){
+			$this->debug('in buildVal, there are children');
+			$children = explode('|',$this->message[$pos]['children']);
+			array_shift($children); // knock off empty
+			// md array
+			if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
+            	$r=0; // rowcount
+            	$c=0; // colcount
+            	foreach($children as $child_pos){
+					$this->debug("in buildVal, got an MD array element: $r, $c");
+					$params[$r][] = $this->message[$child_pos]['result'];
+				    $c++;
+				    if($c == $this->message[$pos]['arrayCols']){
+				    	$c = 0;
+						$r++;
+				    }
+                }
+            // array
+			} elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
+                $this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
+                foreach($children as $child_pos){
+                	$params[] = &$this->message[$child_pos]['result'];
+                }
+            // apache Map type: java hashtable
+            } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
+                $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
+                foreach($children as $child_pos){
+                	$kv = explode("|",$this->message[$child_pos]['children']);
+                   	$params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
+                }
+            // generic compound type
+            //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
+		    } else {
+	    		// Apache Vector type: treat as an array
+                $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']);
+				if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
+					$notstruct = 1;
+				} else {
+					$notstruct = 0;
+	            }
+            	//
+            	foreach($children as $child_pos){
+            		if($notstruct){
+            			$params[] = &$this->message[$child_pos]['result'];
+            		} else {
+            			if (isset($params[$this->message[$child_pos]['name']])) {
+            				// de-serialize repeated element name into an array
+            				if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
+            					$params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
+            				}
+            				$params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
+            			} else {
+					    	$params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
+					    }
+                	}
+                }
+			}
+			if (isset($this->message[$pos]['xattrs'])) {
+                $this->debug('in buildVal, handling attributes');
+				foreach ($this->message[$pos]['xattrs'] as $n => $v) {
+					$params[$n] = $v;
+				}
+			}
+			// handle simpleContent
+			if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
+                $this->debug('in buildVal, handling simpleContent');
+            	if (isset($this->message[$pos]['type'])) {
+					$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+				} else {
+					$parent = $this->message[$pos]['parent'];
+					if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
+						$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+					} else {
+						$params['!'] = $this->message[$pos]['cdata'];
+					}
+				}
+			}
+			return is_array($params) ? $params : array();
+		} else {
+        	$this->debug('in buildVal, no children, building scalar');
+			$cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
+        	if (isset($this->message[$pos]['type'])) {
+				return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+			}
+			$parent = $this->message[$pos]['parent'];
+			if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
+				return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+			}
+           	return $this->message[$pos]['cdata'];
+		}
+	}
+}
+
+
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.soap_server.php b/htdocs/oscommerce_ws/ws_server/lib/class.soap_server.php
index 88afe2059af6e3329d70380f1cd0d13bc0a7ac1e..4033d32513423c5f20a72676718379f6d2e60bc7 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.soap_server.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.soap_server.php
@@ -1,1038 +1,1038 @@
-<?php
-
-
-
-
-/**
-*
-* soap_server allows the user to create a SOAP server
-* that is capable of receiving messages and returning responses
-*
-* NOTE: WSDL functionality is experimental
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class soap_server extends nusoap_base {
-	/**
-	 * HTTP headers of request
-	 * @var array
-	 * @access private
-	 */
-	var $headers = array();
-	/**
-	 * HTTP request
-	 * @var string
-	 * @access private
-	 */
-	var $request = '';
-	/**
-	 * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text)
-	 * @var string
-	 * @access public
-	 */
-	var $requestHeaders = '';
-	/**
-	 * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text)
-	 * @var string
-	 * @access public
-	 */
-	var $document = '';
-	/**
-	 * SOAP payload for request (text)
-	 * @var string
-	 * @access public
-	 */
-	var $requestSOAP = '';
-	/**
-	 * requested method namespace URI
-	 * @var string
-	 * @access private
-	 */
-	var $methodURI = '';
-	/**
-	 * name of method requested
-	 * @var string
-	 * @access private
-	 */
-	var $methodname = '';
-	/**
-	 * method parameters from request
-	 * @var array
-	 * @access private
-	 */
-	var $methodparams = array();
-	/**
-	 * SOAP Action from request
-	 * @var string
-	 * @access private
-	 */
-	var $SOAPAction = '';
-	/**
-	 * character set encoding of incoming (request) messages
-	 * @var string
-	 * @access public
-	 */
-	var $xml_encoding = '';
-	/**
-	 * toggles whether the parser decodes element content w/ utf8_decode()
-	 * @var boolean
-	 * @access public
-	 */
-    var $decode_utf8 = true;
-
-	/**
-	 * HTTP headers of response
-	 * @var array
-	 * @access public
-	 */
-	var $outgoing_headers = array();
-	/**
-	 * HTTP response
-	 * @var string
-	 * @access private
-	 */
-	var $response = '';
-	/**
-	 * SOAP headers for response (text)
-	 * @var string
-	 * @access public
-	 */
-	var $responseHeaders = '';
-	/**
-	 * SOAP payload for response (text)
-	 * @var string
-	 * @access private
-	 */
-	var $responseSOAP = '';
-	/**
-	 * method return value to place in response
-	 * @var mixed
-	 * @access private
-	 */
-	var $methodreturn = false;
-	/**
-	 * whether $methodreturn is a string of literal XML
-	 * @var boolean
-	 * @access public
-	 */
-	var $methodreturnisliteralxml = false;
-	/**
-	 * SOAP fault for response (or false)
-	 * @var mixed
-	 * @access private
-	 */
-	var $fault = false;
-	/**
-	 * text indication of result (for debugging)
-	 * @var string
-	 * @access private
-	 */
-	var $result = 'successful';
-
-	/**
-	 * assoc array of operations => opData; operations are added by the register()
-	 * method or by parsing an external WSDL definition
-	 * @var array
-	 * @access private
-	 */
-	var $operations = array();
-	/**
-	 * wsdl instance (if one)
-	 * @var mixed
-	 * @access private
-	 */
-	var $wsdl = false;
-	/**
-	 * URL for WSDL (if one)
-	 * @var mixed
-	 * @access private
-	 */
-	var $externalWSDLURL = false;
-	/**
-	 * whether to append debug to response as XML comment
-	 * @var boolean
-	 * @access public
-	 */
-	var $debug_flag = false;
-
-
-	/**
-	* constructor
-    * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to.
-	*
-    * @param mixed $wsdl file path or URL (string), or wsdl instance (object)
-	* @access   public
-	*/
-	function soap_server($wsdl=false){
-		parent::nusoap_base();
-		// turn on debugging?
-		global $debug;
-		global $HTTP_SERVER_VARS;
-
-		if (isset($_SERVER)) {
-			$this->debug("_SERVER is defined:");
-			$this->appendDebug($this->varDump($_SERVER));
-		} elseif (isset($HTTP_SERVER_VARS)) {
-			$this->debug("HTTP_SERVER_VARS is defined:");
-			$this->appendDebug($this->varDump($HTTP_SERVER_VARS));
-		} else {
-			$this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
-		}
-
-		if (isset($debug)) {
-			$this->debug("In soap_server, set debug_flag=$debug based on global flag");
-			$this->debug_flag = $debug;
-		} elseif (isset($_SERVER['QUERY_STRING'])) {
-			$qs = explode('&', $_SERVER['QUERY_STRING']);
-			foreach ($qs as $v) {
-				if (substr($v, 0, 6) == 'debug=') {
-					$this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
-					$this->debug_flag = substr($v, 6);
-				}
-			}
-		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
-			$qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
-			foreach ($qs as $v) {
-				if (substr($v, 0, 6) == 'debug=') {
-					$this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
-					$this->debug_flag = substr($v, 6);
-				}
-			}
-		}
-
-		// wsdl
-		if($wsdl){
-			$this->debug("In soap_server, WSDL is specified");
-			if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
-				$this->wsdl = $wsdl;
-				$this->externalWSDLURL = $this->wsdl->wsdl;
-				$this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
-			} else {
-				$this->debug('Create wsdl from ' . $wsdl);
-				$this->wsdl = new wsdl($wsdl);
-				$this->externalWSDLURL = $wsdl;
-			}
-			$this->appendDebug($this->wsdl->getDebug());
-			$this->wsdl->clearDebug();
-			if($err = $this->wsdl->getError()){
-				die('WSDL ERROR: '.$err);
-			}
-		}
-	}
-
-	/**
-	* processes request and returns response
-	*
-	* @param    string $data usually is the value of $HTTP_RAW_POST_DATA
-	* @access   public
-	*/
-	function service($data){
-		global $HTTP_SERVER_VARS;
-
-		if (isset($_SERVER['QUERY_STRING'])) {
-			$qs = $_SERVER['QUERY_STRING'];
-		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
-			$qs = $HTTP_SERVER_VARS['QUERY_STRING'];
-		} else {
-			$qs = '';
-		}
-		$this->debug("In service, query string=$qs");
-
-		if (ereg('wsdl', $qs) ){
-			$this->debug("In service, this is a request for WSDL");
-			if($this->externalWSDLURL){
-              if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL
-				header('Location: '.$this->externalWSDLURL);
-              } else { // assume file
-                header("Content-Type: text/xml\r\n");
-                $fp = fopen($this->externalWSDLURL, 'r');
-                fpassthru($fp);
-              }
-			} elseif ($this->wsdl) {
-				header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
-				print $this->wsdl->serialize($this->debug_flag);
-				if ($this->debug_flag) {
-					$this->debug('wsdl:');
-					$this->appendDebug($this->varDump($this->wsdl));
-					print $this->getDebugAsXMLComment();
-				}
-			} else {
-				header("Content-Type: text/html; charset=ISO-8859-1\r\n");
-				print "This service does not provide WSDL";
-			}
-		} elseif ($data == '' && $this->wsdl) {
-			$this->debug("In service, there is no data, so return Web description");
-			print $this->wsdl->webDescription();
-		} else {
-			$this->debug("In service, invoke the request");
-			$this->parse_request($data);
-			if (! $this->fault) {
-				$this->invoke_method();
-			}
-			if (! $this->fault) {
-				$this->serialize_return();
-			}
-			$this->send_response();
-		}
-	}
-
-	/**
-	* parses HTTP request headers.
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* headers
-	* request
-	* xml_encoding
-	* SOAPAction
-	*
-	* @access   private
-	*/
-	function parse_http_headers() {
-		global $HTTP_SERVER_VARS;
-
-		$this->request = '';
-		$this->SOAPAction = '';
-		if(function_exists('getallheaders')){
-			$this->debug("In parse_http_headers, use getallheaders");
-			$headers = getallheaders();
-			foreach($headers as $k=>$v){
-				$k = strtolower($k);
-				$this->headers[$k] = $v;
-				$this->request .= "$k: $v\r\n";
-				$this->debug("$k: $v");
-			}
-			// get SOAPAction header
-			if(isset($this->headers['soapaction'])){
-				$this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
-			}
-			// get the character encoding of the incoming request
-			if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
-				$enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
-				if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
-					$this->xml_encoding = strtoupper($enc);
-				} else {
-					$this->xml_encoding = 'US-ASCII';
-				}
-			} else {
-				// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-				$this->xml_encoding = 'ISO-8859-1';
-			}
-		} elseif(isset($_SERVER) && is_array($_SERVER)){
-			$this->debug("In parse_http_headers, use _SERVER");
-			foreach ($_SERVER as $k => $v) {
-				if (substr($k, 0, 5) == 'HTTP_') {
-					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
-				} else {
-					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
-				}
-				if ($k == 'soapaction') {
-					// get SOAPAction header
-					$k = 'SOAPAction';
-					$v = str_replace('"', '', $v);
-					$v = str_replace('\\', '', $v);
-					$this->SOAPAction = $v;
-				} else if ($k == 'content-type') {
-					// get the character encoding of the incoming request
-					if (strpos($v, '=')) {
-						$enc = substr(strstr($v, '='), 1);
-						$enc = str_replace('"', '', $enc);
-						$enc = str_replace('\\', '', $enc);
-						if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
-							$this->xml_encoding = strtoupper($enc);
-						} else {
-							$this->xml_encoding = 'US-ASCII';
-						}
-					} else {
-						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-						$this->xml_encoding = 'ISO-8859-1';
-					}
-				}
-				$this->headers[$k] = $v;
-				$this->request .= "$k: $v\r\n";
-				$this->debug("$k: $v");
-			}
-		} elseif (is_array($HTTP_SERVER_VARS)) {
-			$this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
-			foreach ($HTTP_SERVER_VARS as $k => $v) {
-				if (substr($k, 0, 5) == 'HTTP_') {
-					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
-				} else {
-					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
-				}
-				if ($k == 'soapaction') {
-					// get SOAPAction header
-					$k = 'SOAPAction';
-					$v = str_replace('"', '', $v);
-					$v = str_replace('\\', '', $v);
-					$this->SOAPAction = $v;
-				} else if ($k == 'content-type') {
-					// get the character encoding of the incoming request
-					if (strpos($v, '=')) {
-						$enc = substr(strstr($v, '='), 1);
-						$enc = str_replace('"', '', $enc);
-						$enc = str_replace('\\', '', $enc);
-						if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
-							$this->xml_encoding = strtoupper($enc);
-						} else {
-							$this->xml_encoding = 'US-ASCII';
-						}
-					} else {
-						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-						$this->xml_encoding = 'ISO-8859-1';
-					}
-				}
-				$this->headers[$k] = $v;
-				$this->request .= "$k: $v\r\n";
-				$this->debug("$k: $v");
-			}
-		} else {
-			$this->debug("In parse_http_headers, HTTP headers not accessible");
-			$this->setError("HTTP headers not accessible");
-		}
-	}
-
-	/**
-	* parses a request
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* headers
-	* request
-	* xml_encoding
-	* SOAPAction
-	* request
-	* requestSOAP
-	* methodURI
-	* methodname
-	* methodparams
-	* requestHeaders
-	* document
-	*
-	* This sets the fault field on error
-	*
-	* @param    string $data XML string
-	* @access   private
-	*/
-	function parse_request($data='') {
-		$this->debug('entering parse_request()');
-		$this->parse_http_headers();
-		$this->debug('got character encoding: '.$this->xml_encoding);
-		// uncompress if necessary
-		if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
-			$this->debug('got content encoding: ' . $this->headers['content-encoding']);
-			if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
-		    	// if decoding works, use it. else assume data wasn't gzencoded
-				if (function_exists('gzuncompress')) {
-					if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
-						$data = $degzdata;
-					} elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
-						$data = $degzdata;
-					} else {
-						$this->fault('Client', 'Errors occurred when trying to decode the data');
-						return;
-					}
-				} else {
-					$this->fault('Client', 'This Server does not support compressed data');
-					return;
-				}
-			}
-		}
-		$this->request .= "\r\n".$data;
-		$data = $this->parseRequest($this->headers, $data);
-		$this->requestSOAP = $data;
-		$this->debug('leaving parse_request');
-	}
-
-	/**
-	* invokes a PHP function for the requested SOAP method
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* methodreturn
-	*
-	* Note that the PHP function that is called may also set the following
-	* fields to affect the response sent to the client
-	*
-	* responseHeaders
-	* outgoing_headers
-	*
-	* This sets the fault field on error
-	*
-	* @access   private
-	*/
-	function invoke_method() {
-		$this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
-
-		if ($this->wsdl) {
-			if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
-				$this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
-				$this->appendDebug('opData=' . $this->varDump($this->opData));
-			} elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
-				// Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
-				$this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
-				$this->appendDebug('opData=' . $this->varDump($this->opData));
-				$this->methodname = $this->opData['name'];
-			} else {
-				$this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
-				$this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
-				return;
-			}
-		} else {
-			$this->debug('in invoke_method, no WSDL to validate method');
-		}
-
-		// if a . is present in $this->methodname, we see if there is a class in scope,
-		// which could be referred to. We will also distinguish between two deliminators,
-		// to allow methods to be called a the class or an instance
-		$class = '';
-		$method = '';
-		if (strpos($this->methodname, '..') > 0) {
-			$delim = '..';
-		} else if (strpos($this->methodname, '.') > 0) {
-			$delim = '.';
-		} else {
-			$delim = '';
-		}
-
-		if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
-			class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
-			// get the class and method name
-			$class = substr($this->methodname, 0, strpos($this->methodname, $delim));
-			$method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
-			$this->debug("in invoke_method, class=$class method=$method delim=$delim");
-		}
-
-		// does method exist?
-		if ($class == '') {
-			if (!function_exists($this->methodname)) {
-				$this->debug("in invoke_method, function '$this->methodname' not found!");
-				$this->result = 'fault: method not found';
-				$this->fault('Client',"method '$this->methodname' not defined in service");
-				return;
-			}
-		} else {
-			$method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
-			if (!in_array($method_to_compare, get_class_methods($class))) {
-				$this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
-				$this->result = 'fault: method not found';
-				$this->fault('Client',"method '$this->methodname' not defined in service");
-				return;
-			}
-		}
-
-		// evaluate message, getting back parameters
-		// verify that request parameters match the method's signature
-		if(! $this->verify_method($this->methodname,$this->methodparams)){
-			// debug
-			$this->debug('ERROR: request not verified against method signature');
-			$this->result = 'fault: request failed validation against method signature';
-			// return fault
-			$this->fault('Client',"Operation '$this->methodname' not defined in service.");
-			return;
-		}
-
-		// if there are parameters to pass
-		$this->debug('in invoke_method, params:');
-		$this->appendDebug($this->varDump($this->methodparams));
-		$this->debug("in invoke_method, calling '$this->methodname'");
-		if (!function_exists('call_user_func_array')) {
-			if ($class == '') {
-				$this->debug('in invoke_method, calling function using eval()');
-				$funcCall = "\$this->methodreturn = $this->methodname(";
-			} else {
-				if ($delim == '..') {
-					$this->debug('in invoke_method, calling class method using eval()');
-					$funcCall = "\$this->methodreturn = ".$class."::".$method."(";
-				} else {
-					$this->debug('in invoke_method, calling instance method using eval()');
-					// generate unique instance name
-					$instname = "\$inst_".time();
-					$funcCall = $instname." = new ".$class."(); ";
-					$funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
-				}
-			}
-			if ($this->methodparams) {
-				foreach ($this->methodparams as $param) {
-					if (is_array($param)) {
-						$this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
-						return;
-					}
-					$funcCall .= "\"$param\",";
-				}
-				$funcCall = substr($funcCall, 0, -1);
-			}
-			$funcCall .= ');';
-			$this->debug('in invoke_method, function call: '.$funcCall);
-			@eval($funcCall);
-		} else {
-			if ($class == '') {
-				$this->debug('in invoke_method, calling function using call_user_func_array()');
-				$call_arg = "$this->methodname";	// straight assignment changes $this->methodname to lower case after call_user_func_array()
-			} elseif ($delim == '..') {
-				$this->debug('in invoke_method, calling class method using call_user_func_array()');
-				$call_arg = array ($class, $method);
-			} else {
-				$this->debug('in invoke_method, calling instance method using call_user_func_array()');
-				$instance = new $class ();
-				$call_arg = array(&$instance, $method);
-			}
-			$this->methodreturn = call_user_func_array($call_arg, $this->methodparams);
-		}
-        $this->debug('in invoke_method, methodreturn:');
-        $this->appendDebug($this->varDump($this->methodreturn));
-		$this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn));
-	}
-
-	/**
-	* serializes the return value from a PHP function into a full SOAP Envelope
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* responseSOAP
-	*
-	* This sets the fault field on error
-	*
-	* @access   private
-	*/
-	function serialize_return() {
-		$this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
-		// if fault
-		if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) {
-			$this->debug('got a fault object from method');
-			$this->fault = $this->methodreturn;
-			return;
-		} elseif ($this->methodreturnisliteralxml) {
-			$return_val = $this->methodreturn;
-		// returned value(s)
-		} else {
-			$this->debug('got a(n) '.gettype($this->methodreturn).' from method');
-			$this->debug('serializing return value');
-			if($this->wsdl){
-				// weak attempt at supporting multiple output params
-				if(sizeof($this->opData['output']['parts']) > 1){
-			    	$opParams = $this->methodreturn;
-			    } else {
-			    	// TODO: is this really necessary?
-			    	$opParams = array($this->methodreturn);
-			    }
-			    $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
-			    $this->appendDebug($this->wsdl->getDebug());
-			    $this->wsdl->clearDebug();
-				if($errstr = $this->wsdl->getError()){
-					$this->debug('got wsdl error: '.$errstr);
-					$this->fault('Server', 'unable to serialize result');
-					return;
-				}
-			} else {
-				if (isset($this->methodreturn)) {
-					$return_val = $this->serialize_val($this->methodreturn, 'return');
-				} else {
-					$return_val = '';
-					$this->debug('in absence of WSDL, assume void return for backward compatibility');
-				}
-			}
-		}
-		$this->debug('return value:');
-		$this->appendDebug($this->varDump($return_val));
-
-		$this->debug('serializing response');
-		if ($this->wsdl) {
-			$this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
-			if ($this->opData['style'] == 'rpc') {
-				$this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
-				if ($this->opData['output']['use'] == 'literal') {
-					$payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>";
-				} else {
-					$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
-				}
-			} else {
-				$this->debug('style is not rpc for serialization: assume document');
-				$payload = $return_val;
-			}
-		} else {
-			$this->debug('do not have WSDL for serialization: assume rpc/encoded');
-			$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
-		}
-		$this->result = 'successful';
-		if($this->wsdl){
-			//if($this->debug_flag){
-            	$this->appendDebug($this->wsdl->getDebug());
-            //	}
-			if (isset($opData['output']['encodingStyle'])) {
-				$encodingStyle = $opData['output']['encodingStyle'];
-			} else {
-				$encodingStyle = '';
-			}
-			// Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
-			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle);
-		} else {
-			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
-		}
-		$this->debug("Leaving serialize_return");
-	}
-
-	/**
-	* sends an HTTP response
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* outgoing_headers
-	* response
-	*
-	* @access   private
-	*/
-	function send_response() {
-		$this->debug('Enter send_response');
-		if ($this->fault) {
-			$payload = $this->fault->serialize();
-			$this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
-			$this->outgoing_headers[] = "Status: 500 Internal Server Error";
-		} else {
-			$payload = $this->responseSOAP;
-			// Some combinations of PHP+Web server allow the Status
-			// to come through as a header.  Since OK is the default
-			// just do nothing.
-			// $this->outgoing_headers[] = "HTTP/1.0 200 OK";
-			// $this->outgoing_headers[] = "Status: 200 OK";
-		}
-        // add debug data if in debug mode
-		if(isset($this->debug_flag) && $this->debug_flag){
-        	$payload .= $this->getDebugAsXMLComment();
-        }
-		$this->outgoing_headers[] = "Server: $this->title Server v$this->version";
-		ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
-		$this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
-		// Let the Web server decide about this
-		//$this->outgoing_headers[] = "Connection: Close\r\n";
-		$payload = $this->getHTTPBody($payload);
-		$type = $this->getHTTPContentType();
-		$charset = $this->getHTTPContentTypeCharset();
-		$this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
-		//begin code to compress payload - by John
-		// NOTE: there is no way to know whether the Web server will also compress
-		// this data.
-		if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {	
-			if (strstr($this->headers['accept-encoding'], 'gzip')) {
-				if (function_exists('gzencode')) {
-					if (isset($this->debug_flag) && $this->debug_flag) {
-						$payload .= "<!-- Content being gzipped -->";
-					}
-					$this->outgoing_headers[] = "Content-Encoding: gzip";
-					$payload = gzencode($payload);
-				} else {
-					if (isset($this->debug_flag) && $this->debug_flag) {
-						$payload .= "<!-- Content will not be gzipped: no gzencode -->";
-					}
-				}
-			} elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
-				// Note: MSIE requires gzdeflate output (no Zlib header and checksum),
-				// instead of gzcompress output,
-				// which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
-				if (function_exists('gzdeflate')) {
-					if (isset($this->debug_flag) && $this->debug_flag) {
-						$payload .= "<!-- Content being deflated -->";
-					}
-					$this->outgoing_headers[] = "Content-Encoding: deflate";
-					$payload = gzdeflate($payload);
-				} else {
-					if (isset($this->debug_flag) && $this->debug_flag) {
-						$payload .= "<!-- Content will not be deflated: no gzcompress -->";
-					}
-				}
-			}
-		}
-		//end code
-		$this->outgoing_headers[] = "Content-Length: ".strlen($payload);
-		reset($this->outgoing_headers);
-		foreach($this->outgoing_headers as $hdr){
-			header($hdr, false);
-		}
-		print $payload;
-		$this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
-	}
-
-	/**
-	* takes the value that was created by parsing the request
-	* and compares to the method's signature, if available.
-	*
-	* @param	string	$operation	The operation to be invoked
-	* @param	array	$request	The array of parameter values
-	* @return	boolean	Whether the operation was found
-	* @access   private
-	*/
-	function verify_method($operation,$request){
-		if(isset($this->wsdl) && is_object($this->wsdl)){
-			if($this->wsdl->getOperationData($operation)){
-				return true;
-			}
-	    } elseif(isset($this->operations[$operation])){
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	* processes SOAP message received from client
-	*
-	* @param	array	$headers	The HTTP headers
-	* @param	string	$data		unprocessed request data from client
-	* @return	mixed	value of the message, decoded into a PHP type
-	* @access   private
-	*/
-    function parseRequest($headers, $data) {
-		$this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
-		if (!strstr($headers['content-type'], 'text/xml')) {
-			$this->setError('Request not of type text/xml');
-			return false;
-		}
-		if (strpos($headers['content-type'], '=')) {
-			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
-			$this->debug('Got response encoding: ' . $enc);
-			if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
-				$this->xml_encoding = strtoupper($enc);
-			} else {
-				$this->xml_encoding = 'US-ASCII';
-			}
-		} else {
-			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-			$this->xml_encoding = 'ISO-8859-1';
-		}
-		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
-		// parse response, get soap parser obj
-		$parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
-		// parser debug
-		$this->debug("parser debug: \n".$parser->getDebug());
-		// if fault occurred during message parsing
-		if($err = $parser->getError()){
-			$this->result = 'fault: error in msg parsing: '.$err;
-			$this->fault('Client',"error in msg parsing:\n".$err);
-		// else successfully parsed request into soapval object
-		} else {
-			// get/set methodname
-			$this->methodURI = $parser->root_struct_namespace;
-			$this->methodname = $parser->root_struct_name;
-			$this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
-			$this->debug('calling parser->get_response()');
-			$this->methodparams = $parser->get_response();
-			// get SOAP headers
-			$this->requestHeaders = $parser->getHeaders();
-            // add document for doclit support
-            $this->document = $parser->document;
-		}
-	 }
-
-	/**
-	* gets the HTTP body for the current response.
-	*
-	* @param string $soapmsg The SOAP payload
-	* @return string The HTTP body, which includes the SOAP payload
-	* @access private
-	*/
-	function getHTTPBody($soapmsg) {
-		return $soapmsg;
-	}
-	
-	/**
-	* gets the HTTP content type for the current response.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type for the current response.
-	* @access private
-	*/
-	function getHTTPContentType() {
-		return 'text/xml';
-	}
-	
-	/**
-	* gets the HTTP content type charset for the current response.
-	* returns false for non-text content types.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type charset for the current response.
-	* @access private
-	*/
-	function getHTTPContentTypeCharset() {
-		return $this->soap_defencoding;
-	}
-
-	/**
-	* add a method to the dispatch map (this has been replaced by the register method)
-	*
-	* @param    string $methodname
-	* @param    string $in array of input values
-	* @param    string $out array of output values
-	* @access   public
-	* @deprecated
-	*/
-	function add_to_map($methodname,$in,$out){
-			$this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
-	}
-
-	/**
-	* register a service function with the server
-	*
-	* @param    string $name the name of the PHP function, class.method or class..method
-	* @param    array $in assoc array of input values: key = param name, value = param type
-	* @param    array $out assoc array of output values: key = param name, value = param type
-	* @param	mixed $namespace the element namespace for the method or false
-	* @param	mixed $soapaction the soapaction for the method or false
-	* @param	mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically
-	* @param	mixed $use optional (encoded|literal) or false
-	* @param	string $documentation optional Description to include in WSDL
-	* @param	string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
-	* @access   public
-	*/
-	function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
-		global $HTTP_SERVER_VARS;
-
-		if($this->externalWSDLURL){
-			die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
-		}
-		if (! $name) {
-			die('You must specify a name when you register an operation');
-		}
-		if (!is_array($in)) {
-			die('You must provide an array for operation inputs');
-		}
-		if (!is_array($out)) {
-			die('You must provide an array for operation outputs');
-		}
-		if(false == $namespace) {
-		}
-		if(false == $soapaction) {
-			if (isset($_SERVER)) {
-				$SERVER_NAME = $_SERVER['SERVER_NAME'];
-				$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
-			} elseif (isset($HTTP_SERVER_VARS)) {
-				$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
-				$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
-			} else {
-				$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
-			}
-			$soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name";
-		}
-		if(false == $style) {
-			$style = "rpc";
-		}
-		if(false == $use) {
-			$use = "encoded";
-		}
-		if ($use == 'encoded' && $encodingStyle = '') {
-			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-		}
-
-		$this->operations[$name] = array(
-	    'name' => $name,
-	    'in' => $in,
-	    'out' => $out,
-	    'namespace' => $namespace,
-	    'soapaction' => $soapaction,
-	    'style' => $style);
-        if($this->wsdl){
-        	$this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
-	    }
-		return true;
-	}
-
-	/**
-	* Specify a fault to be returned to the client.
-	* This also acts as a flag to the server that a fault has occured.
-	*
-	* @param	string $faultcode
-	* @param	string $faultstring
-	* @param	string $faultactor
-	* @param	string $faultdetail
-	* @access   public
-	*/
-	function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
-		if ($faultdetail == '' && $this->debug_flag) {
-			$faultdetail = $this->getDebug();
-		}
-		$this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
-		$this->fault->soap_defencoding = $this->soap_defencoding;
-	}
-
-    /**
-    * Sets up wsdl object.
-    * Acts as a flag to enable internal WSDL generation
-    *
-    * @param string $serviceName, name of the service
-    * @param mixed $namespace optional 'tns' service namespace or false
-    * @param mixed $endpoint optional URL of service endpoint or false
-    * @param string $style optional (rpc|document) WSDL style (also specified by operation)
-    * @param string $transport optional SOAP transport
-    * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false
-    */
-    function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
-    {
-    	global $HTTP_SERVER_VARS;
-
-		if (isset($_SERVER)) {
-			$SERVER_NAME = $_SERVER['SERVER_NAME'];
-			$SERVER_PORT = $_SERVER['SERVER_PORT'];
-			$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
-			$HTTPS = $_SERVER['HTTPS'];
-		} elseif (isset($HTTP_SERVER_VARS)) {
-			$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
-			$SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
-			$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
-			$HTTPS = $HTTP_SERVER_VARS['HTTPS'];
-		} else {
-			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
-		}
-		if ($SERVER_PORT == 80) {
-			$SERVER_PORT = '';
-		} else {
-			$SERVER_PORT = ':' . $SERVER_PORT;
-		}
-        if(false == $namespace) {
-            $namespace = "http://$SERVER_NAME/soap/$serviceName";
-        }
-        
-        if(false == $endpoint) {
-        	if ($HTTPS == '1' || $HTTPS == 'on') {
-        		$SCHEME = 'https';
-        	} else {
-        		$SCHEME = 'http';
-        	}
-            $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
-        }
-        
-        if(false == $schemaTargetNamespace) {
-            $schemaTargetNamespace = $namespace;
-        }
-        
-		$this->wsdl = new wsdl;
-		$this->wsdl->serviceName = $serviceName;
-        $this->wsdl->endpoint = $endpoint;
-		$this->wsdl->namespaces['tns'] = $namespace;
-		$this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
-		$this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
-		if ($schemaTargetNamespace != $namespace) {
-			$this->wsdl->namespaces['types'] = $schemaTargetNamespace;
-		}
-        $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces);
-        $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
-        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
-        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
-        $this->wsdl->bindings[$serviceName.'Binding'] = array(
-        	'name'=>$serviceName.'Binding',
-            'style'=>$style,
-            'transport'=>$transport,
-            'portType'=>$serviceName.'PortType');
-        $this->wsdl->ports[$serviceName.'Port'] = array(
-        	'binding'=>$serviceName.'Binding',
-            'location'=>$endpoint,
-            'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
-    }
-}
-
-
-
-
+<?php
+
+
+
+
+/**
+*
+* soap_server allows the user to create a SOAP server
+* that is capable of receiving messages and returning responses
+*
+* NOTE: WSDL functionality is experimental
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class soap_server extends nusoap_base {
+	/**
+	 * HTTP headers of request
+	 * @var array
+	 * @access private
+	 */
+	var $headers = array();
+	/**
+	 * HTTP request
+	 * @var string
+	 * @access private
+	 */
+	var $request = '';
+	/**
+	 * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text)
+	 * @var string
+	 * @access public
+	 */
+	var $requestHeaders = '';
+	/**
+	 * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text)
+	 * @var string
+	 * @access public
+	 */
+	var $document = '';
+	/**
+	 * SOAP payload for request (text)
+	 * @var string
+	 * @access public
+	 */
+	var $requestSOAP = '';
+	/**
+	 * requested method namespace URI
+	 * @var string
+	 * @access private
+	 */
+	var $methodURI = '';
+	/**
+	 * name of method requested
+	 * @var string
+	 * @access private
+	 */
+	var $methodname = '';
+	/**
+	 * method parameters from request
+	 * @var array
+	 * @access private
+	 */
+	var $methodparams = array();
+	/**
+	 * SOAP Action from request
+	 * @var string
+	 * @access private
+	 */
+	var $SOAPAction = '';
+	/**
+	 * character set encoding of incoming (request) messages
+	 * @var string
+	 * @access public
+	 */
+	var $xml_encoding = '';
+	/**
+	 * toggles whether the parser decodes element content w/ utf8_decode()
+	 * @var boolean
+	 * @access public
+	 */
+    var $decode_utf8 = true;
+
+	/**
+	 * HTTP headers of response
+	 * @var array
+	 * @access public
+	 */
+	var $outgoing_headers = array();
+	/**
+	 * HTTP response
+	 * @var string
+	 * @access private
+	 */
+	var $response = '';
+	/**
+	 * SOAP headers for response (text)
+	 * @var string
+	 * @access public
+	 */
+	var $responseHeaders = '';
+	/**
+	 * SOAP payload for response (text)
+	 * @var string
+	 * @access private
+	 */
+	var $responseSOAP = '';
+	/**
+	 * method return value to place in response
+	 * @var mixed
+	 * @access private
+	 */
+	var $methodreturn = false;
+	/**
+	 * whether $methodreturn is a string of literal XML
+	 * @var boolean
+	 * @access public
+	 */
+	var $methodreturnisliteralxml = false;
+	/**
+	 * SOAP fault for response (or false)
+	 * @var mixed
+	 * @access private
+	 */
+	var $fault = false;
+	/**
+	 * text indication of result (for debugging)
+	 * @var string
+	 * @access private
+	 */
+	var $result = 'successful';
+
+	/**
+	 * assoc array of operations => opData; operations are added by the register()
+	 * method or by parsing an external WSDL definition
+	 * @var array
+	 * @access private
+	 */
+	var $operations = array();
+	/**
+	 * wsdl instance (if one)
+	 * @var mixed
+	 * @access private
+	 */
+	var $wsdl = false;
+	/**
+	 * URL for WSDL (if one)
+	 * @var mixed
+	 * @access private
+	 */
+	var $externalWSDLURL = false;
+	/**
+	 * whether to append debug to response as XML comment
+	 * @var boolean
+	 * @access public
+	 */
+	var $debug_flag = false;
+
+
+	/**
+	* constructor
+    * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to.
+	*
+    * @param mixed $wsdl file path or URL (string), or wsdl instance (object)
+	* @access   public
+	*/
+	function soap_server($wsdl=false){
+		parent::nusoap_base();
+		// turn on debugging?
+		global $debug;
+		global $HTTP_SERVER_VARS;
+
+		if (isset($_SERVER)) {
+			$this->debug("_SERVER is defined:");
+			$this->appendDebug($this->varDump($_SERVER));
+		} elseif (isset($HTTP_SERVER_VARS)) {
+			$this->debug("HTTP_SERVER_VARS is defined:");
+			$this->appendDebug($this->varDump($HTTP_SERVER_VARS));
+		} else {
+			$this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
+		}
+
+		if (isset($debug)) {
+			$this->debug("In soap_server, set debug_flag=$debug based on global flag");
+			$this->debug_flag = $debug;
+		} elseif (isset($_SERVER['QUERY_STRING'])) {
+			$qs = explode('&', $_SERVER['QUERY_STRING']);
+			foreach ($qs as $v) {
+				if (substr($v, 0, 6) == 'debug=') {
+					$this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
+					$this->debug_flag = substr($v, 6);
+				}
+			}
+		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
+			$qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
+			foreach ($qs as $v) {
+				if (substr($v, 0, 6) == 'debug=') {
+					$this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
+					$this->debug_flag = substr($v, 6);
+				}
+			}
+		}
+
+		// wsdl
+		if($wsdl){
+			$this->debug("In soap_server, WSDL is specified");
+			if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
+				$this->wsdl = $wsdl;
+				$this->externalWSDLURL = $this->wsdl->wsdl;
+				$this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
+			} else {
+				$this->debug('Create wsdl from ' . $wsdl);
+				$this->wsdl = new wsdl($wsdl);
+				$this->externalWSDLURL = $wsdl;
+			}
+			$this->appendDebug($this->wsdl->getDebug());
+			$this->wsdl->clearDebug();
+			if($err = $this->wsdl->getError()){
+				die('WSDL ERROR: '.$err);
+			}
+		}
+	}
+
+	/**
+	* processes request and returns response
+	*
+	* @param    string $data usually is the value of $HTTP_RAW_POST_DATA
+	* @access   public
+	*/
+	function service($data){
+		global $HTTP_SERVER_VARS;
+
+		if (isset($_SERVER['QUERY_STRING'])) {
+			$qs = $_SERVER['QUERY_STRING'];
+		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
+			$qs = $HTTP_SERVER_VARS['QUERY_STRING'];
+		} else {
+			$qs = '';
+		}
+		$this->debug("In service, query string=$qs");
+
+		if (ereg('wsdl', $qs) ){
+			$this->debug("In service, this is a request for WSDL");
+			if($this->externalWSDLURL){
+              if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL
+				header('Location: '.$this->externalWSDLURL);
+              } else { // assume file
+                header("Content-Type: text/xml\r\n");
+                $fp = fopen($this->externalWSDLURL, 'r');
+                fpassthru($fp);
+              }
+			} elseif ($this->wsdl) {
+				header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
+				print $this->wsdl->serialize($this->debug_flag);
+				if ($this->debug_flag) {
+					$this->debug('wsdl:');
+					$this->appendDebug($this->varDump($this->wsdl));
+					print $this->getDebugAsXMLComment();
+				}
+			} else {
+				header("Content-Type: text/html; charset=ISO-8859-1\r\n");
+				print "This service does not provide WSDL";
+			}
+		} elseif ($data == '' && $this->wsdl) {
+			$this->debug("In service, there is no data, so return Web description");
+			print $this->wsdl->webDescription();
+		} else {
+			$this->debug("In service, invoke the request");
+			$this->parse_request($data);
+			if (! $this->fault) {
+				$this->invoke_method();
+			}
+			if (! $this->fault) {
+				$this->serialize_return();
+			}
+			$this->send_response();
+		}
+	}
+
+	/**
+	* parses HTTP request headers.
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* headers
+	* request
+	* xml_encoding
+	* SOAPAction
+	*
+	* @access   private
+	*/
+	function parse_http_headers() {
+		global $HTTP_SERVER_VARS;
+
+		$this->request = '';
+		$this->SOAPAction = '';
+		if(function_exists('getallheaders')){
+			$this->debug("In parse_http_headers, use getallheaders");
+			$headers = getallheaders();
+			foreach($headers as $k=>$v){
+				$k = strtolower($k);
+				$this->headers[$k] = $v;
+				$this->request .= "$k: $v\r\n";
+				$this->debug("$k: $v");
+			}
+			// get SOAPAction header
+			if(isset($this->headers['soapaction'])){
+				$this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
+			}
+			// get the character encoding of the incoming request
+			if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
+				$enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
+				if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
+					$this->xml_encoding = strtoupper($enc);
+				} else {
+					$this->xml_encoding = 'US-ASCII';
+				}
+			} else {
+				// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+				$this->xml_encoding = 'ISO-8859-1';
+			}
+		} elseif(isset($_SERVER) && is_array($_SERVER)){
+			$this->debug("In parse_http_headers, use _SERVER");
+			foreach ($_SERVER as $k => $v) {
+				if (substr($k, 0, 5) == 'HTTP_') {
+					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
+				} else {
+					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
+				}
+				if ($k == 'soapaction') {
+					// get SOAPAction header
+					$k = 'SOAPAction';
+					$v = str_replace('"', '', $v);
+					$v = str_replace('\\', '', $v);
+					$this->SOAPAction = $v;
+				} else if ($k == 'content-type') {
+					// get the character encoding of the incoming request
+					if (strpos($v, '=')) {
+						$enc = substr(strstr($v, '='), 1);
+						$enc = str_replace('"', '', $enc);
+						$enc = str_replace('\\', '', $enc);
+						if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
+							$this->xml_encoding = strtoupper($enc);
+						} else {
+							$this->xml_encoding = 'US-ASCII';
+						}
+					} else {
+						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+						$this->xml_encoding = 'ISO-8859-1';
+					}
+				}
+				$this->headers[$k] = $v;
+				$this->request .= "$k: $v\r\n";
+				$this->debug("$k: $v");
+			}
+		} elseif (is_array($HTTP_SERVER_VARS)) {
+			$this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
+			foreach ($HTTP_SERVER_VARS as $k => $v) {
+				if (substr($k, 0, 5) == 'HTTP_') {
+					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
+				} else {
+					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
+				}
+				if ($k == 'soapaction') {
+					// get SOAPAction header
+					$k = 'SOAPAction';
+					$v = str_replace('"', '', $v);
+					$v = str_replace('\\', '', $v);
+					$this->SOAPAction = $v;
+				} else if ($k == 'content-type') {
+					// get the character encoding of the incoming request
+					if (strpos($v, '=')) {
+						$enc = substr(strstr($v, '='), 1);
+						$enc = str_replace('"', '', $enc);
+						$enc = str_replace('\\', '', $enc);
+						if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
+							$this->xml_encoding = strtoupper($enc);
+						} else {
+							$this->xml_encoding = 'US-ASCII';
+						}
+					} else {
+						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+						$this->xml_encoding = 'ISO-8859-1';
+					}
+				}
+				$this->headers[$k] = $v;
+				$this->request .= "$k: $v\r\n";
+				$this->debug("$k: $v");
+			}
+		} else {
+			$this->debug("In parse_http_headers, HTTP headers not accessible");
+			$this->setError("HTTP headers not accessible");
+		}
+	}
+
+	/**
+	* parses a request
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* headers
+	* request
+	* xml_encoding
+	* SOAPAction
+	* request
+	* requestSOAP
+	* methodURI
+	* methodname
+	* methodparams
+	* requestHeaders
+	* document
+	*
+	* This sets the fault field on error
+	*
+	* @param    string $data XML string
+	* @access   private
+	*/
+	function parse_request($data='') {
+		$this->debug('entering parse_request()');
+		$this->parse_http_headers();
+		$this->debug('got character encoding: '.$this->xml_encoding);
+		// uncompress if necessary
+		if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
+			$this->debug('got content encoding: ' . $this->headers['content-encoding']);
+			if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
+		    	// if decoding works, use it. else assume data wasn't gzencoded
+				if (function_exists('gzuncompress')) {
+					if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
+						$data = $degzdata;
+					} elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
+						$data = $degzdata;
+					} else {
+						$this->fault('Client', 'Errors occurred when trying to decode the data');
+						return;
+					}
+				} else {
+					$this->fault('Client', 'This Server does not support compressed data');
+					return;
+				}
+			}
+		}
+		$this->request .= "\r\n".$data;
+		$data = $this->parseRequest($this->headers, $data);
+		$this->requestSOAP = $data;
+		$this->debug('leaving parse_request');
+	}
+
+	/**
+	* invokes a PHP function for the requested SOAP method
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* methodreturn
+	*
+	* Note that the PHP function that is called may also set the following
+	* fields to affect the response sent to the client
+	*
+	* responseHeaders
+	* outgoing_headers
+	*
+	* This sets the fault field on error
+	*
+	* @access   private
+	*/
+	function invoke_method() {
+		$this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
+
+		if ($this->wsdl) {
+			if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
+				$this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
+				$this->appendDebug('opData=' . $this->varDump($this->opData));
+			} elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
+				// Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
+				$this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
+				$this->appendDebug('opData=' . $this->varDump($this->opData));
+				$this->methodname = $this->opData['name'];
+			} else {
+				$this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
+				$this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
+				return;
+			}
+		} else {
+			$this->debug('in invoke_method, no WSDL to validate method');
+		}
+
+		// if a . is present in $this->methodname, we see if there is a class in scope,
+		// which could be referred to. We will also distinguish between two deliminators,
+		// to allow methods to be called a the class or an instance
+		$class = '';
+		$method = '';
+		if (strpos($this->methodname, '..') > 0) {
+			$delim = '..';
+		} else if (strpos($this->methodname, '.') > 0) {
+			$delim = '.';
+		} else {
+			$delim = '';
+		}
+
+		if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
+			class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
+			// get the class and method name
+			$class = substr($this->methodname, 0, strpos($this->methodname, $delim));
+			$method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
+			$this->debug("in invoke_method, class=$class method=$method delim=$delim");
+		}
+
+		// does method exist?
+		if ($class == '') {
+			if (!function_exists($this->methodname)) {
+				$this->debug("in invoke_method, function '$this->methodname' not found!");
+				$this->result = 'fault: method not found';
+				$this->fault('Client',"method '$this->methodname' not defined in service");
+				return;
+			}
+		} else {
+			$method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
+			if (!in_array($method_to_compare, get_class_methods($class))) {
+				$this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
+				$this->result = 'fault: method not found';
+				$this->fault('Client',"method '$this->methodname' not defined in service");
+				return;
+			}
+		}
+
+		// evaluate message, getting back parameters
+		// verify that request parameters match the method's signature
+		if(! $this->verify_method($this->methodname,$this->methodparams)){
+			// debug
+			$this->debug('ERROR: request not verified against method signature');
+			$this->result = 'fault: request failed validation against method signature';
+			// return fault
+			$this->fault('Client',"Operation '$this->methodname' not defined in service.");
+			return;
+		}
+
+		// if there are parameters to pass
+		$this->debug('in invoke_method, params:');
+		$this->appendDebug($this->varDump($this->methodparams));
+		$this->debug("in invoke_method, calling '$this->methodname'");
+		if (!function_exists('call_user_func_array')) {
+			if ($class == '') {
+				$this->debug('in invoke_method, calling function using eval()');
+				$funcCall = "\$this->methodreturn = $this->methodname(";
+			} else {
+				if ($delim == '..') {
+					$this->debug('in invoke_method, calling class method using eval()');
+					$funcCall = "\$this->methodreturn = ".$class."::".$method."(";
+				} else {
+					$this->debug('in invoke_method, calling instance method using eval()');
+					// generate unique instance name
+					$instname = "\$inst_".time();
+					$funcCall = $instname." = new ".$class."(); ";
+					$funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
+				}
+			}
+			if ($this->methodparams) {
+				foreach ($this->methodparams as $param) {
+					if (is_array($param)) {
+						$this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
+						return;
+					}
+					$funcCall .= "\"$param\",";
+				}
+				$funcCall = substr($funcCall, 0, -1);
+			}
+			$funcCall .= ');';
+			$this->debug('in invoke_method, function call: '.$funcCall);
+			@eval($funcCall);
+		} else {
+			if ($class == '') {
+				$this->debug('in invoke_method, calling function using call_user_func_array()');
+				$call_arg = "$this->methodname";	// straight assignment changes $this->methodname to lower case after call_user_func_array()
+			} elseif ($delim == '..') {
+				$this->debug('in invoke_method, calling class method using call_user_func_array()');
+				$call_arg = array ($class, $method);
+			} else {
+				$this->debug('in invoke_method, calling instance method using call_user_func_array()');
+				$instance = new $class ();
+				$call_arg = array(&$instance, $method);
+			}
+			$this->methodreturn = call_user_func_array($call_arg, $this->methodparams);
+		}
+        $this->debug('in invoke_method, methodreturn:');
+        $this->appendDebug($this->varDump($this->methodreturn));
+		$this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn));
+	}
+
+	/**
+	* serializes the return value from a PHP function into a full SOAP Envelope
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* responseSOAP
+	*
+	* This sets the fault field on error
+	*
+	* @access   private
+	*/
+	function serialize_return() {
+		$this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
+		// if fault
+		if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) {
+			$this->debug('got a fault object from method');
+			$this->fault = $this->methodreturn;
+			return;
+		} elseif ($this->methodreturnisliteralxml) {
+			$return_val = $this->methodreturn;
+		// returned value(s)
+		} else {
+			$this->debug('got a(n) '.gettype($this->methodreturn).' from method');
+			$this->debug('serializing return value');
+			if($this->wsdl){
+				// weak attempt at supporting multiple output params
+				if(sizeof($this->opData['output']['parts']) > 1){
+			    	$opParams = $this->methodreturn;
+			    } else {
+			    	// TODO: is this really necessary?
+			    	$opParams = array($this->methodreturn);
+			    }
+			    $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
+			    $this->appendDebug($this->wsdl->getDebug());
+			    $this->wsdl->clearDebug();
+				if($errstr = $this->wsdl->getError()){
+					$this->debug('got wsdl error: '.$errstr);
+					$this->fault('Server', 'unable to serialize result');
+					return;
+				}
+			} else {
+				if (isset($this->methodreturn)) {
+					$return_val = $this->serialize_val($this->methodreturn, 'return');
+				} else {
+					$return_val = '';
+					$this->debug('in absence of WSDL, assume void return for backward compatibility');
+				}
+			}
+		}
+		$this->debug('return value:');
+		$this->appendDebug($this->varDump($return_val));
+
+		$this->debug('serializing response');
+		if ($this->wsdl) {
+			$this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
+			if ($this->opData['style'] == 'rpc') {
+				$this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
+				if ($this->opData['output']['use'] == 'literal') {
+					$payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>";
+				} else {
+					$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
+				}
+			} else {
+				$this->debug('style is not rpc for serialization: assume document');
+				$payload = $return_val;
+			}
+		} else {
+			$this->debug('do not have WSDL for serialization: assume rpc/encoded');
+			$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
+		}
+		$this->result = 'successful';
+		if($this->wsdl){
+			//if($this->debug_flag){
+            	$this->appendDebug($this->wsdl->getDebug());
+            //	}
+			if (isset($opData['output']['encodingStyle'])) {
+				$encodingStyle = $opData['output']['encodingStyle'];
+			} else {
+				$encodingStyle = '';
+			}
+			// Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
+			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle);
+		} else {
+			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
+		}
+		$this->debug("Leaving serialize_return");
+	}
+
+	/**
+	* sends an HTTP response
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* outgoing_headers
+	* response
+	*
+	* @access   private
+	*/
+	function send_response() {
+		$this->debug('Enter send_response');
+		if ($this->fault) {
+			$payload = $this->fault->serialize();
+			$this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
+			$this->outgoing_headers[] = "Status: 500 Internal Server Error";
+		} else {
+			$payload = $this->responseSOAP;
+			// Some combinations of PHP+Web server allow the Status
+			// to come through as a header.  Since OK is the default
+			// just do nothing.
+			// $this->outgoing_headers[] = "HTTP/1.0 200 OK";
+			// $this->outgoing_headers[] = "Status: 200 OK";
+		}
+        // add debug data if in debug mode
+		if(isset($this->debug_flag) && $this->debug_flag){
+        	$payload .= $this->getDebugAsXMLComment();
+        }
+		$this->outgoing_headers[] = "Server: $this->title Server v$this->version";
+		ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
+		$this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
+		// Let the Web server decide about this
+		//$this->outgoing_headers[] = "Connection: Close\r\n";
+		$payload = $this->getHTTPBody($payload);
+		$type = $this->getHTTPContentType();
+		$charset = $this->getHTTPContentTypeCharset();
+		$this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
+		//begin code to compress payload - by John
+		// NOTE: there is no way to know whether the Web server will also compress
+		// this data.
+		if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {	
+			if (strstr($this->headers['accept-encoding'], 'gzip')) {
+				if (function_exists('gzencode')) {
+					if (isset($this->debug_flag) && $this->debug_flag) {
+						$payload .= "<!-- Content being gzipped -->";
+					}
+					$this->outgoing_headers[] = "Content-Encoding: gzip";
+					$payload = gzencode($payload);
+				} else {
+					if (isset($this->debug_flag) && $this->debug_flag) {
+						$payload .= "<!-- Content will not be gzipped: no gzencode -->";
+					}
+				}
+			} elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
+				// Note: MSIE requires gzdeflate output (no Zlib header and checksum),
+				// instead of gzcompress output,
+				// which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
+				if (function_exists('gzdeflate')) {
+					if (isset($this->debug_flag) && $this->debug_flag) {
+						$payload .= "<!-- Content being deflated -->";
+					}
+					$this->outgoing_headers[] = "Content-Encoding: deflate";
+					$payload = gzdeflate($payload);
+				} else {
+					if (isset($this->debug_flag) && $this->debug_flag) {
+						$payload .= "<!-- Content will not be deflated: no gzcompress -->";
+					}
+				}
+			}
+		}
+		//end code
+		$this->outgoing_headers[] = "Content-Length: ".strlen($payload);
+		reset($this->outgoing_headers);
+		foreach($this->outgoing_headers as $hdr){
+			header($hdr, false);
+		}
+		print $payload;
+		$this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
+	}
+
+	/**
+	* takes the value that was created by parsing the request
+	* and compares to the method's signature, if available.
+	*
+	* @param	string	$operation	The operation to be invoked
+	* @param	array	$request	The array of parameter values
+	* @return	boolean	Whether the operation was found
+	* @access   private
+	*/
+	function verify_method($operation,$request){
+		if(isset($this->wsdl) && is_object($this->wsdl)){
+			if($this->wsdl->getOperationData($operation)){
+				return true;
+			}
+	    } elseif(isset($this->operations[$operation])){
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	* processes SOAP message received from client
+	*
+	* @param	array	$headers	The HTTP headers
+	* @param	string	$data		unprocessed request data from client
+	* @return	mixed	value of the message, decoded into a PHP type
+	* @access   private
+	*/
+    function parseRequest($headers, $data) {
+		$this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
+		if (!strstr($headers['content-type'], 'text/xml')) {
+			$this->setError('Request not of type text/xml');
+			return false;
+		}
+		if (strpos($headers['content-type'], '=')) {
+			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
+			$this->debug('Got response encoding: ' . $enc);
+			if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
+				$this->xml_encoding = strtoupper($enc);
+			} else {
+				$this->xml_encoding = 'US-ASCII';
+			}
+		} else {
+			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+			$this->xml_encoding = 'ISO-8859-1';
+		}
+		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
+		// parse response, get soap parser obj
+		$parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
+		// parser debug
+		$this->debug("parser debug: \n".$parser->getDebug());
+		// if fault occurred during message parsing
+		if($err = $parser->getError()){
+			$this->result = 'fault: error in msg parsing: '.$err;
+			$this->fault('Client',"error in msg parsing:\n".$err);
+		// else successfully parsed request into soapval object
+		} else {
+			// get/set methodname
+			$this->methodURI = $parser->root_struct_namespace;
+			$this->methodname = $parser->root_struct_name;
+			$this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
+			$this->debug('calling parser->get_response()');
+			$this->methodparams = $parser->get_response();
+			// get SOAP headers
+			$this->requestHeaders = $parser->getHeaders();
+            // add document for doclit support
+            $this->document = $parser->document;
+		}
+	 }
+
+	/**
+	* gets the HTTP body for the current response.
+	*
+	* @param string $soapmsg The SOAP payload
+	* @return string The HTTP body, which includes the SOAP payload
+	* @access private
+	*/
+	function getHTTPBody($soapmsg) {
+		return $soapmsg;
+	}
+	
+	/**
+	* gets the HTTP content type for the current response.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type for the current response.
+	* @access private
+	*/
+	function getHTTPContentType() {
+		return 'text/xml';
+	}
+	
+	/**
+	* gets the HTTP content type charset for the current response.
+	* returns false for non-text content types.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type charset for the current response.
+	* @access private
+	*/
+	function getHTTPContentTypeCharset() {
+		return $this->soap_defencoding;
+	}
+
+	/**
+	* add a method to the dispatch map (this has been replaced by the register method)
+	*
+	* @param    string $methodname
+	* @param    string $in array of input values
+	* @param    string $out array of output values
+	* @access   public
+	* @deprecated
+	*/
+	function add_to_map($methodname,$in,$out){
+			$this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
+	}
+
+	/**
+	* register a service function with the server
+	*
+	* @param    string $name the name of the PHP function, class.method or class..method
+	* @param    array $in assoc array of input values: key = param name, value = param type
+	* @param    array $out assoc array of output values: key = param name, value = param type
+	* @param	mixed $namespace the element namespace for the method or false
+	* @param	mixed $soapaction the soapaction for the method or false
+	* @param	mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically
+	* @param	mixed $use optional (encoded|literal) or false
+	* @param	string $documentation optional Description to include in WSDL
+	* @param	string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
+	* @access   public
+	*/
+	function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
+		global $HTTP_SERVER_VARS;
+
+		if($this->externalWSDLURL){
+			die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
+		}
+		if (! $name) {
+			die('You must specify a name when you register an operation');
+		}
+		if (!is_array($in)) {
+			die('You must provide an array for operation inputs');
+		}
+		if (!is_array($out)) {
+			die('You must provide an array for operation outputs');
+		}
+		if(false == $namespace) {
+		}
+		if(false == $soapaction) {
+			if (isset($_SERVER)) {
+				$SERVER_NAME = $_SERVER['SERVER_NAME'];
+				$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
+			} elseif (isset($HTTP_SERVER_VARS)) {
+				$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
+				$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
+			} else {
+				$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
+			}
+			$soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name";
+		}
+		if(false == $style) {
+			$style = "rpc";
+		}
+		if(false == $use) {
+			$use = "encoded";
+		}
+		if ($use == 'encoded' && $encodingStyle = '') {
+			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+		}
+
+		$this->operations[$name] = array(
+	    'name' => $name,
+	    'in' => $in,
+	    'out' => $out,
+	    'namespace' => $namespace,
+	    'soapaction' => $soapaction,
+	    'style' => $style);
+        if($this->wsdl){
+        	$this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
+	    }
+		return true;
+	}
+
+	/**
+	* Specify a fault to be returned to the client.
+	* This also acts as a flag to the server that a fault has occured.
+	*
+	* @param	string $faultcode
+	* @param	string $faultstring
+	* @param	string $faultactor
+	* @param	string $faultdetail
+	* @access   public
+	*/
+	function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
+		if ($faultdetail == '' && $this->debug_flag) {
+			$faultdetail = $this->getDebug();
+		}
+		$this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
+		$this->fault->soap_defencoding = $this->soap_defencoding;
+	}
+
+    /**
+    * Sets up wsdl object.
+    * Acts as a flag to enable internal WSDL generation
+    *
+    * @param string $serviceName, name of the service
+    * @param mixed $namespace optional 'tns' service namespace or false
+    * @param mixed $endpoint optional URL of service endpoint or false
+    * @param string $style optional (rpc|document) WSDL style (also specified by operation)
+    * @param string $transport optional SOAP transport
+    * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false
+    */
+    function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
+    {
+    	global $HTTP_SERVER_VARS;
+
+		if (isset($_SERVER)) {
+			$SERVER_NAME = $_SERVER['SERVER_NAME'];
+			$SERVER_PORT = $_SERVER['SERVER_PORT'];
+			$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
+			$HTTPS = $_SERVER['HTTPS'];
+		} elseif (isset($HTTP_SERVER_VARS)) {
+			$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
+			$SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
+			$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
+			$HTTPS = $HTTP_SERVER_VARS['HTTPS'];
+		} else {
+			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
+		}
+		if ($SERVER_PORT == 80) {
+			$SERVER_PORT = '';
+		} else {
+			$SERVER_PORT = ':' . $SERVER_PORT;
+		}
+        if(false == $namespace) {
+            $namespace = "http://$SERVER_NAME/soap/$serviceName";
+        }
+        
+        if(false == $endpoint) {
+        	if ($HTTPS == '1' || $HTTPS == 'on') {
+        		$SCHEME = 'https';
+        	} else {
+        		$SCHEME = 'http';
+        	}
+            $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
+        }
+        
+        if(false == $schemaTargetNamespace) {
+            $schemaTargetNamespace = $namespace;
+        }
+        
+		$this->wsdl = new wsdl;
+		$this->wsdl->serviceName = $serviceName;
+        $this->wsdl->endpoint = $endpoint;
+		$this->wsdl->namespaces['tns'] = $namespace;
+		$this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
+		$this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
+		if ($schemaTargetNamespace != $namespace) {
+			$this->wsdl->namespaces['types'] = $schemaTargetNamespace;
+		}
+        $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces);
+        $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
+        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
+        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
+        $this->wsdl->bindings[$serviceName.'Binding'] = array(
+        	'name'=>$serviceName.'Binding',
+            'style'=>$style,
+            'transport'=>$transport,
+            'portType'=>$serviceName.'PortType');
+        $this->wsdl->ports[$serviceName.'Port'] = array(
+        	'binding'=>$serviceName.'Binding',
+            'location'=>$endpoint,
+            'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
+    }
+}
+
+
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.soap_transport_http.php b/htdocs/oscommerce_ws/ws_server/lib/class.soap_transport_http.php
index 71bd0678207c2e3e81b02c0eea226d255f2a18fe..078850080ea99cf80062d438d5fc2009ea5698a7 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.soap_transport_http.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.soap_transport_http.php
@@ -1,1038 +1,1038 @@
-<?php
-
-
-
-
-/**
-* transport class for sending/receiving data via HTTP and HTTPS
-* NOTE: PHP must be compiled with the CURL extension for HTTPS support
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access public
-*/
-class soap_transport_http extends nusoap_base {
-
-	var $url = '';
-	var $uri = '';
-	var $digest_uri = '';
-	var $scheme = '';
-	var $host = '';
-	var $port = '';
-	var $path = '';
-	var $request_method = 'POST';
-	var $protocol_version = '1.0';
-	var $encoding = '';
-	var $outgoing_headers = array();
-	var $incoming_headers = array();
-	var $incoming_cookies = array();
-	var $outgoing_payload = '';
-	var $incoming_payload = '';
-	var $useSOAPAction = true;
-	var $persistentConnection = false;
-	var $ch = false;	// cURL handle
-	var $username = '';
-	var $password = '';
-	var $authtype = '';
-	var $digestRequest = array();
-	var $certRequest = array();	// keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional)
-								// cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
-								// sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
-								// sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem'
-								// passphrase: SSL key password/passphrase
-								// verifypeer: default is 1
-								// verifyhost: default is 1
-
-	/**
-	* constructor
-	*/
-	function soap_transport_http($url){
-		parent::nusoap_base();
-		$this->setURL($url);
-		ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
-		$this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')';
-		$this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']);
-	}
-
-	function setURL($url) {
-		$this->url = $url;
-
-		$u = parse_url($url);
-		foreach($u as $k => $v){
-			$this->debug("$k = $v");
-			$this->$k = $v;
-		}
-		
-		// add any GET params to path
-		if(isset($u['query']) && $u['query'] != ''){
-            $this->path .= '?' . $u['query'];
-		}
-		
-		// set default port
-		if(!isset($u['port'])){
-			if($u['scheme'] == 'https'){
-				$this->port = 443;
-			} else {
-				$this->port = 80;
-			}
-		}
-		
-		$this->uri = $this->path;
-		$this->digest_uri = $this->uri;
-		
-		// build headers
-		if (!isset($u['port'])) {
-			$this->outgoing_headers['Host'] = $this->host;
-		} else {
-			$this->outgoing_headers['Host'] = $this->host.':'.$this->port;
-		}
-		$this->debug('set Host: ' . $this->outgoing_headers['Host']);
-
-		if (isset($u['user']) && $u['user'] != '') {
-			$this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
-		}
-	}
-	
-	function connect($connection_timeout=0,$response_timeout=30){
-	  	// For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like
-	  	// "regular" socket.
-	  	// TODO: disabled for now because OpenSSL must be *compiled* in (not just
-	  	//       loaded), and until PHP5 stream_get_wrappers is not available.
-//	  	if ($this->scheme == 'https') {
-//		  	if (version_compare(phpversion(), '4.3.0') >= 0) {
-//		  		if (extension_loaded('openssl')) {
-//		  			$this->scheme = 'ssl';
-//		  			$this->debug('Using SSL over OpenSSL');
-//		  		}
-//		  	}
-//		}
-		$this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
-	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
-		// use persistent connection
-		if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
-			if (!feof($this->fp)) {
-				$this->debug('Re-use persistent connection');
-				return true;
-			}
-			fclose($this->fp);
-			$this->debug('Closed persistent connection at EOF');
-		}
-
-		// munge host if using OpenSSL
-		if ($this->scheme == 'ssl') {
-			$host = 'ssl://' . $this->host;
-		} else {
-			$host = $this->host;
-		}
-		$this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
-
-		// open socket
-		if($connection_timeout > 0){
-			$this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
-		} else {
-			$this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
-		}
-		
-		// test pointer
-		if(!$this->fp) {
-			$msg = 'Couldn\'t open socket connection to server ' . $this->url;
-			if ($this->errno) {
-				$msg .= ', Error ('.$this->errno.'): '.$this->error_str;
-			} else {
-				$msg .= ' prior to connect().  This is often a problem looking up the host name.';
-			}
-			$this->debug($msg);
-			$this->setError($msg);
-			return false;
-		}
-		
-		// set response timeout
-		$this->debug('set response timeout to ' . $response_timeout);
-		socket_set_timeout( $this->fp, $response_timeout);
-
-		$this->debug('socket connected');
-		return true;
-	  } else if ($this->scheme == 'https') {
-		if (!extension_loaded('curl')) {
-			$this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
-			return false;
-		}
-		$this->debug('connect using https');
-		// init CURL
-		$this->ch = curl_init();
-		// set url
-		$hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host";
-		// add path
-		$hostURL .= $this->path;
-		curl_setopt($this->ch, CURLOPT_URL, $hostURL);
-		// follow location headers (re-directs)
-		curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1);
-		// ask for headers in the response output
-		curl_setopt($this->ch, CURLOPT_HEADER, 1);
-		// ask for the response output as the return value
-		curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
-		// encode
-		// We manage this ourselves through headers and encoding
-//		if(function_exists('gzuncompress')){
-//			curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate');
-//		}
-		// persistent connection
-		if ($this->persistentConnection) {
-			// The way we send data, we cannot use persistent connections, since
-			// there will be some "junk" at the end of our request.
-			//curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true);
-			$this->persistentConnection = false;
-			$this->outgoing_headers['Connection'] = 'close';
-			$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
-		}
-		// set timeout
-		if ($connection_timeout != 0) {
-			curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout);
-		}
-		// TODO: cURL has added a connection timeout separate from the response timeout
-		//if ($connection_timeout != 0) {
-		//	curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
-		//}
-		//if ($response_timeout != 0) {
-		//	curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout);
-		//}
-
-		// recent versions of cURL turn on peer/host checking by default,
-		// while PHP binaries are not compiled with a default location for the
-		// CA cert bundle, so disable peer/host checking.
-//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');		
-		curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
-		curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
-
-		// support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
-		if ($this->authtype == 'certificate') {
-			if (isset($this->certRequest['cainfofile'])) {
-				curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']);
-			}
-			if (isset($this->certRequest['verifypeer'])) {
-				curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
-			} else {
-				curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1);
-			}
-			if (isset($this->certRequest['verifyhost'])) {
-				curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
-			} else {
-				curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1);
-			}
-			if (isset($this->certRequest['sslcertfile'])) {
-				curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
-			}
-			if (isset($this->certRequest['sslkeyfile'])) {
-				curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
-			}
-			if (isset($this->certRequest['passphrase'])) {
-				curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']);
-			}
-		}
-		$this->debug('cURL connection set up');
-		return true;
-	  } else {
-		$this->setError('Unknown scheme ' . $this->scheme);
-		$this->debug('Unknown scheme ' . $this->scheme);
-		return false;
-	  }
-	}
-	
-	/**
-	* send the SOAP message via HTTP
-	*
-	* @param    string $data message data
-	* @param    integer $timeout set connection timeout in seconds
-	* @param	integer $response_timeout set response timeout in seconds
-	* @param	array $cookies cookies to send
-	* @return	string data
-	* @access   public
-	*/
-	function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) {
-		
-		$this->debug('entered send() with data of length: '.strlen($data));
-
-		$this->tryagain = true;
-		$tries = 0;
-		while ($this->tryagain) {
-			$this->tryagain = false;
-			if ($tries++ < 2) {
-				// make connnection
-				if (!$this->connect($timeout, $response_timeout)){
-					return false;
-				}
-				
-				// send request
-				if (!$this->sendRequest($data, $cookies)){
-					return false;
-				}
-				
-				// get response
-				$respdata = $this->getResponse();
-			} else {
-				$this->setError('Too many tries to get an OK response');
-			}
-		}		
-		$this->debug('end of send()');
-		return $respdata;
-	}
-
-
-	/**
-	* send the SOAP message via HTTPS 1.0 using CURL
-	*
-	* @param    string $msg message data
-	* @param    integer $timeout set connection timeout in seconds
-	* @param	integer $response_timeout set response timeout in seconds
-	* @param	array $cookies cookies to send
-	* @return	string data
-	* @access   public
-	*/
-	function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
-		return $this->send($data, $timeout, $response_timeout, $cookies);
-	}
-	
-	/**
-	* if authenticating, set user credentials here
-	*
-	* @param    string $username
-	* @param    string $password
-	* @param	string $authtype (basic, digest, certificate)
-	* @param	array $digestRequest (keys must be nonce, nc, realm, qop)
-	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
-	* @access   public
-	*/
-	function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) {
-		$this->debug("Set credentials for authtype $authtype");
-		// cf. RFC 2617
-		if ($authtype == 'basic') {
-			$this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password);
-		} elseif ($authtype == 'digest') {
-			if (isset($digestRequest['nonce'])) {
-				$digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
-				
-				// calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html)
-	
-				// A1 = unq(username-value) ":" unq(realm-value) ":" passwd
-				$A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
-	
-				// H(A1) = MD5(A1)
-				$HA1 = md5($A1);
-	
-				// A2 = Method ":" digest-uri-value
-				$A2 = 'POST:' . $this->digest_uri;
-	
-				// H(A2)
-				$HA2 =  md5($A2);
-	
-				// KD(secret, data) = H(concat(secret, ":", data))
-				// if qop == auth:
-				// request-digest  = <"> < KD ( H(A1),     unq(nonce-value)
-				//                              ":" nc-value
-				//                              ":" unq(cnonce-value)
-				//                              ":" unq(qop-value)
-				//                              ":" H(A2)
-				//                            ) <">
-				// if qop is missing,
-				// request-digest  = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">
-	
-				$unhashedDigest = '';
-				$nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
-				$cnonce = $nonce;
-				if ($digestRequest['qop'] != '') {
-					$unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
-				} else {
-					$unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
-				}
-	
-				$hashedDigest = md5($unhashedDigest);
-	
-				$this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"';
-			}
-		} elseif ($authtype == 'certificate') {
-			$this->certRequest = $certRequest;
-		}
-		$this->username = $username;
-		$this->password = $password;
-		$this->authtype = $authtype;
-		$this->digestRequest = $digestRequest;
-		
-		if (isset($this->outgoing_headers['Authorization'])) {
-			$this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...');
-		} else {
-			$this->debug('Authorization header not set');
-		}
-	}
-	
-	/**
-	* set the soapaction value
-	*
-	* @param    string $soapaction
-	* @access   public
-	*/
-	function setSOAPAction($soapaction) {
-		$this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"';
-		$this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']);
-	}
-	
-	/**
-	* use http encoding
-	*
-	* @param    string $enc encoding style. supported values: gzip, deflate, or both
-	* @access   public
-	*/
-	function setEncoding($enc='gzip, deflate') {
-		if (function_exists('gzdeflate')) {
-			$this->protocol_version = '1.1';
-			$this->outgoing_headers['Accept-Encoding'] = $enc;
-			$this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']);
-			if (!isset($this->outgoing_headers['Connection'])) {
-				$this->outgoing_headers['Connection'] = 'close';
-				$this->persistentConnection = false;
-				$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
-			}
-			set_magic_quotes_runtime(0);
-			// deprecated
-			$this->encoding = $enc;
-		}
-	}
-	
-	/**
-	* set proxy info here
-	*
-	* @param    string $proxyhost
-	* @param    string $proxyport
-	* @param	string $proxyusername
-	* @param	string $proxypassword
-	* @access   public
-	*/
-	function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
-		$this->uri = $this->url;
-		$this->host = $proxyhost;
-		$this->port = $proxyport;
-		if ($proxyusername != '' && $proxypassword != '') {
-			$this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword);
-			$this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']);
-		}
-	}
-	
-	/**
-	* decode a string that is encoded w/ "chunked' transfer encoding
- 	* as defined in RFC2068 19.4.6
-	*
-	* @param    string $buffer
-	* @param    string $lb
-	* @returns	string
-	* @access   public
-	* @deprecated
-	*/
-	function decodeChunked($buffer, $lb){
-		// length := 0
-		$length = 0;
-		$new = '';
-		
-		// read chunk-size, chunk-extension (if any) and CRLF
-		// get the position of the linebreak
-		$chunkend = strpos($buffer, $lb);
-		if ($chunkend == FALSE) {
-			$this->debug('no linebreak found in decodeChunked');
-			return $new;
-		}
-		$temp = substr($buffer,0,$chunkend);
-		$chunk_size = hexdec( trim($temp) );
-		$chunkstart = $chunkend + strlen($lb);
-		// while (chunk-size > 0) {
-		while ($chunk_size > 0) {
-			$this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
-			$chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
-		  	
-			// Just in case we got a broken connection
-		  	if ($chunkend == FALSE) {
-		  	    $chunk = substr($buffer,$chunkstart);
-				// append chunk-data to entity-body
-		    	$new .= $chunk;
-		  	    $length += strlen($chunk);
-		  	    break;
-			}
-			
-		  	// read chunk-data and CRLF
-		  	$chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
-		  	// append chunk-data to entity-body
-		  	$new .= $chunk;
-		  	// length := length + chunk-size
-		  	$length += strlen($chunk);
-		  	// read chunk-size and CRLF
-		  	$chunkstart = $chunkend + strlen($lb);
-			
-		  	$chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
-			if ($chunkend == FALSE) {
-				break; //Just in case we got a broken connection
-			}
-			$temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
-			$chunk_size = hexdec( trim($temp) );
-			$chunkstart = $chunkend;
-		}
-		return $new;
-	}
-	
-	/*
-	 *	Writes payload, including HTTP headers, to $this->outgoing_payload.
-	 */
-	function buildPayload($data, $cookie_str = '') {
-		// add content-length header
-		$this->outgoing_headers['Content-Length'] = strlen($data);
-		$this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']);
-
-		// start building outgoing payload:
-		$req = "$this->request_method $this->uri HTTP/$this->protocol_version";
-		$this->debug("HTTP request: $req");
-		$this->outgoing_payload = "$req\r\n";
-
-		// loop thru headers, serializing
-		foreach($this->outgoing_headers as $k => $v){
-			$hdr = $k.': '.$v;
-			$this->debug("HTTP header: $hdr");
-			$this->outgoing_payload .= "$hdr\r\n";
-		}
-
-		// add any cookies
-		if ($cookie_str != '') {
-			$hdr = 'Cookie: '.$cookie_str;
-			$this->debug("HTTP header: $hdr");
-			$this->outgoing_payload .= "$hdr\r\n";
-		}
-
-		// header/body separator
-		$this->outgoing_payload .= "\r\n";
-		
-		// add data
-		$this->outgoing_payload .= $data;
-	}
-
-	function sendRequest($data, $cookies = NULL) {
-		// build cookie string
-		$cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
-
-		// build payload
-		$this->buildPayload($data, $cookie_str);
-
-	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
-		// send payload
-		if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
-			$this->setError('couldn\'t write message data to socket');
-			$this->debug('couldn\'t write message data to socket');
-			return false;
-		}
-		$this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
-		return true;
-	  } else if ($this->scheme == 'https') {
-		// set payload
-		// TODO: cURL does say this should only be the verb, and in fact it
-		// turns out that the URI and HTTP version are appended to this, which
-		// some servers refuse to work with
-		//curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
-		foreach($this->outgoing_headers as $k => $v){
-			$curl_headers[] = "$k: $v";
-		}
-		if ($cookie_str != '') {
-			$curl_headers[] = 'Cookie: ' . $cookie_str;
-		}
-		curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers);
-		if ($this->request_method == "POST") {
-	  		curl_setopt($this->ch, CURLOPT_POST, 1);
-	  		curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
-	  	} else {
-	  	}
-		$this->debug('set cURL payload');
-		return true;
-	  }
-	}
-
-	function getResponse(){
-		$this->incoming_payload = '';
-	    
-	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
-	    // loop until headers have been retrieved
-	    $data = '';
-	    while (!isset($lb)){
-
-			// We might EOF during header read.
-			if(feof($this->fp)) {
-				$this->incoming_payload = $data;
-				$this->debug('found no headers before EOF after length ' . strlen($data));
-				$this->debug("received before EOF:\n" . $data);
-				$this->setError('server failed to send headers');
-				return false;
-			}
-
-			$tmp = fgets($this->fp, 256);
-			$tmplen = strlen($tmp);
-			$this->debug("read line of $tmplen bytes: " . trim($tmp));
-
-			if ($tmplen == 0) {
-				$this->incoming_payload = $data;
-				$this->debug('socket read of headers timed out after length ' . strlen($data));
-				$this->debug("read before timeout: " . $data);
-				$this->setError('socket read of headers timed out');
-				return false;
-			}
-
-			$data .= $tmp;
-			$pos = strpos($data,"\r\n\r\n");
-			if($pos > 1){
-				$lb = "\r\n";
-			} else {
-				$pos = strpos($data,"\n\n");
-				if($pos > 1){
-					$lb = "\n";
-				}
-			}
-			// remove 100 header
-			if(isset($lb) && ereg('^HTTP/1.1 100',$data)){
-				unset($lb);
-				$data = '';
-			}//
-		}
-		// store header data
-		$this->incoming_payload .= $data;
-		$this->debug('found end of headers after length ' . strlen($data));
-		// process headers
-		$header_data = trim(substr($data,0,$pos));
-		$header_array = explode($lb,$header_data);
-		$this->incoming_headers = array();
-		$this->incoming_cookies = array();
-		foreach($header_array as $header_line){
-			$arr = explode(':',$header_line, 2);
-			if(count($arr) > 1){
-				$header_name = strtolower(trim($arr[0]));
-				$this->incoming_headers[$header_name] = trim($arr[1]);
-				if ($header_name == 'set-cookie') {
-					// TODO: allow multiple cookies from parseCookie
-					$cookie = $this->parseCookie(trim($arr[1]));
-					if ($cookie) {
-						$this->incoming_cookies[] = $cookie;
-						$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
-					} else {
-						$this->debug('did not find cookie in ' . trim($arr[1]));
-					}
-    			}
-			} else if (isset($header_name)) {
-				// append continuation line to previous header
-				$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
-			}
-		}
-		
-		// loop until msg has been received
-		if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
-			$content_length =  2147483647;	// ignore any content-length header
-			$chunked = true;
-			$this->debug("want to read chunked content");
-		} elseif (isset($this->incoming_headers['content-length'])) {
-			$content_length = $this->incoming_headers['content-length'];
-			$chunked = false;
-			$this->debug("want to read content of length $content_length");
-		} else {
-			$content_length =  2147483647;
-			$chunked = false;
-			$this->debug("want to read content to EOF");
-		}
-		$data = '';
-		do {
-			if ($chunked) {
-				$tmp = fgets($this->fp, 256);
-				$tmplen = strlen($tmp);
-				$this->debug("read chunk line of $tmplen bytes");
-				if ($tmplen == 0) {
-					$this->incoming_payload = $data;
-					$this->debug('socket read of chunk length timed out after length ' . strlen($data));
-					$this->debug("read before timeout:\n" . $data);
-					$this->setError('socket read of chunk length timed out');
-					return false;
-				}
-				$content_length = hexdec(trim($tmp));
-				$this->debug("chunk length $content_length");
-			}
-			$strlen = 0;
-		    while (($strlen < $content_length) && (!feof($this->fp))) {
-		    	$readlen = min(8192, $content_length - $strlen);
-				$tmp = fread($this->fp, $readlen);
-				$tmplen = strlen($tmp);
-				$this->debug("read buffer of $tmplen bytes");
-				if (($tmplen == 0) && (!feof($this->fp))) {
-					$this->incoming_payload = $data;
-					$this->debug('socket read of body timed out after length ' . strlen($data));
-					$this->debug("read before timeout:\n" . $data);
-					$this->setError('socket read of body timed out');
-					return false;
-				}
-				$strlen += $tmplen;
-				$data .= $tmp;
-			}
-			if ($chunked && ($content_length > 0)) {
-				$tmp = fgets($this->fp, 256);
-				$tmplen = strlen($tmp);
-				$this->debug("read chunk terminator of $tmplen bytes");
-				if ($tmplen == 0) {
-					$this->incoming_payload = $data;
-					$this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
-					$this->debug("read before timeout:\n" . $data);
-					$this->setError('socket read of chunk terminator timed out');
-					return false;
-				}
-			}
-		} while ($chunked && ($content_length > 0) && (!feof($this->fp)));
-		if (feof($this->fp)) {
-			$this->debug('read to EOF');
-		}
-		$this->debug('read body of length ' . strlen($data));
-		$this->incoming_payload .= $data;
-		$this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server');
-		
-		// close filepointer
-		if(
-			(isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || 
-			(! $this->persistentConnection) || feof($this->fp)){
-			fclose($this->fp);
-			$this->fp = false;
-			$this->debug('closed socket');
-		}
-		
-		// connection was closed unexpectedly
-		if($this->incoming_payload == ''){
-			$this->setError('no response from server');
-			return false;
-		}
-		
-		// decode transfer-encoding
-//		if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){
-//			if(!$data = $this->decodeChunked($data, $lb)){
-//				$this->setError('Decoding of chunked data failed');
-//				return false;
-//			}
-			//print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>";
-			// set decoded payload
-//			$this->incoming_payload = $header_data.$lb.$lb.$data;
-//		}
-	
-	  } else if ($this->scheme == 'https') {
-		// send and receive
-		$this->debug('send and receive with cURL');
-		$this->incoming_payload = curl_exec($this->ch);
-		$data = $this->incoming_payload;
-
-        $cErr = curl_error($this->ch);
-		if ($cErr != '') {
-        	$err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>';
-        	// TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE
-			foreach(curl_getinfo($this->ch) as $k => $v){
-				$err .= "$k: $v<br>";
-			}
-			$this->debug($err);
-			$this->setError($err);
-			curl_close($this->ch);
-	    	return false;
-		} else {
-			//echo '<pre>';
-			//var_dump(curl_getinfo($this->ch));
-			//echo '</pre>';
-		}
-		// close curl
-		$this->debug('No cURL error, closing cURL');
-		curl_close($this->ch);
-		
-		// remove 100 header(s)
-		while (ereg('^HTTP/1.1 100',$data)) {
-			if ($pos = strpos($data,"\r\n\r\n")) {
-				$data = ltrim(substr($data,$pos));
-			} elseif($pos = strpos($data,"\n\n") ) {
-				$data = ltrim(substr($data,$pos));
-			}
-		}
-		
-		// separate content from HTTP headers
-		if ($pos = strpos($data,"\r\n\r\n")) {
-			$lb = "\r\n";
-		} elseif( $pos = strpos($data,"\n\n")) {
-			$lb = "\n";
-		} else {
-			$this->debug('no proper separation of headers and document');
-			$this->setError('no proper separation of headers and document');
-			return false;
-		}
-		$header_data = trim(substr($data,0,$pos));
-		$header_array = explode($lb,$header_data);
-		$data = ltrim(substr($data,$pos));
-		$this->debug('found proper separation of headers and document');
-		$this->debug('cleaned data, stringlen: '.strlen($data));
-		// clean headers
-		foreach ($header_array as $header_line) {
-			$arr = explode(':',$header_line,2);
-			if(count($arr) > 1){
-				$header_name = strtolower(trim($arr[0]));
-				$this->incoming_headers[$header_name] = trim($arr[1]);
-				if ($header_name == 'set-cookie') {
-					// TODO: allow multiple cookies from parseCookie
-					$cookie = $this->parseCookie(trim($arr[1]));
-					if ($cookie) {
-						$this->incoming_cookies[] = $cookie;
-						$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
-					} else {
-						$this->debug('did not find cookie in ' . trim($arr[1]));
-					}
-    			}
-			} else if (isset($header_name)) {
-				// append continuation line to previous header
-				$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
-			}
-		}
-	  }
-
-		$arr = explode(' ', $header_array[0], 3);
-		$http_version = $arr[0];
-		$http_status = intval($arr[1]);
-		$http_reason = count($arr) > 2 ? $arr[2] : '';
-
- 		// see if we need to resend the request with http digest authentication
- 		if (isset($this->incoming_headers['location']) && $http_status == 301) {
- 			$this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']);
- 			$this->setURL($this->incoming_headers['location']);
-			$this->tryagain = true;
-			return false;
-		}
-
- 		// see if we need to resend the request with http digest authentication
- 		if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
- 			$this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
- 			if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
- 				$this->debug('Server wants digest authentication');
- 				// remove "Digest " from our elements
- 				$digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
- 				
- 				// parse elements into array
- 				$digestElements = explode(',', $digestString);
- 				foreach ($digestElements as $val) {
- 					$tempElement = explode('=', trim($val), 2);
- 					$digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
- 				}
-
-				// should have (at least) qop, realm, nonce
- 				if (isset($digestRequest['nonce'])) {
- 					$this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
- 					$this->tryagain = true;
- 					return false;
- 				}
- 			}
-			$this->debug('HTTP authentication failed');
-			$this->setError('HTTP authentication failed');
-			return false;
- 		}
-		
-		if (
-			($http_status >= 300 && $http_status <= 307) ||
-			($http_status >= 400 && $http_status <= 417) ||
-			($http_status >= 501 && $http_status <= 505)
-		   ) {
-			$this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
-			return false;
-		}
-
-		// decode content-encoding
-		if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){
-			if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){
-    			// if decoding works, use it. else assume data wasn't gzencoded
-    			if(function_exists('gzinflate')){
-					//$timer->setMarker('starting decoding of gzip/deflated content');
-					// IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress)
-					// this means there are no Zlib headers, although there should be
-					$this->debug('The gzinflate function exists');
-					$datalen = strlen($data);
-					if ($this->incoming_headers['content-encoding'] == 'deflate') {
-						if ($degzdata = @gzinflate($data)) {
-	    					$data = $degzdata;
-	    					$this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
-	    					if (strlen($data) < $datalen) {
-	    						// test for the case that the payload has been compressed twice
-		    					$this->debug('The inflated payload is smaller than the gzipped one; try again');
-								if ($degzdata = @gzinflate($data)) {
-			    					$data = $degzdata;
-			    					$this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
-								}
-	    					}
-	    				} else {
-	    					$this->debug('Error using gzinflate to inflate the payload');
-	    					$this->setError('Error using gzinflate to inflate the payload');
-	    				}
-					} elseif ($this->incoming_headers['content-encoding'] == 'gzip') {
-						if ($degzdata = @gzinflate(substr($data, 10))) {	// do our best
-							$data = $degzdata;
-	    					$this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
-	    					if (strlen($data) < $datalen) {
-	    						// test for the case that the payload has been compressed twice
-		    					$this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
-								if ($degzdata = @gzinflate(substr($data, 10))) {
-			    					$data = $degzdata;
-			    					$this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
-								}
-	    					}
-	    				} else {
-	    					$this->debug('Error using gzinflate to un-gzip the payload');
-							$this->setError('Error using gzinflate to un-gzip the payload');
-	    				}
-					}
-					//$timer->setMarker('finished decoding of gzip/deflated content');
-					//print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>";
-					// set decoded payload
-					$this->incoming_payload = $header_data.$lb.$lb.$data;
-    			} else {
-					$this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
-					$this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
-				}
-			} else {
-				$this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
-				$this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
-			}
-		} else {
-			$this->debug('No Content-Encoding header');
-		}
-		
-		if(strlen($data) == 0){
-			$this->debug('no data after headers!');
-			$this->setError('no data present after HTTP headers');
-			return false;
-		}
-		
-		return $data;
-	}
-
-	function setContentType($type, $charset = false) {
-		$this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : '');
-		$this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']);
-	}
-
-	function usePersistentConnection(){
-		if (isset($this->outgoing_headers['Accept-Encoding'])) {
-			return false;
-		}
-		$this->protocol_version = '1.1';
-		$this->persistentConnection = true;
-		$this->outgoing_headers['Connection'] = 'Keep-Alive';
-		$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
-		return true;
-	}
-
-	/**
-	 * parse an incoming Cookie into it's parts
-	 *
-	 * @param	string $cookie_str content of cookie
-	 * @return	array with data of that cookie
-	 * @access	private
-	 */
-	/*
-	 * TODO: allow a Set-Cookie string to be parsed into multiple cookies
-	 */
-	function parseCookie($cookie_str) {
-		$cookie_str = str_replace('; ', ';', $cookie_str) . ';';
-		$data = split(';', $cookie_str);
-		$value_str = $data[0];
-
-		$cookie_param = 'domain=';
-		$start = strpos($cookie_str, $cookie_param);
-		if ($start > 0) {
-			$domain = substr($cookie_str, $start + strlen($cookie_param));
-			$domain = substr($domain, 0, strpos($domain, ';'));
-		} else {
-			$domain = '';
-		}
-
-		$cookie_param = 'expires=';
-		$start = strpos($cookie_str, $cookie_param);
-		if ($start > 0) {
-			$expires = substr($cookie_str, $start + strlen($cookie_param));
-			$expires = substr($expires, 0, strpos($expires, ';'));
-		} else {
-			$expires = '';
-		}
-
-		$cookie_param = 'path=';
-		$start = strpos($cookie_str, $cookie_param);
-		if ( $start > 0 ) {
-			$path = substr($cookie_str, $start + strlen($cookie_param));
-			$path = substr($path, 0, strpos($path, ';'));
-		} else {
-			$path = '/';
-		}
-						
-		$cookie_param = ';secure;';
-		if (strpos($cookie_str, $cookie_param) !== FALSE) {
-			$secure = true;
-		} else {
-			$secure = false;
-		}
-
-		$sep_pos = strpos($value_str, '=');
-
-		if ($sep_pos) {
-			$name = substr($value_str, 0, $sep_pos);
-			$value = substr($value_str, $sep_pos + 1);
-			$cookie= array(	'name' => $name,
-			                'value' => $value,
-							'domain' => $domain,
-							'path' => $path,
-							'expires' => $expires,
-							'secure' => $secure
-							);		
-			return $cookie;
-		}
-		return false;
-	}
-  
-	/**
-	 * sort out cookies for the current request
-	 *
-	 * @param	array $cookies array with all cookies
-	 * @param	boolean $secure is the send-content secure or not?
-	 * @return	string for Cookie-HTTP-Header
-	 * @access	private
-	 */
-	function getCookiesForRequest($cookies, $secure=false) {
-		$cookie_str = '';
-		if ((! is_null($cookies)) && (is_array($cookies))) {
-			foreach ($cookies as $cookie) {
-				if (! is_array($cookie)) {
-					continue;
-				}
-	    		$this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']);
-				if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
-					if (strtotime($cookie['expires']) <= time()) {
-						$this->debug('cookie has expired');
-						continue;
-					}
-				}
-				if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) {
-					$domain = preg_quote($cookie['domain']);
-					if (! preg_match("'.*$domain$'i", $this->host)) {
-						$this->debug('cookie has different domain');
-						continue;
-					}
-				}
-				if ((isset($cookie['path'])) && (! empty($cookie['path']))) {
-					$path = preg_quote($cookie['path']);
-					if (! preg_match("'^$path.*'i", $this->path)) {
-						$this->debug('cookie is for a different path');
-						continue;
-					}
-				}
-				if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
-					$this->debug('cookie is secure, transport is not');
-					continue;
-				}
-				$cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
-	    		$this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
-			}
-		}
-		return $cookie_str;
-  }
-}
-
-
+<?php
+
+
+
+
+/**
+* transport class for sending/receiving data via HTTP and HTTPS
+* NOTE: PHP must be compiled with the CURL extension for HTTPS support
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access public
+*/
+class soap_transport_http extends nusoap_base {
+
+	var $url = '';
+	var $uri = '';
+	var $digest_uri = '';
+	var $scheme = '';
+	var $host = '';
+	var $port = '';
+	var $path = '';
+	var $request_method = 'POST';
+	var $protocol_version = '1.0';
+	var $encoding = '';
+	var $outgoing_headers = array();
+	var $incoming_headers = array();
+	var $incoming_cookies = array();
+	var $outgoing_payload = '';
+	var $incoming_payload = '';
+	var $useSOAPAction = true;
+	var $persistentConnection = false;
+	var $ch = false;	// cURL handle
+	var $username = '';
+	var $password = '';
+	var $authtype = '';
+	var $digestRequest = array();
+	var $certRequest = array();	// keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional)
+								// cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
+								// sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
+								// sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem'
+								// passphrase: SSL key password/passphrase
+								// verifypeer: default is 1
+								// verifyhost: default is 1
+
+	/**
+	* constructor
+	*/
+	function soap_transport_http($url){
+		parent::nusoap_base();
+		$this->setURL($url);
+		ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
+		$this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')';
+		$this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']);
+	}
+
+	function setURL($url) {
+		$this->url = $url;
+
+		$u = parse_url($url);
+		foreach($u as $k => $v){
+			$this->debug("$k = $v");
+			$this->$k = $v;
+		}
+		
+		// add any GET params to path
+		if(isset($u['query']) && $u['query'] != ''){
+            $this->path .= '?' . $u['query'];
+		}
+		
+		// set default port
+		if(!isset($u['port'])){
+			if($u['scheme'] == 'https'){
+				$this->port = 443;
+			} else {
+				$this->port = 80;
+			}
+		}
+		
+		$this->uri = $this->path;
+		$this->digest_uri = $this->uri;
+		
+		// build headers
+		if (!isset($u['port'])) {
+			$this->outgoing_headers['Host'] = $this->host;
+		} else {
+			$this->outgoing_headers['Host'] = $this->host.':'.$this->port;
+		}
+		$this->debug('set Host: ' . $this->outgoing_headers['Host']);
+
+		if (isset($u['user']) && $u['user'] != '') {
+			$this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
+		}
+	}
+	
+	function connect($connection_timeout=0,$response_timeout=30){
+	  	// For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like
+	  	// "regular" socket.
+	  	// TODO: disabled for now because OpenSSL must be *compiled* in (not just
+	  	//       loaded), and until PHP5 stream_get_wrappers is not available.
+//	  	if ($this->scheme == 'https') {
+//		  	if (version_compare(phpversion(), '4.3.0') >= 0) {
+//		  		if (extension_loaded('openssl')) {
+//		  			$this->scheme = 'ssl';
+//		  			$this->debug('Using SSL over OpenSSL');
+//		  		}
+//		  	}
+//		}
+		$this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
+	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+		// use persistent connection
+		if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
+			if (!feof($this->fp)) {
+				$this->debug('Re-use persistent connection');
+				return true;
+			}
+			fclose($this->fp);
+			$this->debug('Closed persistent connection at EOF');
+		}
+
+		// munge host if using OpenSSL
+		if ($this->scheme == 'ssl') {
+			$host = 'ssl://' . $this->host;
+		} else {
+			$host = $this->host;
+		}
+		$this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
+
+		// open socket
+		if($connection_timeout > 0){
+			$this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
+		} else {
+			$this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
+		}
+		
+		// test pointer
+		if(!$this->fp) {
+			$msg = 'Couldn\'t open socket connection to server ' . $this->url;
+			if ($this->errno) {
+				$msg .= ', Error ('.$this->errno.'): '.$this->error_str;
+			} else {
+				$msg .= ' prior to connect().  This is often a problem looking up the host name.';
+			}
+			$this->debug($msg);
+			$this->setError($msg);
+			return false;
+		}
+		
+		// set response timeout
+		$this->debug('set response timeout to ' . $response_timeout);
+		socket_set_timeout( $this->fp, $response_timeout);
+
+		$this->debug('socket connected');
+		return true;
+	  } else if ($this->scheme == 'https') {
+		if (!extension_loaded('curl')) {
+			$this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
+			return false;
+		}
+		$this->debug('connect using https');
+		// init CURL
+		$this->ch = curl_init();
+		// set url
+		$hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host";
+		// add path
+		$hostURL .= $this->path;
+		curl_setopt($this->ch, CURLOPT_URL, $hostURL);
+		// follow location headers (re-directs)
+		curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1);
+		// ask for headers in the response output
+		curl_setopt($this->ch, CURLOPT_HEADER, 1);
+		// ask for the response output as the return value
+		curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
+		// encode
+		// We manage this ourselves through headers and encoding
+//		if(function_exists('gzuncompress')){
+//			curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate');
+//		}
+		// persistent connection
+		if ($this->persistentConnection) {
+			// The way we send data, we cannot use persistent connections, since
+			// there will be some "junk" at the end of our request.
+			//curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true);
+			$this->persistentConnection = false;
+			$this->outgoing_headers['Connection'] = 'close';
+			$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
+		}
+		// set timeout
+		if ($connection_timeout != 0) {
+			curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout);
+		}
+		// TODO: cURL has added a connection timeout separate from the response timeout
+		//if ($connection_timeout != 0) {
+		//	curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
+		//}
+		//if ($response_timeout != 0) {
+		//	curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout);
+		//}
+
+		// recent versions of cURL turn on peer/host checking by default,
+		// while PHP binaries are not compiled with a default location for the
+		// CA cert bundle, so disable peer/host checking.
+//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');		
+		curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
+		curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
+
+		// support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
+		if ($this->authtype == 'certificate') {
+			if (isset($this->certRequest['cainfofile'])) {
+				curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']);
+			}
+			if (isset($this->certRequest['verifypeer'])) {
+				curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
+			} else {
+				curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1);
+			}
+			if (isset($this->certRequest['verifyhost'])) {
+				curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
+			} else {
+				curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1);
+			}
+			if (isset($this->certRequest['sslcertfile'])) {
+				curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
+			}
+			if (isset($this->certRequest['sslkeyfile'])) {
+				curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
+			}
+			if (isset($this->certRequest['passphrase'])) {
+				curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']);
+			}
+		}
+		$this->debug('cURL connection set up');
+		return true;
+	  } else {
+		$this->setError('Unknown scheme ' . $this->scheme);
+		$this->debug('Unknown scheme ' . $this->scheme);
+		return false;
+	  }
+	}
+	
+	/**
+	* send the SOAP message via HTTP
+	*
+	* @param    string $data message data
+	* @param    integer $timeout set connection timeout in seconds
+	* @param	integer $response_timeout set response timeout in seconds
+	* @param	array $cookies cookies to send
+	* @return	string data
+	* @access   public
+	*/
+	function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) {
+		
+		$this->debug('entered send() with data of length: '.strlen($data));
+
+		$this->tryagain = true;
+		$tries = 0;
+		while ($this->tryagain) {
+			$this->tryagain = false;
+			if ($tries++ < 2) {
+				// make connnection
+				if (!$this->connect($timeout, $response_timeout)){
+					return false;
+				}
+				
+				// send request
+				if (!$this->sendRequest($data, $cookies)){
+					return false;
+				}
+				
+				// get response
+				$respdata = $this->getResponse();
+			} else {
+				$this->setError('Too many tries to get an OK response');
+			}
+		}		
+		$this->debug('end of send()');
+		return $respdata;
+	}
+
+
+	/**
+	* send the SOAP message via HTTPS 1.0 using CURL
+	*
+	* @param    string $msg message data
+	* @param    integer $timeout set connection timeout in seconds
+	* @param	integer $response_timeout set response timeout in seconds
+	* @param	array $cookies cookies to send
+	* @return	string data
+	* @access   public
+	*/
+	function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
+		return $this->send($data, $timeout, $response_timeout, $cookies);
+	}
+	
+	/**
+	* if authenticating, set user credentials here
+	*
+	* @param    string $username
+	* @param    string $password
+	* @param	string $authtype (basic, digest, certificate)
+	* @param	array $digestRequest (keys must be nonce, nc, realm, qop)
+	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
+	* @access   public
+	*/
+	function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) {
+		$this->debug("Set credentials for authtype $authtype");
+		// cf. RFC 2617
+		if ($authtype == 'basic') {
+			$this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password);
+		} elseif ($authtype == 'digest') {
+			if (isset($digestRequest['nonce'])) {
+				$digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
+				
+				// calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html)
+	
+				// A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+				$A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
+	
+				// H(A1) = MD5(A1)
+				$HA1 = md5($A1);
+	
+				// A2 = Method ":" digest-uri-value
+				$A2 = 'POST:' . $this->digest_uri;
+	
+				// H(A2)
+				$HA2 =  md5($A2);
+	
+				// KD(secret, data) = H(concat(secret, ":", data))
+				// if qop == auth:
+				// request-digest  = <"> < KD ( H(A1),     unq(nonce-value)
+				//                              ":" nc-value
+				//                              ":" unq(cnonce-value)
+				//                              ":" unq(qop-value)
+				//                              ":" H(A2)
+				//                            ) <">
+				// if qop is missing,
+				// request-digest  = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">
+	
+				$unhashedDigest = '';
+				$nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
+				$cnonce = $nonce;
+				if ($digestRequest['qop'] != '') {
+					$unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
+				} else {
+					$unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
+				}
+	
+				$hashedDigest = md5($unhashedDigest);
+	
+				$this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"';
+			}
+		} elseif ($authtype == 'certificate') {
+			$this->certRequest = $certRequest;
+		}
+		$this->username = $username;
+		$this->password = $password;
+		$this->authtype = $authtype;
+		$this->digestRequest = $digestRequest;
+		
+		if (isset($this->outgoing_headers['Authorization'])) {
+			$this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...');
+		} else {
+			$this->debug('Authorization header not set');
+		}
+	}
+	
+	/**
+	* set the soapaction value
+	*
+	* @param    string $soapaction
+	* @access   public
+	*/
+	function setSOAPAction($soapaction) {
+		$this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"';
+		$this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']);
+	}
+	
+	/**
+	* use http encoding
+	*
+	* @param    string $enc encoding style. supported values: gzip, deflate, or both
+	* @access   public
+	*/
+	function setEncoding($enc='gzip, deflate') {
+		if (function_exists('gzdeflate')) {
+			$this->protocol_version = '1.1';
+			$this->outgoing_headers['Accept-Encoding'] = $enc;
+			$this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']);
+			if (!isset($this->outgoing_headers['Connection'])) {
+				$this->outgoing_headers['Connection'] = 'close';
+				$this->persistentConnection = false;
+				$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
+			}
+			set_magic_quotes_runtime(0);
+			// deprecated
+			$this->encoding = $enc;
+		}
+	}
+	
+	/**
+	* set proxy info here
+	*
+	* @param    string $proxyhost
+	* @param    string $proxyport
+	* @param	string $proxyusername
+	* @param	string $proxypassword
+	* @access   public
+	*/
+	function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
+		$this->uri = $this->url;
+		$this->host = $proxyhost;
+		$this->port = $proxyport;
+		if ($proxyusername != '' && $proxypassword != '') {
+			$this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword);
+			$this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']);
+		}
+	}
+	
+	/**
+	* decode a string that is encoded w/ "chunked' transfer encoding
+ 	* as defined in RFC2068 19.4.6
+	*
+	* @param    string $buffer
+	* @param    string $lb
+	* @returns	string
+	* @access   public
+	* @deprecated
+	*/
+	function decodeChunked($buffer, $lb){
+		// length := 0
+		$length = 0;
+		$new = '';
+		
+		// read chunk-size, chunk-extension (if any) and CRLF
+		// get the position of the linebreak
+		$chunkend = strpos($buffer, $lb);
+		if ($chunkend == FALSE) {
+			$this->debug('no linebreak found in decodeChunked');
+			return $new;
+		}
+		$temp = substr($buffer,0,$chunkend);
+		$chunk_size = hexdec( trim($temp) );
+		$chunkstart = $chunkend + strlen($lb);
+		// while (chunk-size > 0) {
+		while ($chunk_size > 0) {
+			$this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
+			$chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
+		  	
+			// Just in case we got a broken connection
+		  	if ($chunkend == FALSE) {
+		  	    $chunk = substr($buffer,$chunkstart);
+				// append chunk-data to entity-body
+		    	$new .= $chunk;
+		  	    $length += strlen($chunk);
+		  	    break;
+			}
+			
+		  	// read chunk-data and CRLF
+		  	$chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
+		  	// append chunk-data to entity-body
+		  	$new .= $chunk;
+		  	// length := length + chunk-size
+		  	$length += strlen($chunk);
+		  	// read chunk-size and CRLF
+		  	$chunkstart = $chunkend + strlen($lb);
+			
+		  	$chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
+			if ($chunkend == FALSE) {
+				break; //Just in case we got a broken connection
+			}
+			$temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
+			$chunk_size = hexdec( trim($temp) );
+			$chunkstart = $chunkend;
+		}
+		return $new;
+	}
+	
+	/*
+	 *	Writes payload, including HTTP headers, to $this->outgoing_payload.
+	 */
+	function buildPayload($data, $cookie_str = '') {
+		// add content-length header
+		$this->outgoing_headers['Content-Length'] = strlen($data);
+		$this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']);
+
+		// start building outgoing payload:
+		$req = "$this->request_method $this->uri HTTP/$this->protocol_version";
+		$this->debug("HTTP request: $req");
+		$this->outgoing_payload = "$req\r\n";
+
+		// loop thru headers, serializing
+		foreach($this->outgoing_headers as $k => $v){
+			$hdr = $k.': '.$v;
+			$this->debug("HTTP header: $hdr");
+			$this->outgoing_payload .= "$hdr\r\n";
+		}
+
+		// add any cookies
+		if ($cookie_str != '') {
+			$hdr = 'Cookie: '.$cookie_str;
+			$this->debug("HTTP header: $hdr");
+			$this->outgoing_payload .= "$hdr\r\n";
+		}
+
+		// header/body separator
+		$this->outgoing_payload .= "\r\n";
+		
+		// add data
+		$this->outgoing_payload .= $data;
+	}
+
+	function sendRequest($data, $cookies = NULL) {
+		// build cookie string
+		$cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
+
+		// build payload
+		$this->buildPayload($data, $cookie_str);
+
+	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+		// send payload
+		if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
+			$this->setError('couldn\'t write message data to socket');
+			$this->debug('couldn\'t write message data to socket');
+			return false;
+		}
+		$this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
+		return true;
+	  } else if ($this->scheme == 'https') {
+		// set payload
+		// TODO: cURL does say this should only be the verb, and in fact it
+		// turns out that the URI and HTTP version are appended to this, which
+		// some servers refuse to work with
+		//curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
+		foreach($this->outgoing_headers as $k => $v){
+			$curl_headers[] = "$k: $v";
+		}
+		if ($cookie_str != '') {
+			$curl_headers[] = 'Cookie: ' . $cookie_str;
+		}
+		curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers);
+		if ($this->request_method == "POST") {
+	  		curl_setopt($this->ch, CURLOPT_POST, 1);
+	  		curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
+	  	} else {
+	  	}
+		$this->debug('set cURL payload');
+		return true;
+	  }
+	}
+
+	function getResponse(){
+		$this->incoming_payload = '';
+	    
+	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+	    // loop until headers have been retrieved
+	    $data = '';
+	    while (!isset($lb)){
+
+			// We might EOF during header read.
+			if(feof($this->fp)) {
+				$this->incoming_payload = $data;
+				$this->debug('found no headers before EOF after length ' . strlen($data));
+				$this->debug("received before EOF:\n" . $data);
+				$this->setError('server failed to send headers');
+				return false;
+			}
+
+			$tmp = fgets($this->fp, 256);
+			$tmplen = strlen($tmp);
+			$this->debug("read line of $tmplen bytes: " . trim($tmp));
+
+			if ($tmplen == 0) {
+				$this->incoming_payload = $data;
+				$this->debug('socket read of headers timed out after length ' . strlen($data));
+				$this->debug("read before timeout: " . $data);
+				$this->setError('socket read of headers timed out');
+				return false;
+			}
+
+			$data .= $tmp;
+			$pos = strpos($data,"\r\n\r\n");
+			if($pos > 1){
+				$lb = "\r\n";
+			} else {
+				$pos = strpos($data,"\n\n");
+				if($pos > 1){
+					$lb = "\n";
+				}
+			}
+			// remove 100 header
+			if(isset($lb) && ereg('^HTTP/1.1 100',$data)){
+				unset($lb);
+				$data = '';
+			}//
+		}
+		// store header data
+		$this->incoming_payload .= $data;
+		$this->debug('found end of headers after length ' . strlen($data));
+		// process headers
+		$header_data = trim(substr($data,0,$pos));
+		$header_array = explode($lb,$header_data);
+		$this->incoming_headers = array();
+		$this->incoming_cookies = array();
+		foreach($header_array as $header_line){
+			$arr = explode(':',$header_line, 2);
+			if(count($arr) > 1){
+				$header_name = strtolower(trim($arr[0]));
+				$this->incoming_headers[$header_name] = trim($arr[1]);
+				if ($header_name == 'set-cookie') {
+					// TODO: allow multiple cookies from parseCookie
+					$cookie = $this->parseCookie(trim($arr[1]));
+					if ($cookie) {
+						$this->incoming_cookies[] = $cookie;
+						$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
+					} else {
+						$this->debug('did not find cookie in ' . trim($arr[1]));
+					}
+    			}
+			} else if (isset($header_name)) {
+				// append continuation line to previous header
+				$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
+			}
+		}
+		
+		// loop until msg has been received
+		if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
+			$content_length =  2147483647;	// ignore any content-length header
+			$chunked = true;
+			$this->debug("want to read chunked content");
+		} elseif (isset($this->incoming_headers['content-length'])) {
+			$content_length = $this->incoming_headers['content-length'];
+			$chunked = false;
+			$this->debug("want to read content of length $content_length");
+		} else {
+			$content_length =  2147483647;
+			$chunked = false;
+			$this->debug("want to read content to EOF");
+		}
+		$data = '';
+		do {
+			if ($chunked) {
+				$tmp = fgets($this->fp, 256);
+				$tmplen = strlen($tmp);
+				$this->debug("read chunk line of $tmplen bytes");
+				if ($tmplen == 0) {
+					$this->incoming_payload = $data;
+					$this->debug('socket read of chunk length timed out after length ' . strlen($data));
+					$this->debug("read before timeout:\n" . $data);
+					$this->setError('socket read of chunk length timed out');
+					return false;
+				}
+				$content_length = hexdec(trim($tmp));
+				$this->debug("chunk length $content_length");
+			}
+			$strlen = 0;
+		    while (($strlen < $content_length) && (!feof($this->fp))) {
+		    	$readlen = min(8192, $content_length - $strlen);
+				$tmp = fread($this->fp, $readlen);
+				$tmplen = strlen($tmp);
+				$this->debug("read buffer of $tmplen bytes");
+				if (($tmplen == 0) && (!feof($this->fp))) {
+					$this->incoming_payload = $data;
+					$this->debug('socket read of body timed out after length ' . strlen($data));
+					$this->debug("read before timeout:\n" . $data);
+					$this->setError('socket read of body timed out');
+					return false;
+				}
+				$strlen += $tmplen;
+				$data .= $tmp;
+			}
+			if ($chunked && ($content_length > 0)) {
+				$tmp = fgets($this->fp, 256);
+				$tmplen = strlen($tmp);
+				$this->debug("read chunk terminator of $tmplen bytes");
+				if ($tmplen == 0) {
+					$this->incoming_payload = $data;
+					$this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
+					$this->debug("read before timeout:\n" . $data);
+					$this->setError('socket read of chunk terminator timed out');
+					return false;
+				}
+			}
+		} while ($chunked && ($content_length > 0) && (!feof($this->fp)));
+		if (feof($this->fp)) {
+			$this->debug('read to EOF');
+		}
+		$this->debug('read body of length ' . strlen($data));
+		$this->incoming_payload .= $data;
+		$this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server');
+		
+		// close filepointer
+		if(
+			(isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || 
+			(! $this->persistentConnection) || feof($this->fp)){
+			fclose($this->fp);
+			$this->fp = false;
+			$this->debug('closed socket');
+		}
+		
+		// connection was closed unexpectedly
+		if($this->incoming_payload == ''){
+			$this->setError('no response from server');
+			return false;
+		}
+		
+		// decode transfer-encoding
+//		if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){
+//			if(!$data = $this->decodeChunked($data, $lb)){
+//				$this->setError('Decoding of chunked data failed');
+//				return false;
+//			}
+			//print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>";
+			// set decoded payload
+//			$this->incoming_payload = $header_data.$lb.$lb.$data;
+//		}
+	
+	  } else if ($this->scheme == 'https') {
+		// send and receive
+		$this->debug('send and receive with cURL');
+		$this->incoming_payload = curl_exec($this->ch);
+		$data = $this->incoming_payload;
+
+        $cErr = curl_error($this->ch);
+		if ($cErr != '') {
+        	$err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>';
+        	// TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE
+			foreach(curl_getinfo($this->ch) as $k => $v){
+				$err .= "$k: $v<br>";
+			}
+			$this->debug($err);
+			$this->setError($err);
+			curl_close($this->ch);
+	    	return false;
+		} else {
+			//echo '<pre>';
+			//var_dump(curl_getinfo($this->ch));
+			//echo '</pre>';
+		}
+		// close curl
+		$this->debug('No cURL error, closing cURL');
+		curl_close($this->ch);
+		
+		// remove 100 header(s)
+		while (ereg('^HTTP/1.1 100',$data)) {
+			if ($pos = strpos($data,"\r\n\r\n")) {
+				$data = ltrim(substr($data,$pos));
+			} elseif($pos = strpos($data,"\n\n") ) {
+				$data = ltrim(substr($data,$pos));
+			}
+		}
+		
+		// separate content from HTTP headers
+		if ($pos = strpos($data,"\r\n\r\n")) {
+			$lb = "\r\n";
+		} elseif( $pos = strpos($data,"\n\n")) {
+			$lb = "\n";
+		} else {
+			$this->debug('no proper separation of headers and document');
+			$this->setError('no proper separation of headers and document');
+			return false;
+		}
+		$header_data = trim(substr($data,0,$pos));
+		$header_array = explode($lb,$header_data);
+		$data = ltrim(substr($data,$pos));
+		$this->debug('found proper separation of headers and document');
+		$this->debug('cleaned data, stringlen: '.strlen($data));
+		// clean headers
+		foreach ($header_array as $header_line) {
+			$arr = explode(':',$header_line,2);
+			if(count($arr) > 1){
+				$header_name = strtolower(trim($arr[0]));
+				$this->incoming_headers[$header_name] = trim($arr[1]);
+				if ($header_name == 'set-cookie') {
+					// TODO: allow multiple cookies from parseCookie
+					$cookie = $this->parseCookie(trim($arr[1]));
+					if ($cookie) {
+						$this->incoming_cookies[] = $cookie;
+						$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
+					} else {
+						$this->debug('did not find cookie in ' . trim($arr[1]));
+					}
+    			}
+			} else if (isset($header_name)) {
+				// append continuation line to previous header
+				$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
+			}
+		}
+	  }
+
+		$arr = explode(' ', $header_array[0], 3);
+		$http_version = $arr[0];
+		$http_status = intval($arr[1]);
+		$http_reason = count($arr) > 2 ? $arr[2] : '';
+
+ 		// see if we need to resend the request with http digest authentication
+ 		if (isset($this->incoming_headers['location']) && $http_status == 301) {
+ 			$this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']);
+ 			$this->setURL($this->incoming_headers['location']);
+			$this->tryagain = true;
+			return false;
+		}
+
+ 		// see if we need to resend the request with http digest authentication
+ 		if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
+ 			$this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
+ 			if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
+ 				$this->debug('Server wants digest authentication');
+ 				// remove "Digest " from our elements
+ 				$digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
+ 				
+ 				// parse elements into array
+ 				$digestElements = explode(',', $digestString);
+ 				foreach ($digestElements as $val) {
+ 					$tempElement = explode('=', trim($val), 2);
+ 					$digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
+ 				}
+
+				// should have (at least) qop, realm, nonce
+ 				if (isset($digestRequest['nonce'])) {
+ 					$this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
+ 					$this->tryagain = true;
+ 					return false;
+ 				}
+ 			}
+			$this->debug('HTTP authentication failed');
+			$this->setError('HTTP authentication failed');
+			return false;
+ 		}
+		
+		if (
+			($http_status >= 300 && $http_status <= 307) ||
+			($http_status >= 400 && $http_status <= 417) ||
+			($http_status >= 501 && $http_status <= 505)
+		   ) {
+			$this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
+			return false;
+		}
+
+		// decode content-encoding
+		if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){
+			if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){
+    			// if decoding works, use it. else assume data wasn't gzencoded
+    			if(function_exists('gzinflate')){
+					//$timer->setMarker('starting decoding of gzip/deflated content');
+					// IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress)
+					// this means there are no Zlib headers, although there should be
+					$this->debug('The gzinflate function exists');
+					$datalen = strlen($data);
+					if ($this->incoming_headers['content-encoding'] == 'deflate') {
+						if ($degzdata = @gzinflate($data)) {
+	    					$data = $degzdata;
+	    					$this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
+	    					if (strlen($data) < $datalen) {
+	    						// test for the case that the payload has been compressed twice
+		    					$this->debug('The inflated payload is smaller than the gzipped one; try again');
+								if ($degzdata = @gzinflate($data)) {
+			    					$data = $degzdata;
+			    					$this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
+								}
+	    					}
+	    				} else {
+	    					$this->debug('Error using gzinflate to inflate the payload');
+	    					$this->setError('Error using gzinflate to inflate the payload');
+	    				}
+					} elseif ($this->incoming_headers['content-encoding'] == 'gzip') {
+						if ($degzdata = @gzinflate(substr($data, 10))) {	// do our best
+							$data = $degzdata;
+	    					$this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
+	    					if (strlen($data) < $datalen) {
+	    						// test for the case that the payload has been compressed twice
+		    					$this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
+								if ($degzdata = @gzinflate(substr($data, 10))) {
+			    					$data = $degzdata;
+			    					$this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
+								}
+	    					}
+	    				} else {
+	    					$this->debug('Error using gzinflate to un-gzip the payload');
+							$this->setError('Error using gzinflate to un-gzip the payload');
+	    				}
+					}
+					//$timer->setMarker('finished decoding of gzip/deflated content');
+					//print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>";
+					// set decoded payload
+					$this->incoming_payload = $header_data.$lb.$lb.$data;
+    			} else {
+					$this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
+					$this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
+				}
+			} else {
+				$this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
+				$this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
+			}
+		} else {
+			$this->debug('No Content-Encoding header');
+		}
+		
+		if(strlen($data) == 0){
+			$this->debug('no data after headers!');
+			$this->setError('no data present after HTTP headers');
+			return false;
+		}
+		
+		return $data;
+	}
+
+	function setContentType($type, $charset = false) {
+		$this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : '');
+		$this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']);
+	}
+
+	function usePersistentConnection(){
+		if (isset($this->outgoing_headers['Accept-Encoding'])) {
+			return false;
+		}
+		$this->protocol_version = '1.1';
+		$this->persistentConnection = true;
+		$this->outgoing_headers['Connection'] = 'Keep-Alive';
+		$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
+		return true;
+	}
+
+	/**
+	 * parse an incoming Cookie into it's parts
+	 *
+	 * @param	string $cookie_str content of cookie
+	 * @return	array with data of that cookie
+	 * @access	private
+	 */
+	/*
+	 * TODO: allow a Set-Cookie string to be parsed into multiple cookies
+	 */
+	function parseCookie($cookie_str) {
+		$cookie_str = str_replace('; ', ';', $cookie_str) . ';';
+		$data = split(';', $cookie_str);
+		$value_str = $data[0];
+
+		$cookie_param = 'domain=';
+		$start = strpos($cookie_str, $cookie_param);
+		if ($start > 0) {
+			$domain = substr($cookie_str, $start + strlen($cookie_param));
+			$domain = substr($domain, 0, strpos($domain, ';'));
+		} else {
+			$domain = '';
+		}
+
+		$cookie_param = 'expires=';
+		$start = strpos($cookie_str, $cookie_param);
+		if ($start > 0) {
+			$expires = substr($cookie_str, $start + strlen($cookie_param));
+			$expires = substr($expires, 0, strpos($expires, ';'));
+		} else {
+			$expires = '';
+		}
+
+		$cookie_param = 'path=';
+		$start = strpos($cookie_str, $cookie_param);
+		if ( $start > 0 ) {
+			$path = substr($cookie_str, $start + strlen($cookie_param));
+			$path = substr($path, 0, strpos($path, ';'));
+		} else {
+			$path = '/';
+		}
+						
+		$cookie_param = ';secure;';
+		if (strpos($cookie_str, $cookie_param) !== FALSE) {
+			$secure = true;
+		} else {
+			$secure = false;
+		}
+
+		$sep_pos = strpos($value_str, '=');
+
+		if ($sep_pos) {
+			$name = substr($value_str, 0, $sep_pos);
+			$value = substr($value_str, $sep_pos + 1);
+			$cookie= array(	'name' => $name,
+			                'value' => $value,
+							'domain' => $domain,
+							'path' => $path,
+							'expires' => $expires,
+							'secure' => $secure
+							);		
+			return $cookie;
+		}
+		return false;
+	}
+  
+	/**
+	 * sort out cookies for the current request
+	 *
+	 * @param	array $cookies array with all cookies
+	 * @param	boolean $secure is the send-content secure or not?
+	 * @return	string for Cookie-HTTP-Header
+	 * @access	private
+	 */
+	function getCookiesForRequest($cookies, $secure=false) {
+		$cookie_str = '';
+		if ((! is_null($cookies)) && (is_array($cookies))) {
+			foreach ($cookies as $cookie) {
+				if (! is_array($cookie)) {
+					continue;
+				}
+	    		$this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']);
+				if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
+					if (strtotime($cookie['expires']) <= time()) {
+						$this->debug('cookie has expired');
+						continue;
+					}
+				}
+				if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) {
+					$domain = preg_quote($cookie['domain']);
+					if (! preg_match("'.*$domain$'i", $this->host)) {
+						$this->debug('cookie has different domain');
+						continue;
+					}
+				}
+				if ((isset($cookie['path'])) && (! empty($cookie['path']))) {
+					$path = preg_quote($cookie['path']);
+					if (! preg_match("'^$path.*'i", $this->path)) {
+						$this->debug('cookie is for a different path');
+						continue;
+					}
+				}
+				if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
+					$this->debug('cookie is secure, transport is not');
+					continue;
+				}
+				$cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
+	    		$this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
+			}
+		}
+		return $cookie_str;
+  }
+}
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.soap_val.php b/htdocs/oscommerce_ws/ws_server/lib/class.soap_val.php
index dd5bc1797a0afa7c8df1f4084b60179b081713e8..0b43e0b78c6e237629bcad3ce81d707d9b2fed37 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.soap_val.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.soap_val.php
@@ -1,107 +1,107 @@
-<?php
-
-
-
-
-/**
-* For creating serializable abstractions of native PHP types.  This class
-* allows element name/namespace, XSD type, and XML attributes to be
-* associated with a value.  This is extremely useful when WSDL is not
-* used, but is also useful when WSDL is used with polymorphic types, including
-* xsd:anyType and user-defined types.
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class soapval extends nusoap_base {
-	/**
-	 * The XML element name
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $name;
-	/**
-	 * The XML type name (string or false)
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $type;
-	/**
-	 * The PHP value
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $value;
-	/**
-	 * The XML element namespace (string or false)
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $element_ns;
-	/**
-	 * The XML type namespace (string or false)
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $type_ns;
-	/**
-	 * The XML element attributes (array or false)
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $attributes;
-
-	/**
-	* constructor
-	*
-	* @param    string $name optional name
-	* @param    mixed $type optional type name
-	* @param	mixed $value optional value
-	* @param	mixed $element_ns optional namespace of value
-	* @param	mixed $type_ns optional namespace of type
-	* @param	mixed $attributes associative array of attributes to add to element serialization
-	* @access   public
-	*/
-  	function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
-		parent::nusoap_base();
-		$this->name = $name;
-		$this->type = $type;
-		$this->value = $value;
-		$this->element_ns = $element_ns;
-		$this->type_ns = $type_ns;
-		$this->attributes = $attributes;
-    }
-
-	/**
-	* return serialized value
-	*
-	* @param	string $use The WSDL use value (encoded|literal)
-	* @return	string XML data
-	* @access   public
-	*/
-	function serialize($use='encoded') {
-		return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use);
-    }
-
-	/**
-	* decodes a soapval object into a PHP native type
-	*
-	* @return	mixed
-	* @access   public
-	*/
-	function decode(){
-		return $this->value;
-	}
-}
-
-
-
-
+<?php
+
+
+
+
+/**
+* For creating serializable abstractions of native PHP types.  This class
+* allows element name/namespace, XSD type, and XML attributes to be
+* associated with a value.  This is extremely useful when WSDL is not
+* used, but is also useful when WSDL is used with polymorphic types, including
+* xsd:anyType and user-defined types.
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class soapval extends nusoap_base {
+	/**
+	 * The XML element name
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $name;
+	/**
+	 * The XML type name (string or false)
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $type;
+	/**
+	 * The PHP value
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $value;
+	/**
+	 * The XML element namespace (string or false)
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $element_ns;
+	/**
+	 * The XML type namespace (string or false)
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $type_ns;
+	/**
+	 * The XML element attributes (array or false)
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $attributes;
+
+	/**
+	* constructor
+	*
+	* @param    string $name optional name
+	* @param    mixed $type optional type name
+	* @param	mixed $value optional value
+	* @param	mixed $element_ns optional namespace of value
+	* @param	mixed $type_ns optional namespace of type
+	* @param	mixed $attributes associative array of attributes to add to element serialization
+	* @access   public
+	*/
+  	function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
+		parent::nusoap_base();
+		$this->name = $name;
+		$this->type = $type;
+		$this->value = $value;
+		$this->element_ns = $element_ns;
+		$this->type_ns = $type_ns;
+		$this->attributes = $attributes;
+    }
+
+	/**
+	* return serialized value
+	*
+	* @param	string $use The WSDL use value (encoded|literal)
+	* @return	string XML data
+	* @access   public
+	*/
+	function serialize($use='encoded') {
+		return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use);
+    }
+
+	/**
+	* decodes a soapval object into a PHP native type
+	*
+	* @return	mixed
+	* @access   public
+	*/
+	function decode(){
+		return $this->value;
+	}
+}
+
+
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.soapclient.php b/htdocs/oscommerce_ws/ws_server/lib/class.soapclient.php
index c21f04b5636b55e7bd677e69234829f9fda14da8..a99b17282e65c9ad4f1ef6a7d4a4f64bf82cfc51 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.soapclient.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.soapclient.php
@@ -1,859 +1,859 @@
-<?php
-
-
-
-
-/**
-*
-* soapclient higher level class for easy usage.
-*
-* usage:
-*
-* // instantiate client with server info
-* $soapclient = new soapclient_nusoap( string path [ ,boolean wsdl] );
-*
-* // call method, get results
-* echo $soapclient->call( string methodname [ ,array parameters] );
-*
-* // bye bye client
-* unset($soapclient);
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class soapclient_nusoap extends nusoap_base  {
-
-	var $username = '';
-	var $password = '';
-	var $authtype = '';
-	var $certRequest = array();
-	var $requestHeaders = false;	// SOAP headers in request (text)
-	var $responseHeaders = '';		// SOAP headers from response (incomplete namespace resolution) (text)
-	var $document = '';				// SOAP body response portion (incomplete namespace resolution) (text)
-	var $endpoint;
-	var $forceEndpoint = '';		// overrides WSDL endpoint
-    var $proxyhost = '';
-    var $proxyport = '';
-	var $proxyusername = '';
-	var $proxypassword = '';
-    var $xml_encoding = '';			// character set encoding of incoming (response) messages
-	var $http_encoding = false;
-	var $timeout = 0;				// HTTP connection timeout
-	var $response_timeout = 30;		// HTTP response timeout
-	var $endpointType = '';			// soap|wsdl, empty for WSDL initialization error
-	var $persistentConnection = false;
-	var $defaultRpcParams = false;	// This is no longer used
-	var $request = '';				// HTTP request
-	var $response = '';				// HTTP response
-	var $responseData = '';			// SOAP payload of response
-	var $cookies = array();			// Cookies from response or for request
-    var $decode_utf8 = true;		// toggles whether the parser decodes element content w/ utf8_decode()
-	var $operations = array();		// WSDL operations, empty for WSDL initialization error
-	
-	/*
-	 * fault related variables
-	 */
-	/**
-	 * @var      fault
-	 * @access   public
-	 */
-	var $fault;
-	/**
-	 * @var      faultcode
-	 * @access   public
-	 */
-	var $faultcode;
-	/**
-	 * @var      faultstring
-	 * @access   public
-	 */
-	var $faultstring;
-	/**
-	 * @var      faultdetail
-	 * @access   public
-	 */
-	var $faultdetail;
-
-	/**
-	* constructor
-	*
-	* @param    mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object)
-	* @param    bool $wsdl optional, set to true if using WSDL
-	* @param	int $portName optional portName in WSDL document
-	* @param    string $proxyhost
-	* @param    string $proxyport
-	* @param	string $proxyusername
-	* @param	string $proxypassword
-	* @param	integer $timeout set the connection timeout
-	* @param	integer $response_timeout set the response timeout
-	* @access   public
-	*/
-	function soapclient_nusoap($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
-		parent::nusoap_base();
-		$this->endpoint = $endpoint;
-		$this->proxyhost = $proxyhost;
-		$this->proxyport = $proxyport;
-		$this->proxyusername = $proxyusername;
-		$this->proxypassword = $proxypassword;
-		$this->timeout = $timeout;
-		$this->response_timeout = $response_timeout;
-
-		// make values
-		if($wsdl){
-			if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
-				$this->wsdl = $endpoint;
-				$this->endpoint = $this->wsdl->wsdl;
-				$this->wsdlFile = $this->endpoint;
-				$this->debug('existing wsdl instance created from ' . $this->endpoint);
-			} else {
-				$this->wsdlFile = $this->endpoint;
-				
-				// instantiate wsdl object and parse wsdl file
-				$this->debug('instantiating wsdl class with doc: '.$endpoint);
-				$this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout);
-			}
-			$this->appendDebug($this->wsdl->getDebug());
-			$this->wsdl->clearDebug();
-			// catch errors
-			if($errstr = $this->wsdl->getError()){
-				$this->debug('got wsdl error: '.$errstr);
-				$this->setError('wsdl error: '.$errstr);
-			} elseif($this->operations = $this->wsdl->getOperations()){
-				$this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile);
-				$this->endpointType = 'wsdl';
-			} else {
-				$this->debug( 'getOperations returned false');
-				$this->setError('no operations defined in the WSDL document!');
-			}
-		} else {
-			$this->debug("instantiate SOAP with endpoint at $endpoint");
-			$this->endpointType = 'soap';
-		}
-	}
-
-	/**
-	* calls method, returns PHP native type
-	*
-	* @param    string $method SOAP server URL or path
-	* @param    mixed $params An array, associative or simple, of the parameters
-	*			              for the method call, or a string that is the XML
-	*			              for the call.  For rpc style, this call will
-	*			              wrap the XML in a tag named after the method, as
-	*			              well as the SOAP Envelope and Body.  For document
-	*			              style, this will only wrap with the Envelope and Body.
-	*			              IMPORTANT: when using an array with document style,
-	*			              in which case there
-	*                         is really one parameter, the root of the fragment
-	*                         used in the call, which encloses what programmers
-	*                         normally think of parameters.  A parameter array
-	*                         *must* include the wrapper.
-	* @param	string $namespace optional method namespace (WSDL can override)
-	* @param	string $soapAction optional SOAPAction value (WSDL can override)
-	* @param	mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
-	* @param	boolean $rpcParams optional (no longer used)
-	* @param	string	$style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
-	* @param	string	$use optional (encoded|literal) the use when serializing parameters (WSDL can override)
-	* @return	mixed	response from SOAP call
-	* @access   public
-	*/
-	function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
-		$this->operation = $operation;
-		$this->fault = false;
-		$this->setError('');
-		$this->request = '';
-		$this->response = '';
-		$this->responseData = '';
-		$this->faultstring = '';
-		$this->faultcode = '';
-		$this->opData = array();
-		
-		$this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
-		$this->appendDebug('params=' . $this->varDump($params));
-		$this->appendDebug('headers=' . $this->varDump($headers));
-		if ($headers) {
-			$this->requestHeaders = $headers;
-		}
-		// serialize parameters
-		if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
-			// use WSDL for operation
-			$this->opData = $opData;
-			$this->debug("found operation");
-			$this->appendDebug('opData=' . $this->varDump($opData));
-			if (isset($opData['soapAction'])) {
-				$soapAction = $opData['soapAction'];
-			}
-			if (! $this->forceEndpoint) {
-				$this->endpoint = $opData['endpoint'];
-			} else {
-				$this->endpoint = $this->forceEndpoint;
-			}
-			$namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] :	$namespace;
-			$style = $opData['style'];
-			$use = $opData['input']['use'];
-			// add ns to ns array
-			if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
-				$nsPrefix = 'ns' . rand(1000, 9999);
-				$this->wsdl->namespaces[$nsPrefix] = $namespace;
-			}
-            $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
-			// serialize payload
-			if (is_string($params)) {
-				$this->debug("serializing param string for WSDL operation $operation");
-				$payload = $params;
-			} elseif (is_array($params)) {
-				$this->debug("serializing param array for WSDL operation $operation");
-				$payload = $this->wsdl->serializeRPCParameters($operation,'input',$params);
-			} else {
-				$this->debug('params must be array or string');
-				$this->setError('params must be array or string');
-				return false;
-			}
-            $usedNamespaces = $this->wsdl->usedNamespaces;
-			if (isset($opData['input']['encodingStyle'])) {
-				$encodingStyle = $opData['input']['encodingStyle'];
-			} else {
-				$encodingStyle = '';
-			}
-			$this->appendDebug($this->wsdl->getDebug());
-			$this->wsdl->clearDebug();
-			if ($errstr = $this->wsdl->getError()) {
-				$this->debug('got wsdl error: '.$errstr);
-				$this->setError('wsdl error: '.$errstr);
-				return false;
-			}
-		} elseif($this->endpointType == 'wsdl') {
-			// operation not in WSDL
-			$this->appendDebug($this->wsdl->getDebug());
-			$this->wsdl->clearDebug();
-			$this->setError( 'operation '.$operation.' not present.');
-			$this->debug("operation '$operation' not present.");
-			return false;
-		} else {
-			// no WSDL
-			//$this->namespaces['ns1'] = $namespace;
-			$nsPrefix = 'ns' . rand(1000, 9999);
-			// serialize 
-			$payload = '';
-			if (is_string($params)) {
-				$this->debug("serializing param string for operation $operation");
-				$payload = $params;
-			} elseif (is_array($params)) {
-				$this->debug("serializing param array for operation $operation");
-				foreach($params as $k => $v){
-					$payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
-				}
-			} else {
-				$this->debug('params must be array or string');
-				$this->setError('params must be array or string');
-				return false;
-			}
-			$usedNamespaces = array();
-			if ($use == 'encoded') {
-				$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-			} else {
-				$encodingStyle = '';
-			}
-		}
-		// wrap RPC calls with method element
-		if ($style == 'rpc') {
-			if ($use == 'literal') {
-				$this->debug("wrapping RPC request with literal method element");
-				if ($namespace) {
-					$payload = "<$operation xmlns=\"$namespace\">" . $payload . "</$operation>";
-				} else {
-					$payload = "<$operation>" . $payload . "</$operation>";
-				}
-			} else {
-				$this->debug("wrapping RPC request with encoded method element");
-				if ($namespace) {
-					$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
-								$payload .
-								"</$nsPrefix:$operation>";
-				} else {
-					$payload = "<$operation>" .
-								$payload .
-								"</$operation>";
-				}
-			}
-		}
-		// serialize envelope
-		$soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
-		$this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
-		$this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
-		// send
-		$return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
-		if($errstr = $this->getError()){
-			$this->debug('Error: '.$errstr);
-			return false;
-		} else {
-			$this->return = $return;
-			$this->debug('sent message successfully and got a(n) '.gettype($return));
-           	$this->appendDebug('return=' . $this->varDump($return));
-			
-			// fault?
-			if(is_array($return) && isset($return['faultcode'])){
-				$this->debug('got fault');
-				$this->setError($return['faultcode'].': '.$return['faultstring']);
-				$this->fault = true;
-				foreach($return as $k => $v){
-					$this->$k = $v;
-					$this->debug("$k = $v<br>");
-				}
-				return $return;
-			} elseif ($style == 'document') {
-				// NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
-				// we are only going to return the first part here...sorry about that
-				return $return;
-			} else {
-				// array of return values
-				if(is_array($return)){
-					// multiple 'out' parameters, which we return wrapped up
-					// in the array
-					if(sizeof($return) > 1){
-						return $return;
-					}
-					// single 'out' parameter (normally the return value)
-					$return = array_shift($return);
-					$this->debug('return shifted value: ');
-					$this->appendDebug($this->varDump($return));
-           			return $return;
-				// nothing returned (ie, echoVoid)
-				} else {
-					return "";
-				}
-			}
-		}
-	}
-
-	/**
-	* get available data pertaining to an operation
-	*
-	* @param    string $operation operation name
-	* @return	array array of data pertaining to the operation
-	* @access   public
-	*/
-	function getOperationData($operation){
-		if(isset($this->operations[$operation])){
-			return $this->operations[$operation];
-		}
-		$this->debug("No data for operation: $operation");
-	}
-
-    /**
-    * send the SOAP message
-    *
-    * Note: if the operation has multiple return values
-    * the return value of this method will be an array
-    * of those values.
-    *
-	* @param    string $msg a SOAPx4 soapmsg object
-	* @param    string $soapaction SOAPAction value
-	* @param    integer $timeout set connection timeout in seconds
-	* @param	integer $response_timeout set response timeout in seconds
-	* @return	mixed native PHP types.
-	* @access   private
-	*/
-	function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
-		$this->checkCookies();
-		// detect transport
-		switch(true){
-			// http(s)
-			case ereg('^http',$this->endpoint):
-				$this->debug('transporting via HTTP');
-				if($this->persistentConnection == true && is_object($this->persistentConnection)){
-					$http =& $this->persistentConnection;
-				} else {
-					$http = new soap_transport_http($this->endpoint);
-					if ($this->persistentConnection) {
-						$http->usePersistentConnection();
-					}
-				}
-				$http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
-				$http->setSOAPAction($soapaction);
-				if($this->proxyhost && $this->proxyport){
-					$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
-				}
-                if($this->authtype != '') {
-					$http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
-				}
-				if($this->http_encoding != ''){
-					$http->setEncoding($this->http_encoding);
-				}
-				$this->debug('sending message, length='.strlen($msg));
-				if(ereg('^http:',$this->endpoint)){
-				//if(strpos($this->endpoint,'http:')){
-					$this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
-				} elseif(ereg('^https',$this->endpoint)){
-				//} elseif(strpos($this->endpoint,'https:')){
-					//if(phpversion() == '4.3.0-dev'){
-						//$response = $http->send($msg,$timeout,$response_timeout);
-                   		//$this->request = $http->outgoing_payload;
-						//$this->response = $http->incoming_payload;
-					//} else
-					$this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
-				} else {
-					$this->setError('no http/s in endpoint url');
-				}
-				$this->request = $http->outgoing_payload;
-				$this->response = $http->incoming_payload;
-				$this->appendDebug($http->getDebug());
-				$this->UpdateCookies($http->incoming_cookies);
-
-				// save transport object if using persistent connections
-				if ($this->persistentConnection) {
-					$http->clearDebug();
-					if (!is_object($this->persistentConnection)) {
-						$this->persistentConnection = $http;
-					}
-				}
-				
-				if($err = $http->getError()){
-					$this->setError('HTTP Error: '.$err);
-					return false;
-				} elseif($this->getError()){
-					return false;
-				} else {
-					$this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
-					return $this->parseResponse($http->incoming_headers, $this->responseData);
-				}
-			break;
-			default:
-				$this->setError('no transport found, or selected transport is not yet supported!');
-			return false;
-			break;
-		}
-	}
-
-	/**
-	* processes SOAP message returned from server
-	*
-	* @param	array	$headers	The HTTP headers
-	* @param	string	$data		unprocessed response data from server
-	* @return	mixed	value of the message, decoded into a PHP type
-	* @access   private
-	*/
-    function parseResponse($headers, $data) {
-		$this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
-		if (!strstr($headers['content-type'], 'text/xml')) {
-			$this->setError('Response not of type text/xml');
-			return false;
-		}
-		if (strpos($headers['content-type'], '=')) {
-			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
-			$this->debug('Got response encoding: ' . $enc);
-			if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
-				$this->xml_encoding = strtoupper($enc);
-			} else {
-				$this->xml_encoding = 'US-ASCII';
-			}
-		} else {
-			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-			$this->xml_encoding = 'ISO-8859-1';
-		}
-		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
-		$parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
-		// add parser debug data to our debug
-		$this->appendDebug($parser->getDebug());
-		// if parse errors
-		if($errstr = $parser->getError()){
-			$this->setError( $errstr);
-			// destroy the parser object
-			unset($parser);
-			return false;
-		} else {
-			// get SOAP headers
-			$this->responseHeaders = $parser->getHeaders();
-			// get decoded message
-			$return = $parser->get_response();
-            // add document for doclit support
-            $this->document = $parser->document;
-			// destroy the parser object
-			unset($parser);
-			// return decode message
-			return $return;
-		}
-	 }
-
-	/**
-	* sets the SOAP endpoint, which can override WSDL
-	*
-	* @param	$endpoint string The endpoint URL to use, or empty string or false to prevent override
-	* @access   public
-	*/
-	function setEndpoint($endpoint) {
-		$this->forceEndpoint = $endpoint;
-	}
-
-	/**
-	* set the SOAP headers
-	*
-	* @param	$headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers
-	* @access   public
-	*/
-	function setHeaders($headers){
-		$this->requestHeaders = $headers;
-	}
-
-	/**
-	* get the SOAP response headers (namespace resolution incomplete)
-	*
-	* @return	string
-	* @access   public
-	*/
-	function getHeaders(){
-		return $this->responseHeaders;
-	}
-
-	/**
-	* set proxy info here
-	*
-	* @param    string $proxyhost
-	* @param    string $proxyport
-	* @param	string $proxyusername
-	* @param	string $proxypassword
-	* @access   public
-	*/
-	function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
-		$this->proxyhost = $proxyhost;
-		$this->proxyport = $proxyport;
-		$this->proxyusername = $proxyusername;
-		$this->proxypassword = $proxypassword;
-	}
-
-	/**
-	* if authenticating, set user credentials here
-	*
-	* @param    string $username
-	* @param    string $password
-	* @param	string $authtype (basic|digest|certificate)
-	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
-	* @access   public
-	*/
-	function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
-		$this->username = $username;
-		$this->password = $password;
-		$this->authtype = $authtype;
-		$this->certRequest = $certRequest;
-	}
-	
-	/**
-	* use HTTP encoding
-	*
-	* @param    string $enc
-	* @access   public
-	*/
-	function setHTTPEncoding($enc='gzip, deflate'){
-		$this->http_encoding = $enc;
-	}
-	
-	/**
-	* use HTTP persistent connections if possible
-	*
-	* @access   public
-	*/
-	function useHTTPPersistentConnection(){
-		$this->persistentConnection = true;
-	}
-	
-	/**
-	* gets the default RPC parameter setting.
-	* If true, default is that call params are like RPC even for document style.
-	* Each call() can override this value.
-	*
-	* This is no longer used.
-	*
-	* @return boolean
-	* @access public
-	* @deprecated
-	*/
-	function getDefaultRpcParams() {
-		return $this->defaultRpcParams;
-	}
-
-	/**
-	* sets the default RPC parameter setting.
-	* If true, default is that call params are like RPC even for document style
-	* Each call() can override this value.
-	*
-	* This is no longer used.
-	*
-	* @param    boolean $rpcParams
-	* @access public
-	* @deprecated
-	*/
-	function setDefaultRpcParams($rpcParams) {
-		$this->defaultRpcParams = $rpcParams;
-	}
-	
-	/**
-	* dynamically creates an instance of a proxy class,
-	* allowing user to directly call methods from wsdl
-	*
-	* @return   object soap_proxy object
-	* @access   public
-	*/
-	function getProxy(){
-		$r = rand();
-		$evalStr = $this->_getProxyClassCode($r);
-		//$this->debug("proxy class: $evalStr";
-		// eval the class
-		eval($evalStr);
-		// instantiate proxy object
-		eval("\$proxy = new soap_proxy_$r('');");
-		// transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
-		$proxy->endpointType = 'wsdl';
-		$proxy->wsdlFile = $this->wsdlFile;
-		$proxy->wsdl = $this->wsdl;
-		$proxy->operations = $this->operations;
-		$proxy->defaultRpcParams = $this->defaultRpcParams;
-		// transfer other state
-		$proxy->username = $this->username;
-		$proxy->password = $this->password;
-		$proxy->authtype = $this->authtype;
-		$proxy->proxyhost = $this->proxyhost;
-		$proxy->proxyport = $this->proxyport;
-		$proxy->proxyusername = $this->proxyusername;
-		$proxy->proxypassword = $this->proxypassword;
-		$proxy->timeout = $this->timeout;
-		$proxy->response_timeout = $this->response_timeout;
-		$proxy->http_encoding = $this->http_encoding;
-		$proxy->persistentConnection = $this->persistentConnection;
-		$proxy->requestHeaders = $this->requestHeaders;
-		$proxy->soap_defencoding = $this->soap_defencoding;
-		$proxy->endpoint = $this->endpoint;
-		$proxy->forceEndpoint = $this->forceEndpoint;
-		return $proxy;
-	}
-
-	/**
-	* dynamically creates proxy class code
-	*
-	* @return   string PHP/NuSOAP code for the proxy class
-	* @access   private
-	*/
-	function _getProxyClassCode($r) {
-		if ($this->endpointType != 'wsdl') {
-			$evalStr = 'A proxy can only be created for a WSDL client';
-			$this->setError($evalStr);
-			return $evalStr;
-		}
-		$evalStr = '';
-		foreach ($this->operations as $operation => $opData) {
-			if ($operation != '') {
-				// create param string and param comment string
-				if (sizeof($opData['input']['parts']) > 0) {
-					$paramStr = '';
-					$paramArrayStr = '';
-					$paramCommentStr = '';
-					foreach ($opData['input']['parts'] as $name => $type) {
-						$paramStr .= "\$$name, ";
-						$paramArrayStr .= "'$name' => \$$name, ";
-						$paramCommentStr .= "$type \$$name, ";
-					}
-					$paramStr = substr($paramStr, 0, strlen($paramStr)-2);
-					$paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
-					$paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
-				} else {
-					$paramStr = '';
-					$paramCommentStr = 'void';
-				}
-				$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
-				$evalStr .= "// $paramCommentStr
-	function " . str_replace('.', '__', $operation) . "($paramStr) {
-		\$params = array($paramArrayStr);
-		return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
-	}
-	";
-				unset($paramStr);
-				unset($paramCommentStr);
-			}
-		}
-		$evalStr = 'class soap_proxy_'.$r.' extends soapclient_nusoap {
-	'.$evalStr.'
-}';
-		return $evalStr;
-	}
-
-	/**
-	* dynamically creates proxy class code
-	*
-	* @return   string PHP/NuSOAP code for the proxy class
-	* @access   public
-	*/
-	function getProxyClassCode() {
-		$r = rand();
-		return $this->_getProxyClassCode($r);
-	}
-
-	/**
-	* gets the HTTP body for the current request.
-	*
-	* @param string $soapmsg The SOAP payload
-	* @return string The HTTP body, which includes the SOAP payload
-	* @access private
-	*/
-	function getHTTPBody($soapmsg) {
-		return $soapmsg;
-	}
-	
-	/**
-	* gets the HTTP content type for the current request.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type for the current request.
-	* @access private
-	*/
-	function getHTTPContentType() {
-		return 'text/xml';
-	}
-	
-	/**
-	* gets the HTTP content type charset for the current request.
-	* returns false for non-text content types.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type charset for the current request.
-	* @access private
-	*/
-	function getHTTPContentTypeCharset() {
-		return $this->soap_defencoding;
-	}
-
-	/*
-	* whether or not parser should decode utf8 element content
-    *
-    * @return   always returns true
-    * @access   public
-    */
-    function decodeUTF8($bool){
-		$this->decode_utf8 = $bool;
-		return true;
-    }
-
-	/**
-	 * adds a new Cookie into $this->cookies array
-	 *
-	 * @param	string $name Cookie Name
-	 * @param	string $value Cookie Value
-	 * @return	if cookie-set was successful returns true, else false
-	 * @access	public
-	 */
-	function setCookie($name, $value) {
-		if (strlen($name) == 0) {
-			return false;
-		}
-		$this->cookies[] = array('name' => $name, 'value' => $value);
-		return true;
-	}
-
-	/**
-	 * gets all Cookies
-	 *
-	 * @return   array with all internal cookies
-	 * @access   public
-	 */
-	function getCookies() {
-		return $this->cookies;
-	}
-
-	/**
-	 * checks all Cookies and delete those which are expired
-	 *
-	 * @return   always return true
-	 * @access   private
-	 */
-	function checkCookies() {
-		if (sizeof($this->cookies) == 0) {
-			return true;
-		}
-		$this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
-		$curr_cookies = $this->cookies;
-		$this->cookies = array();
-		foreach ($curr_cookies as $cookie) {
-			if (! is_array($cookie)) {
-				$this->debug('Remove cookie that is not an array');
-				continue;
-			}
-			if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
-				if (strtotime($cookie['expires']) > time()) {
-					$this->cookies[] = $cookie;
-				} else {
-					$this->debug('Remove expired cookie ' . $cookie['name']);
-				}
-			} else {
-				$this->cookies[] = $cookie;
-			}
-		}
-		$this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
-		return true;
-	}
-
-	/**
-	 * updates the current cookies with a new set
-	 *
-	 * @param	array $cookies new cookies with which to update current ones
-	 * @return	always return true
-	 * @access	private
-	 */
-	function UpdateCookies($cookies) {
-		if (sizeof($this->cookies) == 0) {
-			// no existing cookies: take whatever is new
-			if (sizeof($cookies) > 0) {
-				$this->debug('Setting new cookie(s)');
-				$this->cookies = $cookies;
-			}
-			return true;
-		}
-		if (sizeof($cookies) == 0) {
-			// no new cookies: keep what we've got
-			return true;
-		}
-		// merge
-		foreach ($cookies as $newCookie) {
-			if (!is_array($newCookie)) {
-				continue;
-			}
-			if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
-				continue;
-			}
-			$newName = $newCookie['name'];
-
-			$found = false;
-			for ($i = 0; $i < count($this->cookies); $i++) {
-				$cookie = $this->cookies[$i];
-				if (!is_array($cookie)) {
-					continue;
-				}
-				if (!isset($cookie['name'])) {
-					continue;
-				}
-				if ($newName != $cookie['name']) {
-					continue;
-				}
-				$newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
-				$domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
-				if ($newDomain != $domain) {
-					continue;
-				}
-				$newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
-				$path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
-				if ($newPath != $path) {
-					continue;
-				}
-				$this->cookies[$i] = $newCookie;
-				$found = true;
-				$this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
-				break;
-			}
-			if (! $found) {
-				$this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
-				$this->cookies[] = $newCookie;
-			}
-		}
-		return true;
-	}
-}
-?>
+<?php
+
+
+
+
+/**
+*
+* soapclient higher level class for easy usage.
+*
+* usage:
+*
+* // instantiate client with server info
+* $soapclient = new soapclient_nusoap( string path [ ,boolean wsdl] );
+*
+* // call method, get results
+* echo $soapclient->call( string methodname [ ,array parameters] );
+*
+* // bye bye client
+* unset($soapclient);
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class soapclient_nusoap extends nusoap_base  {
+
+	var $username = '';
+	var $password = '';
+	var $authtype = '';
+	var $certRequest = array();
+	var $requestHeaders = false;	// SOAP headers in request (text)
+	var $responseHeaders = '';		// SOAP headers from response (incomplete namespace resolution) (text)
+	var $document = '';				// SOAP body response portion (incomplete namespace resolution) (text)
+	var $endpoint;
+	var $forceEndpoint = '';		// overrides WSDL endpoint
+    var $proxyhost = '';
+    var $proxyport = '';
+	var $proxyusername = '';
+	var $proxypassword = '';
+    var $xml_encoding = '';			// character set encoding of incoming (response) messages
+	var $http_encoding = false;
+	var $timeout = 0;				// HTTP connection timeout
+	var $response_timeout = 30;		// HTTP response timeout
+	var $endpointType = '';			// soap|wsdl, empty for WSDL initialization error
+	var $persistentConnection = false;
+	var $defaultRpcParams = false;	// This is no longer used
+	var $request = '';				// HTTP request
+	var $response = '';				// HTTP response
+	var $responseData = '';			// SOAP payload of response
+	var $cookies = array();			// Cookies from response or for request
+    var $decode_utf8 = true;		// toggles whether the parser decodes element content w/ utf8_decode()
+	var $operations = array();		// WSDL operations, empty for WSDL initialization error
+	
+	/*
+	 * fault related variables
+	 */
+	/**
+	 * @var      fault
+	 * @access   public
+	 */
+	var $fault;
+	/**
+	 * @var      faultcode
+	 * @access   public
+	 */
+	var $faultcode;
+	/**
+	 * @var      faultstring
+	 * @access   public
+	 */
+	var $faultstring;
+	/**
+	 * @var      faultdetail
+	 * @access   public
+	 */
+	var $faultdetail;
+
+	/**
+	* constructor
+	*
+	* @param    mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object)
+	* @param    bool $wsdl optional, set to true if using WSDL
+	* @param	int $portName optional portName in WSDL document
+	* @param    string $proxyhost
+	* @param    string $proxyport
+	* @param	string $proxyusername
+	* @param	string $proxypassword
+	* @param	integer $timeout set the connection timeout
+	* @param	integer $response_timeout set the response timeout
+	* @access   public
+	*/
+	function soapclient_nusoap($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
+		parent::nusoap_base();
+		$this->endpoint = $endpoint;
+		$this->proxyhost = $proxyhost;
+		$this->proxyport = $proxyport;
+		$this->proxyusername = $proxyusername;
+		$this->proxypassword = $proxypassword;
+		$this->timeout = $timeout;
+		$this->response_timeout = $response_timeout;
+
+		// make values
+		if($wsdl){
+			if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
+				$this->wsdl = $endpoint;
+				$this->endpoint = $this->wsdl->wsdl;
+				$this->wsdlFile = $this->endpoint;
+				$this->debug('existing wsdl instance created from ' . $this->endpoint);
+			} else {
+				$this->wsdlFile = $this->endpoint;
+				
+				// instantiate wsdl object and parse wsdl file
+				$this->debug('instantiating wsdl class with doc: '.$endpoint);
+				$this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout);
+			}
+			$this->appendDebug($this->wsdl->getDebug());
+			$this->wsdl->clearDebug();
+			// catch errors
+			if($errstr = $this->wsdl->getError()){
+				$this->debug('got wsdl error: '.$errstr);
+				$this->setError('wsdl error: '.$errstr);
+			} elseif($this->operations = $this->wsdl->getOperations()){
+				$this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile);
+				$this->endpointType = 'wsdl';
+			} else {
+				$this->debug( 'getOperations returned false');
+				$this->setError('no operations defined in the WSDL document!');
+			}
+		} else {
+			$this->debug("instantiate SOAP with endpoint at $endpoint");
+			$this->endpointType = 'soap';
+		}
+	}
+
+	/**
+	* calls method, returns PHP native type
+	*
+	* @param    string $method SOAP server URL or path
+	* @param    mixed $params An array, associative or simple, of the parameters
+	*			              for the method call, or a string that is the XML
+	*			              for the call.  For rpc style, this call will
+	*			              wrap the XML in a tag named after the method, as
+	*			              well as the SOAP Envelope and Body.  For document
+	*			              style, this will only wrap with the Envelope and Body.
+	*			              IMPORTANT: when using an array with document style,
+	*			              in which case there
+	*                         is really one parameter, the root of the fragment
+	*                         used in the call, which encloses what programmers
+	*                         normally think of parameters.  A parameter array
+	*                         *must* include the wrapper.
+	* @param	string $namespace optional method namespace (WSDL can override)
+	* @param	string $soapAction optional SOAPAction value (WSDL can override)
+	* @param	mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
+	* @param	boolean $rpcParams optional (no longer used)
+	* @param	string	$style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
+	* @param	string	$use optional (encoded|literal) the use when serializing parameters (WSDL can override)
+	* @return	mixed	response from SOAP call
+	* @access   public
+	*/
+	function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
+		$this->operation = $operation;
+		$this->fault = false;
+		$this->setError('');
+		$this->request = '';
+		$this->response = '';
+		$this->responseData = '';
+		$this->faultstring = '';
+		$this->faultcode = '';
+		$this->opData = array();
+		
+		$this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
+		$this->appendDebug('params=' . $this->varDump($params));
+		$this->appendDebug('headers=' . $this->varDump($headers));
+		if ($headers) {
+			$this->requestHeaders = $headers;
+		}
+		// serialize parameters
+		if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
+			// use WSDL for operation
+			$this->opData = $opData;
+			$this->debug("found operation");
+			$this->appendDebug('opData=' . $this->varDump($opData));
+			if (isset($opData['soapAction'])) {
+				$soapAction = $opData['soapAction'];
+			}
+			if (! $this->forceEndpoint) {
+				$this->endpoint = $opData['endpoint'];
+			} else {
+				$this->endpoint = $this->forceEndpoint;
+			}
+			$namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] :	$namespace;
+			$style = $opData['style'];
+			$use = $opData['input']['use'];
+			// add ns to ns array
+			if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
+				$nsPrefix = 'ns' . rand(1000, 9999);
+				$this->wsdl->namespaces[$nsPrefix] = $namespace;
+			}
+            $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
+			// serialize payload
+			if (is_string($params)) {
+				$this->debug("serializing param string for WSDL operation $operation");
+				$payload = $params;
+			} elseif (is_array($params)) {
+				$this->debug("serializing param array for WSDL operation $operation");
+				$payload = $this->wsdl->serializeRPCParameters($operation,'input',$params);
+			} else {
+				$this->debug('params must be array or string');
+				$this->setError('params must be array or string');
+				return false;
+			}
+            $usedNamespaces = $this->wsdl->usedNamespaces;
+			if (isset($opData['input']['encodingStyle'])) {
+				$encodingStyle = $opData['input']['encodingStyle'];
+			} else {
+				$encodingStyle = '';
+			}
+			$this->appendDebug($this->wsdl->getDebug());
+			$this->wsdl->clearDebug();
+			if ($errstr = $this->wsdl->getError()) {
+				$this->debug('got wsdl error: '.$errstr);
+				$this->setError('wsdl error: '.$errstr);
+				return false;
+			}
+		} elseif($this->endpointType == 'wsdl') {
+			// operation not in WSDL
+			$this->appendDebug($this->wsdl->getDebug());
+			$this->wsdl->clearDebug();
+			$this->setError( 'operation '.$operation.' not present.');
+			$this->debug("operation '$operation' not present.");
+			return false;
+		} else {
+			// no WSDL
+			//$this->namespaces['ns1'] = $namespace;
+			$nsPrefix = 'ns' . rand(1000, 9999);
+			// serialize 
+			$payload = '';
+			if (is_string($params)) {
+				$this->debug("serializing param string for operation $operation");
+				$payload = $params;
+			} elseif (is_array($params)) {
+				$this->debug("serializing param array for operation $operation");
+				foreach($params as $k => $v){
+					$payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
+				}
+			} else {
+				$this->debug('params must be array or string');
+				$this->setError('params must be array or string');
+				return false;
+			}
+			$usedNamespaces = array();
+			if ($use == 'encoded') {
+				$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+			} else {
+				$encodingStyle = '';
+			}
+		}
+		// wrap RPC calls with method element
+		if ($style == 'rpc') {
+			if ($use == 'literal') {
+				$this->debug("wrapping RPC request with literal method element");
+				if ($namespace) {
+					$payload = "<$operation xmlns=\"$namespace\">" . $payload . "</$operation>";
+				} else {
+					$payload = "<$operation>" . $payload . "</$operation>";
+				}
+			} else {
+				$this->debug("wrapping RPC request with encoded method element");
+				if ($namespace) {
+					$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
+								$payload .
+								"</$nsPrefix:$operation>";
+				} else {
+					$payload = "<$operation>" .
+								$payload .
+								"</$operation>";
+				}
+			}
+		}
+		// serialize envelope
+		$soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
+		$this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
+		$this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
+		// send
+		$return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
+		if($errstr = $this->getError()){
+			$this->debug('Error: '.$errstr);
+			return false;
+		} else {
+			$this->return = $return;
+			$this->debug('sent message successfully and got a(n) '.gettype($return));
+           	$this->appendDebug('return=' . $this->varDump($return));
+			
+			// fault?
+			if(is_array($return) && isset($return['faultcode'])){
+				$this->debug('got fault');
+				$this->setError($return['faultcode'].': '.$return['faultstring']);
+				$this->fault = true;
+				foreach($return as $k => $v){
+					$this->$k = $v;
+					$this->debug("$k = $v<br>");
+				}
+				return $return;
+			} elseif ($style == 'document') {
+				// NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
+				// we are only going to return the first part here...sorry about that
+				return $return;
+			} else {
+				// array of return values
+				if(is_array($return)){
+					// multiple 'out' parameters, which we return wrapped up
+					// in the array
+					if(sizeof($return) > 1){
+						return $return;
+					}
+					// single 'out' parameter (normally the return value)
+					$return = array_shift($return);
+					$this->debug('return shifted value: ');
+					$this->appendDebug($this->varDump($return));
+           			return $return;
+				// nothing returned (ie, echoVoid)
+				} else {
+					return "";
+				}
+			}
+		}
+	}
+
+	/**
+	* get available data pertaining to an operation
+	*
+	* @param    string $operation operation name
+	* @return	array array of data pertaining to the operation
+	* @access   public
+	*/
+	function getOperationData($operation){
+		if(isset($this->operations[$operation])){
+			return $this->operations[$operation];
+		}
+		$this->debug("No data for operation: $operation");
+	}
+
+    /**
+    * send the SOAP message
+    *
+    * Note: if the operation has multiple return values
+    * the return value of this method will be an array
+    * of those values.
+    *
+	* @param    string $msg a SOAPx4 soapmsg object
+	* @param    string $soapaction SOAPAction value
+	* @param    integer $timeout set connection timeout in seconds
+	* @param	integer $response_timeout set response timeout in seconds
+	* @return	mixed native PHP types.
+	* @access   private
+	*/
+	function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
+		$this->checkCookies();
+		// detect transport
+		switch(true){
+			// http(s)
+			case ereg('^http',$this->endpoint):
+				$this->debug('transporting via HTTP');
+				if($this->persistentConnection == true && is_object($this->persistentConnection)){
+					$http =& $this->persistentConnection;
+				} else {
+					$http = new soap_transport_http($this->endpoint);
+					if ($this->persistentConnection) {
+						$http->usePersistentConnection();
+					}
+				}
+				$http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
+				$http->setSOAPAction($soapaction);
+				if($this->proxyhost && $this->proxyport){
+					$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
+				}
+                if($this->authtype != '') {
+					$http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
+				}
+				if($this->http_encoding != ''){
+					$http->setEncoding($this->http_encoding);
+				}
+				$this->debug('sending message, length='.strlen($msg));
+				if(ereg('^http:',$this->endpoint)){
+				//if(strpos($this->endpoint,'http:')){
+					$this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
+				} elseif(ereg('^https',$this->endpoint)){
+				//} elseif(strpos($this->endpoint,'https:')){
+					//if(phpversion() == '4.3.0-dev'){
+						//$response = $http->send($msg,$timeout,$response_timeout);
+                   		//$this->request = $http->outgoing_payload;
+						//$this->response = $http->incoming_payload;
+					//} else
+					$this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
+				} else {
+					$this->setError('no http/s in endpoint url');
+				}
+				$this->request = $http->outgoing_payload;
+				$this->response = $http->incoming_payload;
+				$this->appendDebug($http->getDebug());
+				$this->UpdateCookies($http->incoming_cookies);
+
+				// save transport object if using persistent connections
+				if ($this->persistentConnection) {
+					$http->clearDebug();
+					if (!is_object($this->persistentConnection)) {
+						$this->persistentConnection = $http;
+					}
+				}
+				
+				if($err = $http->getError()){
+					$this->setError('HTTP Error: '.$err);
+					return false;
+				} elseif($this->getError()){
+					return false;
+				} else {
+					$this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
+					return $this->parseResponse($http->incoming_headers, $this->responseData);
+				}
+			break;
+			default:
+				$this->setError('no transport found, or selected transport is not yet supported!');
+			return false;
+			break;
+		}
+	}
+
+	/**
+	* processes SOAP message returned from server
+	*
+	* @param	array	$headers	The HTTP headers
+	* @param	string	$data		unprocessed response data from server
+	* @return	mixed	value of the message, decoded into a PHP type
+	* @access   private
+	*/
+    function parseResponse($headers, $data) {
+		$this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
+		if (!strstr($headers['content-type'], 'text/xml')) {
+			$this->setError('Response not of type text/xml');
+			return false;
+		}
+		if (strpos($headers['content-type'], '=')) {
+			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
+			$this->debug('Got response encoding: ' . $enc);
+			if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
+				$this->xml_encoding = strtoupper($enc);
+			} else {
+				$this->xml_encoding = 'US-ASCII';
+			}
+		} else {
+			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+			$this->xml_encoding = 'ISO-8859-1';
+		}
+		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
+		$parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
+		// add parser debug data to our debug
+		$this->appendDebug($parser->getDebug());
+		// if parse errors
+		if($errstr = $parser->getError()){
+			$this->setError( $errstr);
+			// destroy the parser object
+			unset($parser);
+			return false;
+		} else {
+			// get SOAP headers
+			$this->responseHeaders = $parser->getHeaders();
+			// get decoded message
+			$return = $parser->get_response();
+            // add document for doclit support
+            $this->document = $parser->document;
+			// destroy the parser object
+			unset($parser);
+			// return decode message
+			return $return;
+		}
+	 }
+
+	/**
+	* sets the SOAP endpoint, which can override WSDL
+	*
+	* @param	$endpoint string The endpoint URL to use, or empty string or false to prevent override
+	* @access   public
+	*/
+	function setEndpoint($endpoint) {
+		$this->forceEndpoint = $endpoint;
+	}
+
+	/**
+	* set the SOAP headers
+	*
+	* @param	$headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers
+	* @access   public
+	*/
+	function setHeaders($headers){
+		$this->requestHeaders = $headers;
+	}
+
+	/**
+	* get the SOAP response headers (namespace resolution incomplete)
+	*
+	* @return	string
+	* @access   public
+	*/
+	function getHeaders(){
+		return $this->responseHeaders;
+	}
+
+	/**
+	* set proxy info here
+	*
+	* @param    string $proxyhost
+	* @param    string $proxyport
+	* @param	string $proxyusername
+	* @param	string $proxypassword
+	* @access   public
+	*/
+	function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
+		$this->proxyhost = $proxyhost;
+		$this->proxyport = $proxyport;
+		$this->proxyusername = $proxyusername;
+		$this->proxypassword = $proxypassword;
+	}
+
+	/**
+	* if authenticating, set user credentials here
+	*
+	* @param    string $username
+	* @param    string $password
+	* @param	string $authtype (basic|digest|certificate)
+	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
+	* @access   public
+	*/
+	function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
+		$this->username = $username;
+		$this->password = $password;
+		$this->authtype = $authtype;
+		$this->certRequest = $certRequest;
+	}
+	
+	/**
+	* use HTTP encoding
+	*
+	* @param    string $enc
+	* @access   public
+	*/
+	function setHTTPEncoding($enc='gzip, deflate'){
+		$this->http_encoding = $enc;
+	}
+	
+	/**
+	* use HTTP persistent connections if possible
+	*
+	* @access   public
+	*/
+	function useHTTPPersistentConnection(){
+		$this->persistentConnection = true;
+	}
+	
+	/**
+	* gets the default RPC parameter setting.
+	* If true, default is that call params are like RPC even for document style.
+	* Each call() can override this value.
+	*
+	* This is no longer used.
+	*
+	* @return boolean
+	* @access public
+	* @deprecated
+	*/
+	function getDefaultRpcParams() {
+		return $this->defaultRpcParams;
+	}
+
+	/**
+	* sets the default RPC parameter setting.
+	* If true, default is that call params are like RPC even for document style
+	* Each call() can override this value.
+	*
+	* This is no longer used.
+	*
+	* @param    boolean $rpcParams
+	* @access public
+	* @deprecated
+	*/
+	function setDefaultRpcParams($rpcParams) {
+		$this->defaultRpcParams = $rpcParams;
+	}
+	
+	/**
+	* dynamically creates an instance of a proxy class,
+	* allowing user to directly call methods from wsdl
+	*
+	* @return   object soap_proxy object
+	* @access   public
+	*/
+	function getProxy(){
+		$r = rand();
+		$evalStr = $this->_getProxyClassCode($r);
+		//$this->debug("proxy class: $evalStr";
+		// eval the class
+		eval($evalStr);
+		// instantiate proxy object
+		eval("\$proxy = new soap_proxy_$r('');");
+		// transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
+		$proxy->endpointType = 'wsdl';
+		$proxy->wsdlFile = $this->wsdlFile;
+		$proxy->wsdl = $this->wsdl;
+		$proxy->operations = $this->operations;
+		$proxy->defaultRpcParams = $this->defaultRpcParams;
+		// transfer other state
+		$proxy->username = $this->username;
+		$proxy->password = $this->password;
+		$proxy->authtype = $this->authtype;
+		$proxy->proxyhost = $this->proxyhost;
+		$proxy->proxyport = $this->proxyport;
+		$proxy->proxyusername = $this->proxyusername;
+		$proxy->proxypassword = $this->proxypassword;
+		$proxy->timeout = $this->timeout;
+		$proxy->response_timeout = $this->response_timeout;
+		$proxy->http_encoding = $this->http_encoding;
+		$proxy->persistentConnection = $this->persistentConnection;
+		$proxy->requestHeaders = $this->requestHeaders;
+		$proxy->soap_defencoding = $this->soap_defencoding;
+		$proxy->endpoint = $this->endpoint;
+		$proxy->forceEndpoint = $this->forceEndpoint;
+		return $proxy;
+	}
+
+	/**
+	* dynamically creates proxy class code
+	*
+	* @return   string PHP/NuSOAP code for the proxy class
+	* @access   private
+	*/
+	function _getProxyClassCode($r) {
+		if ($this->endpointType != 'wsdl') {
+			$evalStr = 'A proxy can only be created for a WSDL client';
+			$this->setError($evalStr);
+			return $evalStr;
+		}
+		$evalStr = '';
+		foreach ($this->operations as $operation => $opData) {
+			if ($operation != '') {
+				// create param string and param comment string
+				if (sizeof($opData['input']['parts']) > 0) {
+					$paramStr = '';
+					$paramArrayStr = '';
+					$paramCommentStr = '';
+					foreach ($opData['input']['parts'] as $name => $type) {
+						$paramStr .= "\$$name, ";
+						$paramArrayStr .= "'$name' => \$$name, ";
+						$paramCommentStr .= "$type \$$name, ";
+					}
+					$paramStr = substr($paramStr, 0, strlen($paramStr)-2);
+					$paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
+					$paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
+				} else {
+					$paramStr = '';
+					$paramCommentStr = 'void';
+				}
+				$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
+				$evalStr .= "// $paramCommentStr
+	function " . str_replace('.', '__', $operation) . "($paramStr) {
+		\$params = array($paramArrayStr);
+		return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
+	}
+	";
+				unset($paramStr);
+				unset($paramCommentStr);
+			}
+		}
+		$evalStr = 'class soap_proxy_'.$r.' extends soapclient_nusoap {
+	'.$evalStr.'
+}';
+		return $evalStr;
+	}
+
+	/**
+	* dynamically creates proxy class code
+	*
+	* @return   string PHP/NuSOAP code for the proxy class
+	* @access   public
+	*/
+	function getProxyClassCode() {
+		$r = rand();
+		return $this->_getProxyClassCode($r);
+	}
+
+	/**
+	* gets the HTTP body for the current request.
+	*
+	* @param string $soapmsg The SOAP payload
+	* @return string The HTTP body, which includes the SOAP payload
+	* @access private
+	*/
+	function getHTTPBody($soapmsg) {
+		return $soapmsg;
+	}
+	
+	/**
+	* gets the HTTP content type for the current request.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type for the current request.
+	* @access private
+	*/
+	function getHTTPContentType() {
+		return 'text/xml';
+	}
+	
+	/**
+	* gets the HTTP content type charset for the current request.
+	* returns false for non-text content types.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type charset for the current request.
+	* @access private
+	*/
+	function getHTTPContentTypeCharset() {
+		return $this->soap_defencoding;
+	}
+
+	/*
+	* whether or not parser should decode utf8 element content
+    *
+    * @return   always returns true
+    * @access   public
+    */
+    function decodeUTF8($bool){
+		$this->decode_utf8 = $bool;
+		return true;
+    }
+
+	/**
+	 * adds a new Cookie into $this->cookies array
+	 *
+	 * @param	string $name Cookie Name
+	 * @param	string $value Cookie Value
+	 * @return	if cookie-set was successful returns true, else false
+	 * @access	public
+	 */
+	function setCookie($name, $value) {
+		if (strlen($name) == 0) {
+			return false;
+		}
+		$this->cookies[] = array('name' => $name, 'value' => $value);
+		return true;
+	}
+
+	/**
+	 * gets all Cookies
+	 *
+	 * @return   array with all internal cookies
+	 * @access   public
+	 */
+	function getCookies() {
+		return $this->cookies;
+	}
+
+	/**
+	 * checks all Cookies and delete those which are expired
+	 *
+	 * @return   always return true
+	 * @access   private
+	 */
+	function checkCookies() {
+		if (sizeof($this->cookies) == 0) {
+			return true;
+		}
+		$this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
+		$curr_cookies = $this->cookies;
+		$this->cookies = array();
+		foreach ($curr_cookies as $cookie) {
+			if (! is_array($cookie)) {
+				$this->debug('Remove cookie that is not an array');
+				continue;
+			}
+			if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
+				if (strtotime($cookie['expires']) > time()) {
+					$this->cookies[] = $cookie;
+				} else {
+					$this->debug('Remove expired cookie ' . $cookie['name']);
+				}
+			} else {
+				$this->cookies[] = $cookie;
+			}
+		}
+		$this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
+		return true;
+	}
+
+	/**
+	 * updates the current cookies with a new set
+	 *
+	 * @param	array $cookies new cookies with which to update current ones
+	 * @return	always return true
+	 * @access	private
+	 */
+	function UpdateCookies($cookies) {
+		if (sizeof($this->cookies) == 0) {
+			// no existing cookies: take whatever is new
+			if (sizeof($cookies) > 0) {
+				$this->debug('Setting new cookie(s)');
+				$this->cookies = $cookies;
+			}
+			return true;
+		}
+		if (sizeof($cookies) == 0) {
+			// no new cookies: keep what we've got
+			return true;
+		}
+		// merge
+		foreach ($cookies as $newCookie) {
+			if (!is_array($newCookie)) {
+				continue;
+			}
+			if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
+				continue;
+			}
+			$newName = $newCookie['name'];
+
+			$found = false;
+			for ($i = 0; $i < count($this->cookies); $i++) {
+				$cookie = $this->cookies[$i];
+				if (!is_array($cookie)) {
+					continue;
+				}
+				if (!isset($cookie['name'])) {
+					continue;
+				}
+				if ($newName != $cookie['name']) {
+					continue;
+				}
+				$newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
+				$domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
+				if ($newDomain != $domain) {
+					continue;
+				}
+				$newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
+				$path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
+				if ($newPath != $path) {
+					continue;
+				}
+				$this->cookies[$i] = $newCookie;
+				$found = true;
+				$this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
+				break;
+			}
+			if (! $found) {
+				$this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
+				$this->cookies[] = $newCookie;
+			}
+		}
+		return true;
+	}
+}
+?>
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.wsdl.php b/htdocs/oscommerce_ws/ws_server/lib/class.wsdl.php
index afcd7a3eb6a692e253cd697f2af5ca77f35ba8c6..4abce0c32d744c5732f50cc6ba9a402112074abf 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.wsdl.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.wsdl.php
@@ -1,1727 +1,1727 @@
-<?php
-
-
-
-
-/**
-* parses a WSDL file, allows access to it's data, other utility methods
-* 
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access public 
-*/
-class wsdl extends nusoap_base {
-	// URL or filename of the root of this WSDL
-    var $wsdl; 
-    // define internal arrays of bindings, ports, operations, messages, etc.
-    var $schemas = array();
-    var $currentSchema;
-    var $message = array();
-    var $complexTypes = array();
-    var $messages = array();
-    var $currentMessage;
-    var $currentOperation;
-    var $portTypes = array();
-    var $currentPortType;
-    var $bindings = array();
-    var $currentBinding;
-    var $ports = array();
-    var $currentPort;
-    var $opData = array();
-    var $status = '';
-    var $documentation = false;
-    var $endpoint = ''; 
-    // array of wsdl docs to import
-    var $import = array(); 
-    // parser vars
-    var $parser;
-    var $position = 0;
-    var $depth = 0;
-    var $depth_array = array();
-	// for getting wsdl
-	var $proxyhost = '';
-    var $proxyport = '';
-	var $proxyusername = '';
-	var $proxypassword = '';
-	var $timeout = 0;
-	var $response_timeout = 30;
-
-    /**
-     * constructor
-     * 
-     * @param string $wsdl WSDL document URL
-	 * @param string $proxyhost
-	 * @param string $proxyport
-	 * @param string $proxyusername
-	 * @param string $proxypassword
-	 * @param integer $timeout set the connection timeout
-	 * @param integer $response_timeout set the response timeout
-     * @access public 
-     */
-    function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){
-		parent::nusoap_base();
-        $this->wsdl = $wsdl;
-        $this->proxyhost = $proxyhost;
-        $this->proxyport = $proxyport;
-		$this->proxyusername = $proxyusername;
-		$this->proxypassword = $proxypassword;
-		$this->timeout = $timeout;
-		$this->response_timeout = $response_timeout;
-        
-        // parse wsdl file
-        if ($wsdl != "") {
-            $this->debug('initial wsdl URL: ' . $wsdl);
-            $this->parseWSDL($wsdl);
-        }
-        // imports
-        // TODO: handle imports more properly, grabbing them in-line and nesting them
-        	$imported_urls = array();
-        	$imported = 1;
-        	while ($imported > 0) {
-        		$imported = 0;
-        		// Schema imports
-        		foreach ($this->schemas as $ns => $list) {
-        			foreach ($list as $xs) {
-						$wsdlparts = parse_url($this->wsdl);	// this is bogusly simple!
-			            foreach ($xs->imports as $ns2 => $list2) {
-			                for ($ii = 0; $ii < count($list2); $ii++) {
-			                	if (! $list2[$ii]['loaded']) {
-			                		$this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
-			                		$url = $list2[$ii]['location'];
-									if ($url != '') {
-										$urlparts = parse_url($url);
-										if (!isset($urlparts['host'])) {
-											$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
-													substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
-										}
-										if (! in_array($url, $imported_urls)) {
-						                	$this->parseWSDL($url);
-					                		$imported++;
-					                		$imported_urls[] = $url;
-					                	}
-									} else {
-										$this->debug("Unexpected scenario: empty URL for unloaded import");
-									}
-								}
-							}
-			            } 
-        			}
-        		}
-        		// WSDL imports
-				$wsdlparts = parse_url($this->wsdl);	// this is bogusly simple!
-	            foreach ($this->import as $ns => $list) {
-	                for ($ii = 0; $ii < count($list); $ii++) {
-	                	if (! $list[$ii]['loaded']) {
-	                		$this->import[$ns][$ii]['loaded'] = true;
-	                		$url = $list[$ii]['location'];
-							if ($url != '') {
-								$urlparts = parse_url($url);
-								if (!isset($urlparts['host'])) {
-									$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
-											substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
-								}
-								if (! in_array($url, $imported_urls)) {
-				                	$this->parseWSDL($url);
-			                		$imported++;
-			                		$imported_urls[] = $url;
-			                	}
-							} else {
-								$this->debug("Unexpected scenario: empty URL for unloaded import");
-							}
-						}
-					}
-	            } 
-			}
-        // add new data to operation data
-        foreach($this->bindings as $binding => $bindingData) {
-            if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
-                foreach($bindingData['operations'] as $operation => $data) {
-                    $this->debug('post-parse data gathering for ' . $operation);
-                    $this->bindings[$binding]['operations'][$operation]['input'] = 
-						isset($this->bindings[$binding]['operations'][$operation]['input']) ? 
-						array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
-						$this->portTypes[ $bindingData['portType'] ][$operation]['input'];
-                    $this->bindings[$binding]['operations'][$operation]['output'] = 
-						isset($this->bindings[$binding]['operations'][$operation]['output']) ?
-						array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
-						$this->portTypes[ $bindingData['portType'] ][$operation]['output'];
-                    if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
-						$this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
-					}
-					if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
-                   		$this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
-                    }
-					if (isset($bindingData['style'])) {
-                        $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
-                    }
-                    $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
-                    $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
-                    $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
-                } 
-            } 
-        }
-    }
-
-    /**
-     * parses the wsdl document
-     * 
-     * @param string $wsdl path or URL
-     * @access private 
-     */
-    function parseWSDL($wsdl = '')
-    {
-        if ($wsdl == '') {
-            $this->debug('no wsdl passed to parseWSDL()!!');
-            $this->setError('no wsdl passed to parseWSDL()!!');
-            return false;
-        }
-        
-        // parse $wsdl for url format
-        $wsdl_props = parse_url($wsdl);
-
-        if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
-            $this->debug('getting WSDL http(s) URL ' . $wsdl);
-        	// get wsdl
-	        $tr = new soap_transport_http($wsdl);
-			$tr->request_method = 'GET';
-			$tr->useSOAPAction = false;
-			if($this->proxyhost && $this->proxyport){
-				$tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
-			}
-			$tr->setEncoding('gzip, deflate');
-			$wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
-			//$this->debug("WSDL request\n" . $tr->outgoing_payload);
-			//$this->debug("WSDL response\n" . $tr->incoming_payload);
-			$this->appendDebug($tr->getDebug());
-			// catch errors
-			if($err = $tr->getError() ){
-				$errstr = 'HTTP ERROR: '.$err;
-				$this->debug($errstr);
-	            $this->setError($errstr);
-				unset($tr);
-	            return false;
-			}
-			unset($tr);
-			$this->debug("got WSDL URL");
-        } else {
-            // $wsdl is not http(s), so treat it as a file URL or plain file path
-        	if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
-        		$path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
-        	} else {
-        		$path = $wsdl;
-        	}
-            $this->debug('getting WSDL file ' . $path);
-            if ($fp = @fopen($path, 'r')) {
-                $wsdl_string = '';
-                while ($data = fread($fp, 32768)) {
-                    $wsdl_string .= $data;
-                } 
-                fclose($fp);
-            } else {
-            	$errstr = "Bad path to WSDL file $path";
-            	$this->debug($errstr);
-                $this->setError($errstr);
-                return false;
-            } 
-        }
-        $this->debug('Parse WSDL');
-        // end new code added
-        // Create an XML parser.
-        $this->parser = xml_parser_create(); 
-        // Set the options for parsing the XML data.
-        // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
-        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 
-        // Set the object for the parser.
-        xml_set_object($this->parser, $this); 
-        // Set the element handlers for the parser.
-        xml_set_element_handler($this->parser, 'start_element', 'end_element');
-        xml_set_character_data_handler($this->parser, 'character_data');
-        // Parse the XML file.
-        if (!xml_parse($this->parser, $wsdl_string, true)) {
-            // Display an error message.
-            $errstr = sprintf(
-				'XML error parsing WSDL from %s on line %d: %s',
-				$wsdl,
-                xml_get_current_line_number($this->parser),
-                xml_error_string(xml_get_error_code($this->parser))
-                );
-            $this->debug($errstr);
-			$this->debug("XML payload:\n" . $wsdl_string);
-            $this->setError($errstr);
-            return false;
-        } 
-		// free the parser
-        xml_parser_free($this->parser);
-        $this->debug('Parsing WSDL done');
-		// catch wsdl parse errors
-		if($this->getError()){
-			return false;
-		}
-        return true;
-    } 
-
-    /**
-     * start-element handler
-     * 
-     * @param string $parser XML parser object
-     * @param string $name element name
-     * @param string $attrs associative array of attributes
-     * @access private 
-     */
-    function start_element($parser, $name, $attrs)
-    {
-        if ($this->status == 'schema') {
-            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
-            $this->appendDebug($this->currentSchema->getDebug());
-            $this->currentSchema->clearDebug();
-        } elseif (ereg('schema$', $name)) {
-        	$this->debug('Parsing WSDL schema');
-            // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
-            $this->status = 'schema';
-            $this->currentSchema = new xmlschema('', '', $this->namespaces);
-            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
-            $this->appendDebug($this->currentSchema->getDebug());
-            $this->currentSchema->clearDebug();
-        } else {
-            // position in the total number of elements, starting from 0
-            $pos = $this->position++;
-            $depth = $this->depth++; 
-            // set self as current value for this depth
-            $this->depth_array[$depth] = $pos;
-            $this->message[$pos] = array('cdata' => ''); 
-            // process attributes
-            if (count($attrs) > 0) {
-				// register namespace declarations
-                foreach($attrs as $k => $v) {
-                    if (ereg("^xmlns", $k)) {
-                        if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
-                            $this->namespaces[$ns_prefix] = $v;
-                        } else {
-                            $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
-                        } 
-                        if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
-                            $this->XMLSchemaVersion = $v;
-                            $this->namespaces['xsi'] = $v . '-instance';
-                        } 
-                    }
-                }
-                // expand each attribute prefix to its namespace
-                foreach($attrs as $k => $v) {
-                    $k = strpos($k, ':') ? $this->expandQname($k) : $k;
-                    if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
-                        $v = strpos($v, ':') ? $this->expandQname($v) : $v;
-                    } 
-                    $eAttrs[$k] = $v;
-                } 
-                $attrs = $eAttrs;
-            } else {
-                $attrs = array();
-            } 
-            // get element prefix, namespace and name
-            if (ereg(':', $name)) {
-                // get ns prefix
-                $prefix = substr($name, 0, strpos($name, ':')); 
-                // get ns
-                $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; 
-                // get unqualified name
-                $name = substr(strstr($name, ':'), 1);
-            } 
-			// process attributes, expanding any prefixes to namespaces
-            // find status, register data
-            switch ($this->status) {
-                case 'message':
-                    if ($name == 'part') {
-			            if (isset($attrs['type'])) {
-		                    $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
-		                    $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
-            			} 
-			            if (isset($attrs['element'])) {
-		                    $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
-			                $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'];
-			            } 
-        			} 
-        			break;
-			    case 'portType':
-			        switch ($name) {
-			            case 'operation':
-			                $this->currentPortOperation = $attrs['name'];
-			                $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
-			                if (isset($attrs['parameterOrder'])) {
-			                	$this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
-			        		} 
-			        		break;
-					    case 'documentation':
-					        $this->documentation = true;
-					        break; 
-					    // merge input/output data
-					    default:
-					        $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
-					        $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
-					        break;
-					} 
-			    	break;
-				case 'binding':
-				    switch ($name) {
-				        case 'binding': 
-				            // get ns prefix
-				            if (isset($attrs['style'])) {
-				            $this->bindings[$this->currentBinding]['prefix'] = $prefix;
-					    	} 
-					    	$this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
-					    	break;
-						case 'header':
-						    $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
-						    break;
-						case 'operation':
-						    if (isset($attrs['soapAction'])) {
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
-						    } 
-						    if (isset($attrs['style'])) {
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
-						    } 
-						    if (isset($attrs['name'])) {
-						        $this->currentOperation = $attrs['name'];
-						        $this->debug("current binding operation: $this->currentOperation");
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
-						    } 
-						    break;
-						case 'input':
-						    $this->opStatus = 'input';
-						    break;
-						case 'output':
-						    $this->opStatus = 'output';
-						    break;
-						case 'body':
-						    if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
-						    } else {
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
-						    } 
-						    break;
-					} 
-					break;
-				case 'service':
-					switch ($name) {
-					    case 'port':
-					        $this->currentPort = $attrs['name'];
-					        $this->debug('current port: ' . $this->currentPort);
-					        $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
-					
-					        break;
-					    case 'address':
-					        $this->ports[$this->currentPort]['location'] = $attrs['location'];
-					        $this->ports[$this->currentPort]['bindingType'] = $namespace;
-					        $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
-					        $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
-					        break;
-					} 
-					break;
-			} 
-		// set status
-		switch ($name) {
-			case 'import':
-			    if (isset($attrs['location'])) {
-                    $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
-                    $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
-				} else {
-                    $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
-					if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
-						$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
-					}
-                    $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
-				}
-				break;
-			//wait for schema
-			//case 'types':
-			//	$this->status = 'schema';
-			//	break;
-			case 'message':
-				$this->status = 'message';
-				$this->messages[$attrs['name']] = array();
-				$this->currentMessage = $attrs['name'];
-				break;
-			case 'portType':
-				$this->status = 'portType';
-				$this->portTypes[$attrs['name']] = array();
-				$this->currentPortType = $attrs['name'];
-				break;
-			case "binding":
-				if (isset($attrs['name'])) {
-				// get binding name
-					if (strpos($attrs['name'], ':')) {
-			    		$this->currentBinding = $this->getLocalPart($attrs['name']);
-					} else {
-			    		$this->currentBinding = $attrs['name'];
-					} 
-					$this->status = 'binding';
-					$this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
-					$this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
-				} 
-				break;
-			case 'service':
-				$this->serviceName = $attrs['name'];
-				$this->status = 'service';
-				$this->debug('current service: ' . $this->serviceName);
-				break;
-			case 'definitions':
-				foreach ($attrs as $name => $value) {
-					$this->wsdl_info[$name] = $value;
-				} 
-				break;
-			} 
-		} 
-	} 
-
-	/**
-	* end-element handler
-	* 
-	* @param string $parser XML parser object
-	* @param string $name element name
-	* @access private 
-	*/
-	function end_element($parser, $name){ 
-		// unset schema status
-		if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) {
-			$this->status = "";
-            $this->appendDebug($this->currentSchema->getDebug());
-            $this->currentSchema->clearDebug();
-			$this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
-        	$this->debug('Parsing WSDL schema done');
-		} 
-		if ($this->status == 'schema') {
-			$this->currentSchema->schemaEndElement($parser, $name);
-		} else {
-			// bring depth down a notch
-			$this->depth--;
-		} 
-		// end documentation
-		if ($this->documentation) {
-			//TODO: track the node to which documentation should be assigned; it can be a part, message, etc.
-			//$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
-			$this->documentation = false;
-		} 
-	} 
-
-	/**
-	 * element content handler
-	 * 
-	 * @param string $parser XML parser object
-	 * @param string $data element content
-	 * @access private 
-	 */
-	function character_data($parser, $data)
-	{
-		$pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
-		if (isset($this->message[$pos]['cdata'])) {
-			$this->message[$pos]['cdata'] .= $data;
-		} 
-		if ($this->documentation) {
-			$this->documentation .= $data;
-		} 
-	} 
-	
-	function getBindingData($binding)
-	{
-		if (is_array($this->bindings[$binding])) {
-			return $this->bindings[$binding];
-		} 
-	}
-	
-	/**
-	 * returns an assoc array of operation names => operation data
-	 * 
-	 * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported)
-	 * @return array 
-	 * @access public 
-	 */
-	function getOperations($bindingType = 'soap')
-	{
-		$ops = array();
-		if ($bindingType == 'soap') {
-			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
-		}
-		// loop thru ports
-		foreach($this->ports as $port => $portData) {
-			// binding type of port matches parameter
-			if ($portData['bindingType'] == $bindingType) {
-				//$this->debug("getOperations for port $port");
-				//$this->debug("port data: " . $this->varDump($portData));
-				//$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));
-				// merge bindings
-				if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
-					$ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
-				}
-			}
-		} 
-		return $ops;
-	} 
-	
-	/**
-	 * returns an associative array of data necessary for calling an operation
-	 * 
-	 * @param string $operation , name of operation
-	 * @param string $bindingType , type of binding eg: soap
-	 * @return array 
-	 * @access public 
-	 */
-	function getOperationData($operation, $bindingType = 'soap')
-	{
-		if ($bindingType == 'soap') {
-			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
-		}
-		// loop thru ports
-		foreach($this->ports as $port => $portData) {
-			// binding type of port matches parameter
-			if ($portData['bindingType'] == $bindingType) {
-				// get binding
-				//foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
-				foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
-					// note that we could/should also check the namespace here
-					if ($operation == $bOperation) {
-						$opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
-					    return $opData;
-					} 
-				} 
-			}
-		} 
-	}
-	
-	/**
-	 * returns an associative array of data necessary for calling an operation
-	 * 
-	 * @param string $soapAction soapAction for operation
-	 * @param string $bindingType type of binding eg: soap
-	 * @return array 
-	 * @access public 
-	 */
-	function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
-		if ($bindingType == 'soap') {
-			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
-		}
-		// loop thru ports
-		foreach($this->ports as $port => $portData) {
-			// binding type of port matches parameter
-			if ($portData['bindingType'] == $bindingType) {
-				// loop through operations for the binding
-				foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
-					if ($opData['soapAction'] == $soapAction) {
-					    return $opData;
-					} 
-				} 
-			}
-		} 
-	}
-	
-	/**
-    * returns an array of information about a given type
-    * returns false if no type exists by the given name
-    *
-	*	 typeDef = array(
-	*	 'elements' => array(), // refs to elements array
-	*	'restrictionBase' => '',
-	*	'phpType' => '',
-	*	'order' => '(sequence|all)',
-	*	'attrs' => array() // refs to attributes array
-	*	)
-    *
-    * @param $type string the type
-    * @param $ns string namespace (not prefix) of the type
-    * @return mixed
-    * @access public
-    * @see xmlschema
-    */
-	function getTypeDef($type, $ns) {
-		$this->debug("in getTypeDef: type=$type, ns=$ns");
-		if ((! $ns) && isset($this->namespaces['tns'])) {
-			$ns = $this->namespaces['tns'];
-			$this->debug("in getTypeDef: type namespace forced to $ns");
-		}
-		if (isset($this->schemas[$ns])) {
-			$this->debug("in getTypeDef: have schema for namespace $ns");
-			for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
-				$xs = &$this->schemas[$ns][$i];
-				$t = $xs->getTypeDef($type);
-				$this->appendDebug($xs->getDebug());
-				$xs->clearDebug();
-				if ($t) {
-					if (!isset($t['phpType'])) {
-						// get info for type to tack onto the element
-						$uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
-						$ns = substr($t['type'], 0, strrpos($t['type'], ':'));
-						$etype = $this->getTypeDef($uqType, $ns);
-						if ($etype) {
-							$this->debug("found type for [element] $type:");
-							$this->debug($this->varDump($etype));
-							if (isset($etype['phpType'])) {
-								$t['phpType'] = $etype['phpType'];
-							}
-							if (isset($etype['elements'])) {
-								$t['elements'] = $etype['elements'];
-							}
-							if (isset($etype['attrs'])) {
-								$t['attrs'] = $etype['attrs'];
-							}
-						}
-					}
-					return $t;
-				}
-			}
-		} else {
-			$this->debug("in getTypeDef: do not have schema for namespace $ns");
-		}
-		return false;
-	}
-
-    /**
-    * prints html description of services
-    *
-    * @access private
-    */
-    function webDescription(){
-    	global $HTTP_SERVER_VARS;
-
-		if (isset($_SERVER)) {
-			$PHP_SELF = $_SERVER['PHP_SELF'];
-		} elseif (isset($HTTP_SERVER_VARS)) {
-			$PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
-		} else {
-			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
-		}
-
-		$b = '
-		<html><head><title>NuSOAP: '.$this->serviceName.'</title>
-		<style type="text/css">
-		    body    { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
-		    p       { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
-		    pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
-		    ul      { margin-top: 10px; margin-left: 20px; }
-		    li      { list-style-type: none; margin-top: 10px; color: #000000; }
-		    .content{
-			margin-left: 0px; padding-bottom: 2em; }
-		    .nav {
-			padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
-			margin-top: 10px; margin-left: 0px; color: #000000;
-			background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
-		    .title {
-			font-family: arial; font-size: 26px; color: #ffffff;
-			background-color: #999999; width: 105%; margin-left: 0px;
-			padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
-		    .hidden {
-			position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
-			font-family: arial; overflow: hidden; width: 600;
-			padding: 20px; font-size: 10px; background-color: #999999;
-			layer-background-color:#FFFFFF; }
-		    a,a:active  { color: charcoal; font-weight: bold; }
-		    a:visited   { color: #666666; font-weight: bold; }
-		    a:hover     { color: cc3300; font-weight: bold; }
-		</style>
-		<script language="JavaScript" type="text/javascript">
-		<!--
-		// POP-UP CAPTIONS...
-		function lib_bwcheck(){ //Browsercheck (needed)
-		    this.ver=navigator.appVersion
-		    this.agent=navigator.userAgent
-		    this.dom=document.getElementById?1:0
-		    this.opera5=this.agent.indexOf("Opera 5")>-1
-		    this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
-		    this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
-		    this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
-		    this.ie=this.ie4||this.ie5||this.ie6
-		    this.mac=this.agent.indexOf("Mac")>-1
-		    this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
-		    this.ns4=(document.layers && !this.dom)?1:0;
-		    this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
-		    return this
-		}
-		var bw = new lib_bwcheck()
-		//Makes crossbrowser object.
-		function makeObj(obj){
-		    this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
-		    if(!this.evnt) return false
-		    this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
-		    this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
-		    this.writeIt=b_writeIt;
-		    return this
-		}
-		// A unit of measure that will be added when setting the position of a layer.
-		//var px = bw.ns4||window.opera?"":"px";
-		function b_writeIt(text){
-		    if (bw.ns4){this.wref.write(text);this.wref.close()}
-		    else this.wref.innerHTML = text
-		}
-		//Shows the messages
-		var oDesc;
-		function popup(divid){
-		    if(oDesc = new makeObj(divid)){
-			oDesc.css.visibility = "visible"
-		    }
-		}
-		function popout(){ // Hides message
-		    if(oDesc) oDesc.css.visibility = "hidden"
-		}
-		//-->
-		</script>
-		</head>
-		<body>
-		<div class=content>
-			<br><br>
-			<div class=title>'.$this->serviceName.'</div>
-			<div class=nav>
-				<p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
-				Click on an operation name to view it&apos;s details.</p>
-				<ul>';
-				foreach($this->getOperations() as $op => $data){
-				    $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
-				    // create hidden div
-				    $b .= "<div id='$op' class='hidden'>
-				    <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
-				    foreach($data as $donnie => $marie){ // loop through opdata
-						if($donnie == 'input' || $donnie == 'output'){ // show input/output data
-						    $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
-						    foreach($marie as $captain => $tenille){ // loop through data
-								if($captain == 'parts'){ // loop thru parts
-								    $b .= "&nbsp;&nbsp;$captain:<br>";
-					                //if(is_array($tenille)){
-								    	foreach($tenille as $joanie => $chachi){
-											$b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
-								    	}
-					        		//}
-								} else {
-								    $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
-								}
-						    }
-						} else {
-						    $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
-						}
-				    }
-					$b .= '</div>';
-				}
-				$b .= '
-				<ul>
-			</div>
-		</div></body></html>';
-		return $b;
-    }
-
-	/**
-	* serialize the parsed wsdl
-	*
-	* @param mixed $debug whether to put debug=1 in endpoint URL
-	* @return string serialization of WSDL
-	* @access public 
-	*/
-	function serialize($debug = 0)
-	{
-		$xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
-		$xml .= "\n<definitions";
-		foreach($this->namespaces as $k => $v) {
-			$xml .= " xmlns:$k=\"$v\"";
-		} 
-		// 10.9.02 - add poulter fix for wsdl and tns declarations
-		if (isset($this->namespaces['wsdl'])) {
-			$xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
-		} 
-		if (isset($this->namespaces['tns'])) {
-			$xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
-		} 
-		$xml .= '>'; 
-		// imports
-		if (sizeof($this->import) > 0) {
-			foreach($this->import as $ns => $list) {
-				foreach ($list as $ii) {
-					if ($ii['location'] != '') {
-						$xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
-					} else {
-						$xml .= '<import namespace="' . $ns . '" />';
-					}
-				}
-			} 
-		} 
-		// types
-		if (count($this->schemas)>=1) {
-			$xml .= "\n<types>";
-			foreach ($this->schemas as $ns => $list) {
-				foreach ($list as $xs) {
-					$xml .= $xs->serializeSchema();
-				}
-			}
-			$xml .= '</types>';
-		} 
-		// messages
-		if (count($this->messages) >= 1) {
-			foreach($this->messages as $msgName => $msgParts) {
-				$xml .= "\n<message name=\"" . $msgName . '">';
-				if(is_array($msgParts)){
-					foreach($msgParts as $partName => $partType) {
-						// print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';
-						if (strpos($partType, ':')) {
-						    $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
-						} elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
-						    // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';
-						    $typePrefix = 'xsd';
-						} else {
-						    foreach($this->typemap as $ns => $types) {
-						        if (isset($types[$partType])) {
-						            $typePrefix = $this->getPrefixFromNamespace($ns);
-						        } 
-						    } 
-						    if (!isset($typePrefix)) {
-						        die("$partType has no namespace!");
-						    } 
-						}
-						$ns = $this->getNamespaceFromPrefix($typePrefix);
-						$typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns);
-						if ($typeDef['typeClass'] == 'element') {
-							$elementortype = 'element';
-						} else {
-							$elementortype = 'type';
-						}
-						$xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />';
-					}
-				}
-				$xml .= '</message>';
-			} 
-		} 
-		// bindings & porttypes
-		if (count($this->bindings) >= 1) {
-			$binding_xml = '';
-			$portType_xml = '';
-			foreach($this->bindings as $bindingName => $attrs) {
-				$binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
-				$binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
-				$portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
-				foreach($attrs['operations'] as $opName => $opParts) {
-					$binding_xml .= '<operation name="' . $opName . '">';
-					$binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
-					if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
-						$enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
-					} else {
-						$enc_style = '';
-					}
-					$binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
-					if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
-						$enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
-					} else {
-						$enc_style = '';
-					}
-					$binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
-					$binding_xml .= '</operation>';
-					$portType_xml .= '<operation name="' . $opParts['name'] . '"';
-					if (isset($opParts['parameterOrder'])) {
-					    $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
-					} 
-					$portType_xml .= '>';
-					if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
-						$portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
-					}
-					$portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>';
-					$portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>';
-					$portType_xml .= '</operation>';
-				} 
-				$portType_xml .= '</portType>';
-				$binding_xml .= '</binding>';
-			} 
-			$xml .= $portType_xml . $binding_xml;
-		} 
-		// services
-		$xml .= "\n<service name=\"" . $this->serviceName . '">';
-		if (count($this->ports) >= 1) {
-			foreach($this->ports as $pName => $attrs) {
-				$xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
-				$xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
-				$xml .= '</port>';
-			} 
-		} 
-		$xml .= '</service>';
-		return $xml . "\n</definitions>";
-	} 
-	
-	/**
-	 * serialize PHP values according to a WSDL message definition
-	 *
-	 * TODO
-	 * - multi-ref serialization
-	 * - validate PHP values against type definitions, return errors if invalid
-	 * 
-	 * @param string $operation operation name
-	 * @param string $direction (input|output)
-	 * @param mixed $parameters parameter value(s)
-	 * @return mixed parameters serialized as XML or false on error (e.g. operation not found)
-	 * @access public
-	 */
-	function serializeRPCParameters($operation, $direction, $parameters)
-	{
-		$this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
-		$this->appendDebug('parameters=' . $this->varDump($parameters));
-		
-		if ($direction != 'input' && $direction != 'output') {
-			$this->debug('The value of the \$direction argument needs to be either "input" or "output"');
-			$this->setError('The value of the \$direction argument needs to be either "input" or "output"');
-			return false;
-		} 
-		if (!$opData = $this->getOperationData($operation)) {
-			$this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
-			$this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
-			return false;
-		}
-		$this->debug('opData:');
-		$this->appendDebug($this->varDump($opData));
-
-		// Get encoding style for output and set to current
-		$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-		if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
-			$encodingStyle = $opData['output']['encodingStyle'];
-			$enc_style = $encodingStyle;
-		}
-
-		// set input params
-		$xml = '';
-		if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
-			
-			$use = $opData[$direction]['use'];
-			$this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize');
-			if (is_array($parameters)) {
-				$parametersArrayType = $this->isArraySimpleOrStruct($parameters);
-				$this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize');
-				foreach($opData[$direction]['parts'] as $name => $type) {
-					$this->debug('serializing part "'.$name.'" of type "'.$type.'"');
-					// Track encoding style
-					if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
-						$encodingStyle = $opData[$direction]['encodingStyle'];			
-						$enc_style = $encodingStyle;
-					} else {
-						$enc_style = false;
-					}
-					// NOTE: add error handling here
-					// if serializeType returns false, then catch global error and fault
-					if ($parametersArrayType == 'arraySimple') {
-						$p = array_shift($parameters);
-						$this->debug('calling serializeType w/indexed param');
-						$xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
-					} elseif (isset($parameters[$name])) {
-						$this->debug('calling serializeType w/named param');
-						$xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
-					} else {
-						// TODO: only send nillable
-						$this->debug('calling serializeType w/null param');
-						$xml .= $this->serializeType($name, $type, null, $use, $enc_style);
-					}
-				}
-			} else {
-				$this->debug('no parameters passed.');
-			}
-		}
-		$this->debug("serializeRPCParameters returning: $xml");
-		return $xml;
-	} 
-	
-	/**
-	 * serialize a PHP value according to a WSDL message definition
-	 * 
-	 * TODO
-	 * - multi-ref serialization
-	 * - validate PHP values against type definitions, return errors if invalid
-	 * 
-	 * @param string $ type name
-	 * @param mixed $ param value
-	 * @return mixed new param or false if initial value didn't validate
-	 * @access public
-	 * @deprecated
-	 */
-	function serializeParameters($operation, $direction, $parameters)
-	{
-		$this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
-		$this->appendDebug('parameters=' . $this->varDump($parameters));
-		
-		if ($direction != 'input' && $direction != 'output') {
-			$this->debug('The value of the \$direction argument needs to be either "input" or "output"');
-			$this->setError('The value of the \$direction argument needs to be either "input" or "output"');
-			return false;
-		} 
-		if (!$opData = $this->getOperationData($operation)) {
-			$this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
-			$this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
-			return false;
-		}
-		$this->debug('opData:');
-		$this->appendDebug($this->varDump($opData));
-		
-		// Get encoding style for output and set to current
-		$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-		if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
-			$encodingStyle = $opData['output']['encodingStyle'];
-			$enc_style = $encodingStyle;
-		}
-		
-		// set input params
-		$xml = '';
-		if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
-			
-			$use = $opData[$direction]['use'];
-			$this->debug("use=$use");
-			$this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
-			if (is_array($parameters)) {
-				$parametersArrayType = $this->isArraySimpleOrStruct($parameters);
-				$this->debug('have ' . $parametersArrayType . ' parameters');
-				foreach($opData[$direction]['parts'] as $name => $type) {
-					$this->debug('serializing part "'.$name.'" of type "'.$type.'"');
-					// Track encoding style
-					if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
-						$encodingStyle = $opData[$direction]['encodingStyle'];			
-						$enc_style = $encodingStyle;
-					} else {
-						$enc_style = false;
-					}
-					// NOTE: add error handling here
-					// if serializeType returns false, then catch global error and fault
-					if ($parametersArrayType == 'arraySimple') {
-						$p = array_shift($parameters);
-						$this->debug('calling serializeType w/indexed param');
-						$xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
-					} elseif (isset($parameters[$name])) {
-						$this->debug('calling serializeType w/named param');
-						$xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
-					} else {
-						// TODO: only send nillable
-						$this->debug('calling serializeType w/null param');
-						$xml .= $this->serializeType($name, $type, null, $use, $enc_style);
-					}
-				}
-			} else {
-				$this->debug('no parameters passed.');
-			}
-		}
-		$this->debug("serializeParameters returning: $xml");
-		return $xml;
-	} 
-	
-	/**
-	 * serializes a PHP value according a given type definition
-	 * 
-	 * @param string $name name of value (part or element)
-	 * @param string $type XML schema type of value (type or element)
-	 * @param mixed $value a native PHP value (parameter value)
-	 * @param string $use use for part (encoded|literal)
-	 * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
-	 * @param boolean $unqualified a kludge for what should be XML namespace form handling
-	 * @return string value serialized as an XML string
-	 * @access private
-	 */
-	function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
-	{
-		$this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
-		$this->appendDebug("value=" . $this->varDump($value));
-		if($use == 'encoded' && $encodingStyle) {
-			$encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
-		}
-
-		// if a soapval has been supplied, let its type override the WSDL
-    	if (is_object($value) && get_class($value) == 'soapval') {
-    		if ($value->type_ns) {
-    			$type = $value->type_ns . ':' . $value->type;
-		    	$forceType = true;
-		    	$this->debug("in serializeType: soapval overrides type to $type");
-    		} elseif ($value->type) {
-	    		$type = $value->type;
-		    	$forceType = true;
-		    	$this->debug("in serializeType: soapval overrides type to $type");
-	    	} else {
-	    		$forceType = false;
-		    	$this->debug("in serializeType: soapval does not override type");
-	    	}
-	    	$attrs = $value->attributes;
-	    	$value = $value->value;
-	    	$this->debug("in serializeType: soapval overrides value to $value");
-	    	if ($attrs) {
-	    		if (!is_array($value)) {
-	    			$value['!'] = $value;
-	    		}
-	    		foreach ($attrs as $n => $v) {
-	    			$value['!' . $n] = $v;
-	    		}
-		    	$this->debug("in serializeType: soapval provides attributes");
-		    }
-        } else {
-        	$forceType = false;
-        }
-
-		$xml = '';
-		if (strpos($type, ':')) {
-			$uqType = substr($type, strrpos($type, ':') + 1);
-			$ns = substr($type, 0, strrpos($type, ':'));
-			$this->debug("in serializeType: got a prefixed type: $uqType, $ns");
-			if ($this->getNamespaceFromPrefix($ns)) {
-				$ns = $this->getNamespaceFromPrefix($ns);
-				$this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
-			}
-
-			if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
-				$this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
-				if ($unqualified  && $use == 'literal') {
-					$elementNS = " xmlns=\"\"";
-				} else {
-					$elementNS = '';
-				}
-				if (is_null($value)) {
-					if ($use == 'literal') {
-						// TODO: depends on minOccurs
-						$xml = "<$name$elementNS/>";
-					} else {
-						// TODO: depends on nillable, which should be checked before calling this method
-						$xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
-					}
-					$this->debug("in serializeType: returning: $xml");
-					return $xml;
-				}
-		    	if ($uqType == 'boolean') {
-		    		if ((is_string($value) && $value == 'false') || (! $value)) {
-						$value = 'false';
-					} else {
-						$value = 'true';
-					}
-				} 
-				if ($uqType == 'string' && gettype($value) == 'string') {
-					$value = $this->expandEntities($value);
-				}
-				if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
-					$value = sprintf("%.0lf", $value);
-				}
-				// it's a scalar
-				// TODO: what about null/nil values?
-				// check type isn't a custom type extending xmlschema namespace
-				if (!$this->getTypeDef($uqType, $ns)) {
-					if ($use == 'literal') {
-						if ($forceType) {
-							$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
-						} else {
-							$xml = "<$name$elementNS>$value</$name>";
-						}
-					} else {
-						$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
-					}
-					$this->debug("in serializeType: returning: $xml");
-					return $xml;
-				}
-				$this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
-			} else if ($ns == 'http://xml.apache.org/xml-soap') {
-				$this->debug('in serializeType: appears to be Apache SOAP type');
-				if ($uqType == 'Map') {
-					$tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
-					if (! $tt_prefix) {
-						$this->debug('in serializeType: Add namespace for Apache SOAP type');
-						$tt_prefix = 'ns' . rand(1000, 9999);
-						$this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
-						// force this to be added to usedNamespaces
-						$tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
-					}
-					$contents = '';
-					foreach($value as $k => $v) {
-						$this->debug("serializing map element: key $k, value $v");
-						$contents .= '<item>';
-						$contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
-						$contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
-						$contents .= '</item>';
-					}
-					if ($use == 'literal') {
-						if ($forceType) {
-							$xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
-						} else {
-							$xml = "<$name>$contents</$name>";
-						}
-					} else {
-						$xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
-					}
-					$this->debug("in serializeType: returning: $xml");
-					return $xml;
-				}
-				$this->debug('in serializeType: Apache SOAP type, but only support Map');
-			}
-		} else {
-			// TODO: should the type be compared to types in XSD, and the namespace
-			// set to XSD if the type matches?
-			$this->debug("in serializeType: No namespace for type $type");
-			$ns = '';
-			$uqType = $type;
-		}
-		if(!$typeDef = $this->getTypeDef($uqType, $ns)){
-			$this->setError("$type ($uqType) is not a supported type.");
-			$this->debug("in serializeType: $type ($uqType) is not a supported type.");
-			return false;
-		} else {
-			$this->debug("in serializeType: found typeDef");
-			$this->appendDebug('typeDef=' . $this->varDump($typeDef));
-		}
-		$phpType = $typeDef['phpType'];
-		$this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); 
-		// if php type == struct, map value to the <all> element names
-		if ($phpType == 'struct') {
-			if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
-				$elementName = $uqType;
-				if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
-					$elementNS = " xmlns=\"$ns\"";
-				} else {
-					$elementNS = " xmlns=\"\"";
-				}
-			} else {
-				$elementName = $name;
-				if ($unqualified) {
-					$elementNS = " xmlns=\"\"";
-				} else {
-					$elementNS = '';
-				}
-			}
-			if (is_null($value)) {
-				if ($use == 'literal') {
-					// TODO: depends on minOccurs
-					$xml = "<$elementName$elementNS/>";
-				} else {
-					$xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
-				}
-				$this->debug("in serializeType: returning: $xml");
-				return $xml;
-			}
-			if (is_object($value)) {
-				$value = get_object_vars($value);
-			}
-			if (is_array($value)) {
-				$elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
-				if ($use == 'literal') {
-					if ($forceType) {
-						$xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
-					} else {
-						$xml = "<$elementName$elementNS$elementAttrs>";
-					}
-				} else {
-					$xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
-				}
-	
-				$xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
-				$xml .= "</$elementName>";
-			} else {
-				$this->debug("in serializeType: phpType is struct, but value is not an array");
-				$this->setError("phpType is struct, but value is not an array: see debug output for details");
-				$xml = '';
-			}
-		} elseif ($phpType == 'array') {
-			if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
-				$elementNS = " xmlns=\"$ns\"";
-			} else {
-				if ($unqualified) {
-					$elementNS = " xmlns=\"\"";
-				} else {
-					$elementNS = '';
-				}
-			}
-			if (is_null($value)) {
-				if ($use == 'literal') {
-					// TODO: depends on minOccurs
-					$xml = "<$name$elementNS/>";
-				} else {
-					$xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
-						$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
-						":Array\" " .
-						$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
-						':arrayType="' .
-						$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
-						':' .
-						$this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
-				}
-				$this->debug("in serializeType: returning: $xml");
-				return $xml;
-			}
-			if (isset($typeDef['multidimensional'])) {
-				$nv = array();
-				foreach($value as $v) {
-					$cols = ',' . sizeof($v);
-					$nv = array_merge($nv, $v);
-				} 
-				$value = $nv;
-			} else {
-				$cols = '';
-			} 
-			if (is_array($value) && sizeof($value) >= 1) {
-				$rows = sizeof($value);
-				$contents = '';
-				foreach($value as $k => $v) {
-					$this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
-					//if (strpos($typeDef['arrayType'], ':') ) {
-					if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
-					    $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
-					} else {
-					    $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
-					} 
-				}
-			} else {
-				$rows = 0;
-				$contents = null;
-			}
-			// TODO: for now, an empty value will be serialized as a zero element
-			// array.  Revisit this when coding the handling of null/nil values.
-			if ($use == 'literal') {
-				$xml = "<$name$elementNS>"
-					.$contents
-					."</$name>";
-			} else {
-				$xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
-					$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
-					.':arrayType="'
-					.$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
-					.":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
-					.$contents
-					."</$name>";
-			}
-		} elseif ($phpType == 'scalar') {
-			if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
-				$elementNS = " xmlns=\"$ns\"";
-			} else {
-				if ($unqualified) {
-					$elementNS = " xmlns=\"\"";
-				} else {
-					$elementNS = '';
-				}
-			}
-			if ($use == 'literal') {
-				if ($forceType) {
-					$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
-				} else {
-					$xml = "<$name$elementNS>$value</$name>";
-				}
-			} else {
-				$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
-			}
-		}
-		$this->debug("in serializeType: returning: $xml");
-		return $xml;
-	}
-	
-	/**
-	 * serializes the attributes for a complexType
-	 *
-	 * @param array $typeDef our internal representation of an XML schema type (or element)
-	 * @param mixed $value a native PHP value (parameter value)
-	 * @param string $ns the namespace of the type
-	 * @param string $uqType the local part of the type
-	 * @return string value serialized as an XML string
-	 * @access private
-	 */
-	function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
-		$xml = '';
-		if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
-			$this->debug("serialize attributes for XML Schema type $ns:$uqType");
-			if (is_array($value)) {
-				$xvalue = $value;
-			} elseif (is_object($value)) {
-				$xvalue = get_object_vars($value);
-			} else {
-				$this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
-				$xvalue = array();
-			}
-			foreach ($typeDef['attrs'] as $aName => $attrs) {
-				if (isset($xvalue['!' . $aName])) {
-					$xname = '!' . $aName;
-					$this->debug("value provided for attribute $aName with key $xname");
-				} elseif (isset($xvalue[$aName])) {
-					$xname = $aName;
-					$this->debug("value provided for attribute $aName with key $xname");
-				} elseif (isset($attrs['default'])) {
-					$xname = '!' . $aName;
-					$xvalue[$xname] = $attrs['default'];
-					$this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
-				} else {
-					$xname = '';
-					$this->debug("no value provided for attribute $aName");
-				}
-				if ($xname) {
-					$xml .=  " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
-				}
-			} 
-		} else {
-			$this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
-		}
-		if (isset($typeDef['extensionBase'])) {
-			$ns = $this->getPrefix($typeDef['extensionBase']);
-			$uqType = $this->getLocalPart($typeDef['extensionBase']);
-			if ($this->getNamespaceFromPrefix($ns)) {
-				$ns = $this->getNamespaceFromPrefix($ns);
-			}
-			if ($typeDef = $this->getTypeDef($uqType, $ns)) {
-				$this->debug("serialize attributes for extension base $ns:$uqType");
-				$xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
-			} else {
-				$this->debug("extension base $ns:$uqType is not a supported type");
-			}
-		}
-		return $xml;
-	}
-
-	/**
-	 * serializes the elements for a complexType
-	 *
-	 * @param array $typeDef our internal representation of an XML schema type (or element)
-	 * @param mixed $value a native PHP value (parameter value)
-	 * @param string $ns the namespace of the type
-	 * @param string $uqType the local part of the type
-	 * @param string $use use for part (encoded|literal)
-	 * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
-	 * @return string value serialized as an XML string
-	 * @access private
-	 */
-	function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
-		$xml = '';
-		if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
-			$this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
-			if (is_array($value)) {
-				$xvalue = $value;
-			} elseif (is_object($value)) {
-				$xvalue = get_object_vars($value);
-			} else {
-				$this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
-				$xvalue = array();
-			}
-			// toggle whether all elements are present - ideally should validate against schema
-			if (count($typeDef['elements']) != count($xvalue)){
-				$optionals = true;
-			}
-			foreach ($typeDef['elements'] as $eName => $attrs) {
-				if (!isset($xvalue[$eName])) {
-					if (isset($attrs['default'])) {
-						$xvalue[$eName] = $attrs['default'];
-						$this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
-					}
-				}
-				// if user took advantage of a minOccurs=0, then only serialize named parameters
-				if (isset($optionals)
-				    && (!isset($xvalue[$eName])) 
-					&& ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
-					){
-					if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
-						$this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
-					}
-					// do nothing
-					$this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
-				} else {
-					// get value
-					if (isset($xvalue[$eName])) {
-					    $v = $xvalue[$eName];
-					} else {
-					    $v = null;
-					}
-					if (isset($attrs['form'])) {
-						$unqualified = ($attrs['form'] == 'unqualified');
-					} else {
-						$unqualified = false;
-					}
-					if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
-						$vv = $v;
-						foreach ($vv as $k => $v) {
-							if (isset($attrs['type']) || isset($attrs['ref'])) {
-								// serialize schema-defined type
-							    $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
-							} else {
-								// serialize generic type (can this ever really happen?)
-							    $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
-							    $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
-							}
-						}
-					} else {
-						if (isset($attrs['type']) || isset($attrs['ref'])) {
-							// serialize schema-defined type
-						    $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
-						} else {
-							// serialize generic type (can this ever really happen?)
-						    $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
-						    $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
-						}
-					}
-				}
-			} 
-		} else {
-			$this->debug("no elements to serialize for XML Schema type $ns:$uqType");
-		}
-		if (isset($typeDef['extensionBase'])) {
-			$ns = $this->getPrefix($typeDef['extensionBase']);
-			$uqType = $this->getLocalPart($typeDef['extensionBase']);
-			if ($this->getNamespaceFromPrefix($ns)) {
-				$ns = $this->getNamespaceFromPrefix($ns);
-			}
-			if ($typeDef = $this->getTypeDef($uqType, $ns)) {
-				$this->debug("serialize elements for extension base $ns:$uqType");
-				$xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
-			} else {
-				$this->debug("extension base $ns:$uqType is not a supported type");
-			}
-		}
-		return $xml;
-	}
-
-	/**
-	* adds an XML Schema complex type to the WSDL types
-	*
-	* @param string	name
-	* @param string typeClass (complexType|simpleType|attribute)
-	* @param string phpType: currently supported are array and struct (php assoc array)
-	* @param string compositor (all|sequence|choice)
-	* @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
-	* @param array elements = array ( name => array(name=>'',type=>'') )
-	* @param array attrs = 	array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))
-	* @param string arrayType: namespace:name (xsd:string)
-	* @see xmlschema
-	* @access public
-	*/
-	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
-		if (count($elements) > 0) {
-	    	foreach($elements as $n => $e){
-	            // expand each element
-	            foreach ($e as $k => $v) {
-		            $k = strpos($k,':') ? $this->expandQname($k) : $k;
-		            $v = strpos($v,':') ? $this->expandQname($v) : $v;
-		            $ee[$k] = $v;
-		    	}
-	    		$eElements[$n] = $ee;
-	    	}
-	    	$elements = $eElements;
-		}
-		
-		if (count($attrs) > 0) {
-	    	foreach($attrs as $n => $a){
-	            // expand each attribute
-	            foreach ($a as $k => $v) {
-		            $k = strpos($k,':') ? $this->expandQname($k) : $k;
-		            $v = strpos($v,':') ? $this->expandQname($v) : $v;
-		            $aa[$k] = $v;
-		    	}
-	    		$eAttrs[$n] = $aa;
-	    	}
-	    	$attrs = $eAttrs;
-		}
-
-		$restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
-		$arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
-
-		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
-		$this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
-	}
-
-	/**
-	* adds an XML Schema simple type to the WSDL types
-	*
-	* @param string $name
-	* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
-	* @param string $typeClass (should always be simpleType)
-	* @param string $phpType (should always be scalar)
-	* @param array $enumeration array of values
-	* @see xmlschema
-	* @access public
-	*/
-	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
-		$restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
-
-		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
-		$this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
-	}
-
-	/**
-	* adds an element to the WSDL types
-	*
-	* @param array $attrs attributes that must include name and type
-	* @see xmlschema
-	* @access public
-	*/
-	function addElement($attrs) {
-		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
-		$this->schemas[$typens][0]->addElement($attrs);
-	}
-
-	/**
-	* register an operation with the server
-	* 
-	* @param string $name operation (method) name
-	* @param array $in assoc array of input values: key = param name, value = param type
-	* @param array $out assoc array of output values: key = param name, value = param type
-	* @param string $namespace optional The namespace for the operation
-	* @param string $soapaction optional The soapaction for the operation
-	* @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically
-	* @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now)
-	* @param string $documentation optional The description to include in the WSDL
-	* @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
-	* @access public 
-	*/
-	function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
-		if ($use == 'encoded' && $encodingStyle == '') {
-			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-		}
-
-		if ($style == 'document') {
-			$elements = array();
-			foreach ($in as $n => $t) {
-				$elements[$n] = array('name' => $n, 'type' => $t);
-			}
-			$this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
-			$this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
-			$in = array('parameters' => 'tns:' . $name);
-
-			$elements = array();
-			foreach ($out as $n => $t) {
-				$elements[$n] = array('name' => $n, 'type' => $t);
-			}
-			$this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
-			$this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType'));
-			$out = array('parameters' => 'tns:' . $name . 'Response');
-		}
-
-		// get binding
-		$this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
-		array(
-		'name' => $name,
-		'binding' => $this->serviceName . 'Binding',
-		'endpoint' => $this->endpoint,
-		'soapAction' => $soapaction,
-		'style' => $style,
-		'input' => array(
-			'use' => $use,
-			'namespace' => $namespace,
-			'encodingStyle' => $encodingStyle,
-			'message' => $name . 'Request',
-			'parts' => $in),
-		'output' => array(
-			'use' => $use,
-			'namespace' => $namespace,
-			'encodingStyle' => $encodingStyle,
-			'message' => $name . 'Response',
-			'parts' => $out),
-		'namespace' => $namespace,
-		'transport' => 'http://schemas.xmlsoap.org/soap/http',
-		'documentation' => $documentation); 
-		// add portTypes
-		// add messages
-		if($in)
-		{
-			foreach($in as $pName => $pType)
-			{
-				if(strpos($pType,':')) {
-					$pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
-				}
-				$this->messages[$name.'Request'][$pName] = $pType;
-			}
-		} else {
-            $this->messages[$name.'Request']= '0';
-        }
-		if($out)
-		{
-			foreach($out as $pName => $pType)
-			{
-				if(strpos($pType,':')) {
-					$pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
-				}
-				$this->messages[$name.'Response'][$pName] = $pType;
-			}
-		} else {
-            $this->messages[$name.'Response']= '0';
-        }
-		return true;
-	} 
-}
-
+<?php
+
+
+
+
+/**
+* parses a WSDL file, allows access to it's data, other utility methods
+* 
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access public 
+*/
+class wsdl extends nusoap_base {
+	// URL or filename of the root of this WSDL
+    var $wsdl; 
+    // define internal arrays of bindings, ports, operations, messages, etc.
+    var $schemas = array();
+    var $currentSchema;
+    var $message = array();
+    var $complexTypes = array();
+    var $messages = array();
+    var $currentMessage;
+    var $currentOperation;
+    var $portTypes = array();
+    var $currentPortType;
+    var $bindings = array();
+    var $currentBinding;
+    var $ports = array();
+    var $currentPort;
+    var $opData = array();
+    var $status = '';
+    var $documentation = false;
+    var $endpoint = ''; 
+    // array of wsdl docs to import
+    var $import = array(); 
+    // parser vars
+    var $parser;
+    var $position = 0;
+    var $depth = 0;
+    var $depth_array = array();
+	// for getting wsdl
+	var $proxyhost = '';
+    var $proxyport = '';
+	var $proxyusername = '';
+	var $proxypassword = '';
+	var $timeout = 0;
+	var $response_timeout = 30;
+
+    /**
+     * constructor
+     * 
+     * @param string $wsdl WSDL document URL
+	 * @param string $proxyhost
+	 * @param string $proxyport
+	 * @param string $proxyusername
+	 * @param string $proxypassword
+	 * @param integer $timeout set the connection timeout
+	 * @param integer $response_timeout set the response timeout
+     * @access public 
+     */
+    function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){
+		parent::nusoap_base();
+        $this->wsdl = $wsdl;
+        $this->proxyhost = $proxyhost;
+        $this->proxyport = $proxyport;
+		$this->proxyusername = $proxyusername;
+		$this->proxypassword = $proxypassword;
+		$this->timeout = $timeout;
+		$this->response_timeout = $response_timeout;
+        
+        // parse wsdl file
+        if ($wsdl != "") {
+            $this->debug('initial wsdl URL: ' . $wsdl);
+            $this->parseWSDL($wsdl);
+        }
+        // imports
+        // TODO: handle imports more properly, grabbing them in-line and nesting them
+        	$imported_urls = array();
+        	$imported = 1;
+        	while ($imported > 0) {
+        		$imported = 0;
+        		// Schema imports
+        		foreach ($this->schemas as $ns => $list) {
+        			foreach ($list as $xs) {
+						$wsdlparts = parse_url($this->wsdl);	// this is bogusly simple!
+			            foreach ($xs->imports as $ns2 => $list2) {
+			                for ($ii = 0; $ii < count($list2); $ii++) {
+			                	if (! $list2[$ii]['loaded']) {
+			                		$this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
+			                		$url = $list2[$ii]['location'];
+									if ($url != '') {
+										$urlparts = parse_url($url);
+										if (!isset($urlparts['host'])) {
+											$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
+													substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
+										}
+										if (! in_array($url, $imported_urls)) {
+						                	$this->parseWSDL($url);
+					                		$imported++;
+					                		$imported_urls[] = $url;
+					                	}
+									} else {
+										$this->debug("Unexpected scenario: empty URL for unloaded import");
+									}
+								}
+							}
+			            } 
+        			}
+        		}
+        		// WSDL imports
+				$wsdlparts = parse_url($this->wsdl);	// this is bogusly simple!
+	            foreach ($this->import as $ns => $list) {
+	                for ($ii = 0; $ii < count($list); $ii++) {
+	                	if (! $list[$ii]['loaded']) {
+	                		$this->import[$ns][$ii]['loaded'] = true;
+	                		$url = $list[$ii]['location'];
+							if ($url != '') {
+								$urlparts = parse_url($url);
+								if (!isset($urlparts['host'])) {
+									$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
+											substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
+								}
+								if (! in_array($url, $imported_urls)) {
+				                	$this->parseWSDL($url);
+			                		$imported++;
+			                		$imported_urls[] = $url;
+			                	}
+							} else {
+								$this->debug("Unexpected scenario: empty URL for unloaded import");
+							}
+						}
+					}
+	            } 
+			}
+        // add new data to operation data
+        foreach($this->bindings as $binding => $bindingData) {
+            if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
+                foreach($bindingData['operations'] as $operation => $data) {
+                    $this->debug('post-parse data gathering for ' . $operation);
+                    $this->bindings[$binding]['operations'][$operation]['input'] = 
+						isset($this->bindings[$binding]['operations'][$operation]['input']) ? 
+						array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
+						$this->portTypes[ $bindingData['portType'] ][$operation]['input'];
+                    $this->bindings[$binding]['operations'][$operation]['output'] = 
+						isset($this->bindings[$binding]['operations'][$operation]['output']) ?
+						array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
+						$this->portTypes[ $bindingData['portType'] ][$operation]['output'];
+                    if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
+						$this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
+					}
+					if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
+                   		$this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
+                    }
+					if (isset($bindingData['style'])) {
+                        $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
+                    }
+                    $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
+                    $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
+                    $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
+                } 
+            } 
+        }
+    }
+
+    /**
+     * parses the wsdl document
+     * 
+     * @param string $wsdl path or URL
+     * @access private 
+     */
+    function parseWSDL($wsdl = '')
+    {
+        if ($wsdl == '') {
+            $this->debug('no wsdl passed to parseWSDL()!!');
+            $this->setError('no wsdl passed to parseWSDL()!!');
+            return false;
+        }
+        
+        // parse $wsdl for url format
+        $wsdl_props = parse_url($wsdl);
+
+        if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
+            $this->debug('getting WSDL http(s) URL ' . $wsdl);
+        	// get wsdl
+	        $tr = new soap_transport_http($wsdl);
+			$tr->request_method = 'GET';
+			$tr->useSOAPAction = false;
+			if($this->proxyhost && $this->proxyport){
+				$tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
+			}
+			$tr->setEncoding('gzip, deflate');
+			$wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
+			//$this->debug("WSDL request\n" . $tr->outgoing_payload);
+			//$this->debug("WSDL response\n" . $tr->incoming_payload);
+			$this->appendDebug($tr->getDebug());
+			// catch errors
+			if($err = $tr->getError() ){
+				$errstr = 'HTTP ERROR: '.$err;
+				$this->debug($errstr);
+	            $this->setError($errstr);
+				unset($tr);
+	            return false;
+			}
+			unset($tr);
+			$this->debug("got WSDL URL");
+        } else {
+            // $wsdl is not http(s), so treat it as a file URL or plain file path
+        	if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
+        		$path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
+        	} else {
+        		$path = $wsdl;
+        	}
+            $this->debug('getting WSDL file ' . $path);
+            if ($fp = @fopen($path, 'r')) {
+                $wsdl_string = '';
+                while ($data = fread($fp, 32768)) {
+                    $wsdl_string .= $data;
+                } 
+                fclose($fp);
+            } else {
+            	$errstr = "Bad path to WSDL file $path";
+            	$this->debug($errstr);
+                $this->setError($errstr);
+                return false;
+            } 
+        }
+        $this->debug('Parse WSDL');
+        // end new code added
+        // Create an XML parser.
+        $this->parser = xml_parser_create(); 
+        // Set the options for parsing the XML data.
+        // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 
+        // Set the object for the parser.
+        xml_set_object($this->parser, $this); 
+        // Set the element handlers for the parser.
+        xml_set_element_handler($this->parser, 'start_element', 'end_element');
+        xml_set_character_data_handler($this->parser, 'character_data');
+        // Parse the XML file.
+        if (!xml_parse($this->parser, $wsdl_string, true)) {
+            // Display an error message.
+            $errstr = sprintf(
+				'XML error parsing WSDL from %s on line %d: %s',
+				$wsdl,
+                xml_get_current_line_number($this->parser),
+                xml_error_string(xml_get_error_code($this->parser))
+                );
+            $this->debug($errstr);
+			$this->debug("XML payload:\n" . $wsdl_string);
+            $this->setError($errstr);
+            return false;
+        } 
+		// free the parser
+        xml_parser_free($this->parser);
+        $this->debug('Parsing WSDL done');
+		// catch wsdl parse errors
+		if($this->getError()){
+			return false;
+		}
+        return true;
+    } 
+
+    /**
+     * start-element handler
+     * 
+     * @param string $parser XML parser object
+     * @param string $name element name
+     * @param string $attrs associative array of attributes
+     * @access private 
+     */
+    function start_element($parser, $name, $attrs)
+    {
+        if ($this->status == 'schema') {
+            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
+            $this->appendDebug($this->currentSchema->getDebug());
+            $this->currentSchema->clearDebug();
+        } elseif (ereg('schema$', $name)) {
+        	$this->debug('Parsing WSDL schema');
+            // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
+            $this->status = 'schema';
+            $this->currentSchema = new xmlschema('', '', $this->namespaces);
+            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
+            $this->appendDebug($this->currentSchema->getDebug());
+            $this->currentSchema->clearDebug();
+        } else {
+            // position in the total number of elements, starting from 0
+            $pos = $this->position++;
+            $depth = $this->depth++; 
+            // set self as current value for this depth
+            $this->depth_array[$depth] = $pos;
+            $this->message[$pos] = array('cdata' => ''); 
+            // process attributes
+            if (count($attrs) > 0) {
+				// register namespace declarations
+                foreach($attrs as $k => $v) {
+                    if (ereg("^xmlns", $k)) {
+                        if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
+                            $this->namespaces[$ns_prefix] = $v;
+                        } else {
+                            $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
+                        } 
+                        if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
+                            $this->XMLSchemaVersion = $v;
+                            $this->namespaces['xsi'] = $v . '-instance';
+                        } 
+                    }
+                }
+                // expand each attribute prefix to its namespace
+                foreach($attrs as $k => $v) {
+                    $k = strpos($k, ':') ? $this->expandQname($k) : $k;
+                    if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
+                        $v = strpos($v, ':') ? $this->expandQname($v) : $v;
+                    } 
+                    $eAttrs[$k] = $v;
+                } 
+                $attrs = $eAttrs;
+            } else {
+                $attrs = array();
+            } 
+            // get element prefix, namespace and name
+            if (ereg(':', $name)) {
+                // get ns prefix
+                $prefix = substr($name, 0, strpos($name, ':')); 
+                // get ns
+                $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; 
+                // get unqualified name
+                $name = substr(strstr($name, ':'), 1);
+            } 
+			// process attributes, expanding any prefixes to namespaces
+            // find status, register data
+            switch ($this->status) {
+                case 'message':
+                    if ($name == 'part') {
+			            if (isset($attrs['type'])) {
+		                    $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
+		                    $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
+            			} 
+			            if (isset($attrs['element'])) {
+		                    $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
+			                $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'];
+			            } 
+        			} 
+        			break;
+			    case 'portType':
+			        switch ($name) {
+			            case 'operation':
+			                $this->currentPortOperation = $attrs['name'];
+			                $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
+			                if (isset($attrs['parameterOrder'])) {
+			                	$this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
+			        		} 
+			        		break;
+					    case 'documentation':
+					        $this->documentation = true;
+					        break; 
+					    // merge input/output data
+					    default:
+					        $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
+					        $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
+					        break;
+					} 
+			    	break;
+				case 'binding':
+				    switch ($name) {
+				        case 'binding': 
+				            // get ns prefix
+				            if (isset($attrs['style'])) {
+				            $this->bindings[$this->currentBinding]['prefix'] = $prefix;
+					    	} 
+					    	$this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
+					    	break;
+						case 'header':
+						    $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
+						    break;
+						case 'operation':
+						    if (isset($attrs['soapAction'])) {
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
+						    } 
+						    if (isset($attrs['style'])) {
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
+						    } 
+						    if (isset($attrs['name'])) {
+						        $this->currentOperation = $attrs['name'];
+						        $this->debug("current binding operation: $this->currentOperation");
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
+						    } 
+						    break;
+						case 'input':
+						    $this->opStatus = 'input';
+						    break;
+						case 'output':
+						    $this->opStatus = 'output';
+						    break;
+						case 'body':
+						    if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
+						    } else {
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
+						    } 
+						    break;
+					} 
+					break;
+				case 'service':
+					switch ($name) {
+					    case 'port':
+					        $this->currentPort = $attrs['name'];
+					        $this->debug('current port: ' . $this->currentPort);
+					        $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
+					
+					        break;
+					    case 'address':
+					        $this->ports[$this->currentPort]['location'] = $attrs['location'];
+					        $this->ports[$this->currentPort]['bindingType'] = $namespace;
+					        $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
+					        $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
+					        break;
+					} 
+					break;
+			} 
+		// set status
+		switch ($name) {
+			case 'import':
+			    if (isset($attrs['location'])) {
+                    $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
+                    $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
+				} else {
+                    $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
+					if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
+						$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
+					}
+                    $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
+				}
+				break;
+			//wait for schema
+			//case 'types':
+			//	$this->status = 'schema';
+			//	break;
+			case 'message':
+				$this->status = 'message';
+				$this->messages[$attrs['name']] = array();
+				$this->currentMessage = $attrs['name'];
+				break;
+			case 'portType':
+				$this->status = 'portType';
+				$this->portTypes[$attrs['name']] = array();
+				$this->currentPortType = $attrs['name'];
+				break;
+			case "binding":
+				if (isset($attrs['name'])) {
+				// get binding name
+					if (strpos($attrs['name'], ':')) {
+			    		$this->currentBinding = $this->getLocalPart($attrs['name']);
+					} else {
+			    		$this->currentBinding = $attrs['name'];
+					} 
+					$this->status = 'binding';
+					$this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
+					$this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
+				} 
+				break;
+			case 'service':
+				$this->serviceName = $attrs['name'];
+				$this->status = 'service';
+				$this->debug('current service: ' . $this->serviceName);
+				break;
+			case 'definitions':
+				foreach ($attrs as $name => $value) {
+					$this->wsdl_info[$name] = $value;
+				} 
+				break;
+			} 
+		} 
+	} 
+
+	/**
+	* end-element handler
+	* 
+	* @param string $parser XML parser object
+	* @param string $name element name
+	* @access private 
+	*/
+	function end_element($parser, $name){ 
+		// unset schema status
+		if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) {
+			$this->status = "";
+            $this->appendDebug($this->currentSchema->getDebug());
+            $this->currentSchema->clearDebug();
+			$this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
+        	$this->debug('Parsing WSDL schema done');
+		} 
+		if ($this->status == 'schema') {
+			$this->currentSchema->schemaEndElement($parser, $name);
+		} else {
+			// bring depth down a notch
+			$this->depth--;
+		} 
+		// end documentation
+		if ($this->documentation) {
+			//TODO: track the node to which documentation should be assigned; it can be a part, message, etc.
+			//$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
+			$this->documentation = false;
+		} 
+	} 
+
+	/**
+	 * element content handler
+	 * 
+	 * @param string $parser XML parser object
+	 * @param string $data element content
+	 * @access private 
+	 */
+	function character_data($parser, $data)
+	{
+		$pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
+		if (isset($this->message[$pos]['cdata'])) {
+			$this->message[$pos]['cdata'] .= $data;
+		} 
+		if ($this->documentation) {
+			$this->documentation .= $data;
+		} 
+	} 
+	
+	function getBindingData($binding)
+	{
+		if (is_array($this->bindings[$binding])) {
+			return $this->bindings[$binding];
+		} 
+	}
+	
+	/**
+	 * returns an assoc array of operation names => operation data
+	 * 
+	 * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported)
+	 * @return array 
+	 * @access public 
+	 */
+	function getOperations($bindingType = 'soap')
+	{
+		$ops = array();
+		if ($bindingType == 'soap') {
+			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+		}
+		// loop thru ports
+		foreach($this->ports as $port => $portData) {
+			// binding type of port matches parameter
+			if ($portData['bindingType'] == $bindingType) {
+				//$this->debug("getOperations for port $port");
+				//$this->debug("port data: " . $this->varDump($portData));
+				//$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));
+				// merge bindings
+				if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
+					$ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
+				}
+			}
+		} 
+		return $ops;
+	} 
+	
+	/**
+	 * returns an associative array of data necessary for calling an operation
+	 * 
+	 * @param string $operation , name of operation
+	 * @param string $bindingType , type of binding eg: soap
+	 * @return array 
+	 * @access public 
+	 */
+	function getOperationData($operation, $bindingType = 'soap')
+	{
+		if ($bindingType == 'soap') {
+			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+		}
+		// loop thru ports
+		foreach($this->ports as $port => $portData) {
+			// binding type of port matches parameter
+			if ($portData['bindingType'] == $bindingType) {
+				// get binding
+				//foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
+				foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
+					// note that we could/should also check the namespace here
+					if ($operation == $bOperation) {
+						$opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
+					    return $opData;
+					} 
+				} 
+			}
+		} 
+	}
+	
+	/**
+	 * returns an associative array of data necessary for calling an operation
+	 * 
+	 * @param string $soapAction soapAction for operation
+	 * @param string $bindingType type of binding eg: soap
+	 * @return array 
+	 * @access public 
+	 */
+	function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
+		if ($bindingType == 'soap') {
+			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+		}
+		// loop thru ports
+		foreach($this->ports as $port => $portData) {
+			// binding type of port matches parameter
+			if ($portData['bindingType'] == $bindingType) {
+				// loop through operations for the binding
+				foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
+					if ($opData['soapAction'] == $soapAction) {
+					    return $opData;
+					} 
+				} 
+			}
+		} 
+	}
+	
+	/**
+    * returns an array of information about a given type
+    * returns false if no type exists by the given name
+    *
+	*	 typeDef = array(
+	*	 'elements' => array(), // refs to elements array
+	*	'restrictionBase' => '',
+	*	'phpType' => '',
+	*	'order' => '(sequence|all)',
+	*	'attrs' => array() // refs to attributes array
+	*	)
+    *
+    * @param $type string the type
+    * @param $ns string namespace (not prefix) of the type
+    * @return mixed
+    * @access public
+    * @see xmlschema
+    */
+	function getTypeDef($type, $ns) {
+		$this->debug("in getTypeDef: type=$type, ns=$ns");
+		if ((! $ns) && isset($this->namespaces['tns'])) {
+			$ns = $this->namespaces['tns'];
+			$this->debug("in getTypeDef: type namespace forced to $ns");
+		}
+		if (isset($this->schemas[$ns])) {
+			$this->debug("in getTypeDef: have schema for namespace $ns");
+			for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
+				$xs = &$this->schemas[$ns][$i];
+				$t = $xs->getTypeDef($type);
+				$this->appendDebug($xs->getDebug());
+				$xs->clearDebug();
+				if ($t) {
+					if (!isset($t['phpType'])) {
+						// get info for type to tack onto the element
+						$uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
+						$ns = substr($t['type'], 0, strrpos($t['type'], ':'));
+						$etype = $this->getTypeDef($uqType, $ns);
+						if ($etype) {
+							$this->debug("found type for [element] $type:");
+							$this->debug($this->varDump($etype));
+							if (isset($etype['phpType'])) {
+								$t['phpType'] = $etype['phpType'];
+							}
+							if (isset($etype['elements'])) {
+								$t['elements'] = $etype['elements'];
+							}
+							if (isset($etype['attrs'])) {
+								$t['attrs'] = $etype['attrs'];
+							}
+						}
+					}
+					return $t;
+				}
+			}
+		} else {
+			$this->debug("in getTypeDef: do not have schema for namespace $ns");
+		}
+		return false;
+	}
+
+    /**
+    * prints html description of services
+    *
+    * @access private
+    */
+    function webDescription(){
+    	global $HTTP_SERVER_VARS;
+
+		if (isset($_SERVER)) {
+			$PHP_SELF = $_SERVER['PHP_SELF'];
+		} elseif (isset($HTTP_SERVER_VARS)) {
+			$PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
+		} else {
+			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
+		}
+
+		$b = '
+		<html><head><title>NuSOAP: '.$this->serviceName.'</title>
+		<style type="text/css">
+		    body    { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
+		    p       { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
+		    pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
+		    ul      { margin-top: 10px; margin-left: 20px; }
+		    li      { list-style-type: none; margin-top: 10px; color: #000000; }
+		    .content{
+			margin-left: 0px; padding-bottom: 2em; }
+		    .nav {
+			padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
+			margin-top: 10px; margin-left: 0px; color: #000000;
+			background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
+		    .title {
+			font-family: arial; font-size: 26px; color: #ffffff;
+			background-color: #999999; width: 105%; margin-left: 0px;
+			padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
+		    .hidden {
+			position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
+			font-family: arial; overflow: hidden; width: 600;
+			padding: 20px; font-size: 10px; background-color: #999999;
+			layer-background-color:#FFFFFF; }
+		    a,a:active  { color: charcoal; font-weight: bold; }
+		    a:visited   { color: #666666; font-weight: bold; }
+		    a:hover     { color: cc3300; font-weight: bold; }
+		</style>
+		<script language="JavaScript" type="text/javascript">
+		<!--
+		// POP-UP CAPTIONS...
+		function lib_bwcheck(){ //Browsercheck (needed)
+		    this.ver=navigator.appVersion
+		    this.agent=navigator.userAgent
+		    this.dom=document.getElementById?1:0
+		    this.opera5=this.agent.indexOf("Opera 5")>-1
+		    this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
+		    this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
+		    this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
+		    this.ie=this.ie4||this.ie5||this.ie6
+		    this.mac=this.agent.indexOf("Mac")>-1
+		    this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
+		    this.ns4=(document.layers && !this.dom)?1:0;
+		    this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
+		    return this
+		}
+		var bw = new lib_bwcheck()
+		//Makes crossbrowser object.
+		function makeObj(obj){
+		    this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
+		    if(!this.evnt) return false
+		    this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
+		    this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
+		    this.writeIt=b_writeIt;
+		    return this
+		}
+		// A unit of measure that will be added when setting the position of a layer.
+		//var px = bw.ns4||window.opera?"":"px";
+		function b_writeIt(text){
+		    if (bw.ns4){this.wref.write(text);this.wref.close()}
+		    else this.wref.innerHTML = text
+		}
+		//Shows the messages
+		var oDesc;
+		function popup(divid){
+		    if(oDesc = new makeObj(divid)){
+			oDesc.css.visibility = "visible"
+		    }
+		}
+		function popout(){ // Hides message
+		    if(oDesc) oDesc.css.visibility = "hidden"
+		}
+		//-->
+		</script>
+		</head>
+		<body>
+		<div class=content>
+			<br><br>
+			<div class=title>'.$this->serviceName.'</div>
+			<div class=nav>
+				<p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
+				Click on an operation name to view it&apos;s details.</p>
+				<ul>';
+				foreach($this->getOperations() as $op => $data){
+				    $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
+				    // create hidden div
+				    $b .= "<div id='$op' class='hidden'>
+				    <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
+				    foreach($data as $donnie => $marie){ // loop through opdata
+						if($donnie == 'input' || $donnie == 'output'){ // show input/output data
+						    $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
+						    foreach($marie as $captain => $tenille){ // loop through data
+								if($captain == 'parts'){ // loop thru parts
+								    $b .= "&nbsp;&nbsp;$captain:<br>";
+					                //if(is_array($tenille)){
+								    	foreach($tenille as $joanie => $chachi){
+											$b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
+								    	}
+					        		//}
+								} else {
+								    $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
+								}
+						    }
+						} else {
+						    $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
+						}
+				    }
+					$b .= '</div>';
+				}
+				$b .= '
+				<ul>
+			</div>
+		</div></body></html>';
+		return $b;
+    }
+
+	/**
+	* serialize the parsed wsdl
+	*
+	* @param mixed $debug whether to put debug=1 in endpoint URL
+	* @return string serialization of WSDL
+	* @access public 
+	*/
+	function serialize($debug = 0)
+	{
+		$xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
+		$xml .= "\n<definitions";
+		foreach($this->namespaces as $k => $v) {
+			$xml .= " xmlns:$k=\"$v\"";
+		} 
+		// 10.9.02 - add poulter fix for wsdl and tns declarations
+		if (isset($this->namespaces['wsdl'])) {
+			$xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
+		} 
+		if (isset($this->namespaces['tns'])) {
+			$xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
+		} 
+		$xml .= '>'; 
+		// imports
+		if (sizeof($this->import) > 0) {
+			foreach($this->import as $ns => $list) {
+				foreach ($list as $ii) {
+					if ($ii['location'] != '') {
+						$xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
+					} else {
+						$xml .= '<import namespace="' . $ns . '" />';
+					}
+				}
+			} 
+		} 
+		// types
+		if (count($this->schemas)>=1) {
+			$xml .= "\n<types>";
+			foreach ($this->schemas as $ns => $list) {
+				foreach ($list as $xs) {
+					$xml .= $xs->serializeSchema();
+				}
+			}
+			$xml .= '</types>';
+		} 
+		// messages
+		if (count($this->messages) >= 1) {
+			foreach($this->messages as $msgName => $msgParts) {
+				$xml .= "\n<message name=\"" . $msgName . '">';
+				if(is_array($msgParts)){
+					foreach($msgParts as $partName => $partType) {
+						// print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';
+						if (strpos($partType, ':')) {
+						    $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
+						} elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
+						    // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';
+						    $typePrefix = 'xsd';
+						} else {
+						    foreach($this->typemap as $ns => $types) {
+						        if (isset($types[$partType])) {
+						            $typePrefix = $this->getPrefixFromNamespace($ns);
+						        } 
+						    } 
+						    if (!isset($typePrefix)) {
+						        die("$partType has no namespace!");
+						    } 
+						}
+						$ns = $this->getNamespaceFromPrefix($typePrefix);
+						$typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns);
+						if ($typeDef['typeClass'] == 'element') {
+							$elementortype = 'element';
+						} else {
+							$elementortype = 'type';
+						}
+						$xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />';
+					}
+				}
+				$xml .= '</message>';
+			} 
+		} 
+		// bindings & porttypes
+		if (count($this->bindings) >= 1) {
+			$binding_xml = '';
+			$portType_xml = '';
+			foreach($this->bindings as $bindingName => $attrs) {
+				$binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
+				$binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
+				$portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
+				foreach($attrs['operations'] as $opName => $opParts) {
+					$binding_xml .= '<operation name="' . $opName . '">';
+					$binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
+					if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
+						$enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
+					} else {
+						$enc_style = '';
+					}
+					$binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
+					if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
+						$enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
+					} else {
+						$enc_style = '';
+					}
+					$binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
+					$binding_xml .= '</operation>';
+					$portType_xml .= '<operation name="' . $opParts['name'] . '"';
+					if (isset($opParts['parameterOrder'])) {
+					    $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
+					} 
+					$portType_xml .= '>';
+					if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
+						$portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
+					}
+					$portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>';
+					$portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>';
+					$portType_xml .= '</operation>';
+				} 
+				$portType_xml .= '</portType>';
+				$binding_xml .= '</binding>';
+			} 
+			$xml .= $portType_xml . $binding_xml;
+		} 
+		// services
+		$xml .= "\n<service name=\"" . $this->serviceName . '">';
+		if (count($this->ports) >= 1) {
+			foreach($this->ports as $pName => $attrs) {
+				$xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
+				$xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
+				$xml .= '</port>';
+			} 
+		} 
+		$xml .= '</service>';
+		return $xml . "\n</definitions>";
+	} 
+	
+	/**
+	 * serialize PHP values according to a WSDL message definition
+	 *
+	 * TODO
+	 * - multi-ref serialization
+	 * - validate PHP values against type definitions, return errors if invalid
+	 * 
+	 * @param string $operation operation name
+	 * @param string $direction (input|output)
+	 * @param mixed $parameters parameter value(s)
+	 * @return mixed parameters serialized as XML or false on error (e.g. operation not found)
+	 * @access public
+	 */
+	function serializeRPCParameters($operation, $direction, $parameters)
+	{
+		$this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
+		$this->appendDebug('parameters=' . $this->varDump($parameters));
+		
+		if ($direction != 'input' && $direction != 'output') {
+			$this->debug('The value of the \$direction argument needs to be either "input" or "output"');
+			$this->setError('The value of the \$direction argument needs to be either "input" or "output"');
+			return false;
+		} 
+		if (!$opData = $this->getOperationData($operation)) {
+			$this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
+			$this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
+			return false;
+		}
+		$this->debug('opData:');
+		$this->appendDebug($this->varDump($opData));
+
+		// Get encoding style for output and set to current
+		$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+		if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
+			$encodingStyle = $opData['output']['encodingStyle'];
+			$enc_style = $encodingStyle;
+		}
+
+		// set input params
+		$xml = '';
+		if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
+			
+			$use = $opData[$direction]['use'];
+			$this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize');
+			if (is_array($parameters)) {
+				$parametersArrayType = $this->isArraySimpleOrStruct($parameters);
+				$this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize');
+				foreach($opData[$direction]['parts'] as $name => $type) {
+					$this->debug('serializing part "'.$name.'" of type "'.$type.'"');
+					// Track encoding style
+					if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
+						$encodingStyle = $opData[$direction]['encodingStyle'];			
+						$enc_style = $encodingStyle;
+					} else {
+						$enc_style = false;
+					}
+					// NOTE: add error handling here
+					// if serializeType returns false, then catch global error and fault
+					if ($parametersArrayType == 'arraySimple') {
+						$p = array_shift($parameters);
+						$this->debug('calling serializeType w/indexed param');
+						$xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
+					} elseif (isset($parameters[$name])) {
+						$this->debug('calling serializeType w/named param');
+						$xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
+					} else {
+						// TODO: only send nillable
+						$this->debug('calling serializeType w/null param');
+						$xml .= $this->serializeType($name, $type, null, $use, $enc_style);
+					}
+				}
+			} else {
+				$this->debug('no parameters passed.');
+			}
+		}
+		$this->debug("serializeRPCParameters returning: $xml");
+		return $xml;
+	} 
+	
+	/**
+	 * serialize a PHP value according to a WSDL message definition
+	 * 
+	 * TODO
+	 * - multi-ref serialization
+	 * - validate PHP values against type definitions, return errors if invalid
+	 * 
+	 * @param string $ type name
+	 * @param mixed $ param value
+	 * @return mixed new param or false if initial value didn't validate
+	 * @access public
+	 * @deprecated
+	 */
+	function serializeParameters($operation, $direction, $parameters)
+	{
+		$this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
+		$this->appendDebug('parameters=' . $this->varDump($parameters));
+		
+		if ($direction != 'input' && $direction != 'output') {
+			$this->debug('The value of the \$direction argument needs to be either "input" or "output"');
+			$this->setError('The value of the \$direction argument needs to be either "input" or "output"');
+			return false;
+		} 
+		if (!$opData = $this->getOperationData($operation)) {
+			$this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
+			$this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
+			return false;
+		}
+		$this->debug('opData:');
+		$this->appendDebug($this->varDump($opData));
+		
+		// Get encoding style for output and set to current
+		$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+		if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
+			$encodingStyle = $opData['output']['encodingStyle'];
+			$enc_style = $encodingStyle;
+		}
+		
+		// set input params
+		$xml = '';
+		if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
+			
+			$use = $opData[$direction]['use'];
+			$this->debug("use=$use");
+			$this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
+			if (is_array($parameters)) {
+				$parametersArrayType = $this->isArraySimpleOrStruct($parameters);
+				$this->debug('have ' . $parametersArrayType . ' parameters');
+				foreach($opData[$direction]['parts'] as $name => $type) {
+					$this->debug('serializing part "'.$name.'" of type "'.$type.'"');
+					// Track encoding style
+					if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
+						$encodingStyle = $opData[$direction]['encodingStyle'];			
+						$enc_style = $encodingStyle;
+					} else {
+						$enc_style = false;
+					}
+					// NOTE: add error handling here
+					// if serializeType returns false, then catch global error and fault
+					if ($parametersArrayType == 'arraySimple') {
+						$p = array_shift($parameters);
+						$this->debug('calling serializeType w/indexed param');
+						$xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
+					} elseif (isset($parameters[$name])) {
+						$this->debug('calling serializeType w/named param');
+						$xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
+					} else {
+						// TODO: only send nillable
+						$this->debug('calling serializeType w/null param');
+						$xml .= $this->serializeType($name, $type, null, $use, $enc_style);
+					}
+				}
+			} else {
+				$this->debug('no parameters passed.');
+			}
+		}
+		$this->debug("serializeParameters returning: $xml");
+		return $xml;
+	} 
+	
+	/**
+	 * serializes a PHP value according a given type definition
+	 * 
+	 * @param string $name name of value (part or element)
+	 * @param string $type XML schema type of value (type or element)
+	 * @param mixed $value a native PHP value (parameter value)
+	 * @param string $use use for part (encoded|literal)
+	 * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
+	 * @param boolean $unqualified a kludge for what should be XML namespace form handling
+	 * @return string value serialized as an XML string
+	 * @access private
+	 */
+	function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
+	{
+		$this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
+		$this->appendDebug("value=" . $this->varDump($value));
+		if($use == 'encoded' && $encodingStyle) {
+			$encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
+		}
+
+		// if a soapval has been supplied, let its type override the WSDL
+    	if (is_object($value) && get_class($value) == 'soapval') {
+    		if ($value->type_ns) {
+    			$type = $value->type_ns . ':' . $value->type;
+		    	$forceType = true;
+		    	$this->debug("in serializeType: soapval overrides type to $type");
+    		} elseif ($value->type) {
+	    		$type = $value->type;
+		    	$forceType = true;
+		    	$this->debug("in serializeType: soapval overrides type to $type");
+	    	} else {
+	    		$forceType = false;
+		    	$this->debug("in serializeType: soapval does not override type");
+	    	}
+	    	$attrs = $value->attributes;
+	    	$value = $value->value;
+	    	$this->debug("in serializeType: soapval overrides value to $value");
+	    	if ($attrs) {
+	    		if (!is_array($value)) {
+	    			$value['!'] = $value;
+	    		}
+	    		foreach ($attrs as $n => $v) {
+	    			$value['!' . $n] = $v;
+	    		}
+		    	$this->debug("in serializeType: soapval provides attributes");
+		    }
+        } else {
+        	$forceType = false;
+        }
+
+		$xml = '';
+		if (strpos($type, ':')) {
+			$uqType = substr($type, strrpos($type, ':') + 1);
+			$ns = substr($type, 0, strrpos($type, ':'));
+			$this->debug("in serializeType: got a prefixed type: $uqType, $ns");
+			if ($this->getNamespaceFromPrefix($ns)) {
+				$ns = $this->getNamespaceFromPrefix($ns);
+				$this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
+			}
+
+			if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
+				$this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
+				if ($unqualified  && $use == 'literal') {
+					$elementNS = " xmlns=\"\"";
+				} else {
+					$elementNS = '';
+				}
+				if (is_null($value)) {
+					if ($use == 'literal') {
+						// TODO: depends on minOccurs
+						$xml = "<$name$elementNS/>";
+					} else {
+						// TODO: depends on nillable, which should be checked before calling this method
+						$xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
+					}
+					$this->debug("in serializeType: returning: $xml");
+					return $xml;
+				}
+		    	if ($uqType == 'boolean') {
+		    		if ((is_string($value) && $value == 'false') || (! $value)) {
+						$value = 'false';
+					} else {
+						$value = 'true';
+					}
+				} 
+				if ($uqType == 'string' && gettype($value) == 'string') {
+					$value = $this->expandEntities($value);
+				}
+				if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
+					$value = sprintf("%.0lf", $value);
+				}
+				// it's a scalar
+				// TODO: what about null/nil values?
+				// check type isn't a custom type extending xmlschema namespace
+				if (!$this->getTypeDef($uqType, $ns)) {
+					if ($use == 'literal') {
+						if ($forceType) {
+							$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
+						} else {
+							$xml = "<$name$elementNS>$value</$name>";
+						}
+					} else {
+						$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
+					}
+					$this->debug("in serializeType: returning: $xml");
+					return $xml;
+				}
+				$this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
+			} else if ($ns == 'http://xml.apache.org/xml-soap') {
+				$this->debug('in serializeType: appears to be Apache SOAP type');
+				if ($uqType == 'Map') {
+					$tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
+					if (! $tt_prefix) {
+						$this->debug('in serializeType: Add namespace for Apache SOAP type');
+						$tt_prefix = 'ns' . rand(1000, 9999);
+						$this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
+						// force this to be added to usedNamespaces
+						$tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
+					}
+					$contents = '';
+					foreach($value as $k => $v) {
+						$this->debug("serializing map element: key $k, value $v");
+						$contents .= '<item>';
+						$contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
+						$contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
+						$contents .= '</item>';
+					}
+					if ($use == 'literal') {
+						if ($forceType) {
+							$xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
+						} else {
+							$xml = "<$name>$contents</$name>";
+						}
+					} else {
+						$xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
+					}
+					$this->debug("in serializeType: returning: $xml");
+					return $xml;
+				}
+				$this->debug('in serializeType: Apache SOAP type, but only support Map');
+			}
+		} else {
+			// TODO: should the type be compared to types in XSD, and the namespace
+			// set to XSD if the type matches?
+			$this->debug("in serializeType: No namespace for type $type");
+			$ns = '';
+			$uqType = $type;
+		}
+		if(!$typeDef = $this->getTypeDef($uqType, $ns)){
+			$this->setError("$type ($uqType) is not a supported type.");
+			$this->debug("in serializeType: $type ($uqType) is not a supported type.");
+			return false;
+		} else {
+			$this->debug("in serializeType: found typeDef");
+			$this->appendDebug('typeDef=' . $this->varDump($typeDef));
+		}
+		$phpType = $typeDef['phpType'];
+		$this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); 
+		// if php type == struct, map value to the <all> element names
+		if ($phpType == 'struct') {
+			if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
+				$elementName = $uqType;
+				if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
+					$elementNS = " xmlns=\"$ns\"";
+				} else {
+					$elementNS = " xmlns=\"\"";
+				}
+			} else {
+				$elementName = $name;
+				if ($unqualified) {
+					$elementNS = " xmlns=\"\"";
+				} else {
+					$elementNS = '';
+				}
+			}
+			if (is_null($value)) {
+				if ($use == 'literal') {
+					// TODO: depends on minOccurs
+					$xml = "<$elementName$elementNS/>";
+				} else {
+					$xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
+				}
+				$this->debug("in serializeType: returning: $xml");
+				return $xml;
+			}
+			if (is_object($value)) {
+				$value = get_object_vars($value);
+			}
+			if (is_array($value)) {
+				$elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
+				if ($use == 'literal') {
+					if ($forceType) {
+						$xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
+					} else {
+						$xml = "<$elementName$elementNS$elementAttrs>";
+					}
+				} else {
+					$xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
+				}
+	
+				$xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
+				$xml .= "</$elementName>";
+			} else {
+				$this->debug("in serializeType: phpType is struct, but value is not an array");
+				$this->setError("phpType is struct, but value is not an array: see debug output for details");
+				$xml = '';
+			}
+		} elseif ($phpType == 'array') {
+			if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
+				$elementNS = " xmlns=\"$ns\"";
+			} else {
+				if ($unqualified) {
+					$elementNS = " xmlns=\"\"";
+				} else {
+					$elementNS = '';
+				}
+			}
+			if (is_null($value)) {
+				if ($use == 'literal') {
+					// TODO: depends on minOccurs
+					$xml = "<$name$elementNS/>";
+				} else {
+					$xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
+						$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
+						":Array\" " .
+						$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
+						':arrayType="' .
+						$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
+						':' .
+						$this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
+				}
+				$this->debug("in serializeType: returning: $xml");
+				return $xml;
+			}
+			if (isset($typeDef['multidimensional'])) {
+				$nv = array();
+				foreach($value as $v) {
+					$cols = ',' . sizeof($v);
+					$nv = array_merge($nv, $v);
+				} 
+				$value = $nv;
+			} else {
+				$cols = '';
+			} 
+			if (is_array($value) && sizeof($value) >= 1) {
+				$rows = sizeof($value);
+				$contents = '';
+				foreach($value as $k => $v) {
+					$this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
+					//if (strpos($typeDef['arrayType'], ':') ) {
+					if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
+					    $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
+					} else {
+					    $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
+					} 
+				}
+			} else {
+				$rows = 0;
+				$contents = null;
+			}
+			// TODO: for now, an empty value will be serialized as a zero element
+			// array.  Revisit this when coding the handling of null/nil values.
+			if ($use == 'literal') {
+				$xml = "<$name$elementNS>"
+					.$contents
+					."</$name>";
+			} else {
+				$xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
+					$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
+					.':arrayType="'
+					.$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
+					.":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
+					.$contents
+					."</$name>";
+			}
+		} elseif ($phpType == 'scalar') {
+			if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
+				$elementNS = " xmlns=\"$ns\"";
+			} else {
+				if ($unqualified) {
+					$elementNS = " xmlns=\"\"";
+				} else {
+					$elementNS = '';
+				}
+			}
+			if ($use == 'literal') {
+				if ($forceType) {
+					$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
+				} else {
+					$xml = "<$name$elementNS>$value</$name>";
+				}
+			} else {
+				$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
+			}
+		}
+		$this->debug("in serializeType: returning: $xml");
+		return $xml;
+	}
+	
+	/**
+	 * serializes the attributes for a complexType
+	 *
+	 * @param array $typeDef our internal representation of an XML schema type (or element)
+	 * @param mixed $value a native PHP value (parameter value)
+	 * @param string $ns the namespace of the type
+	 * @param string $uqType the local part of the type
+	 * @return string value serialized as an XML string
+	 * @access private
+	 */
+	function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
+		$xml = '';
+		if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
+			$this->debug("serialize attributes for XML Schema type $ns:$uqType");
+			if (is_array($value)) {
+				$xvalue = $value;
+			} elseif (is_object($value)) {
+				$xvalue = get_object_vars($value);
+			} else {
+				$this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
+				$xvalue = array();
+			}
+			foreach ($typeDef['attrs'] as $aName => $attrs) {
+				if (isset($xvalue['!' . $aName])) {
+					$xname = '!' . $aName;
+					$this->debug("value provided for attribute $aName with key $xname");
+				} elseif (isset($xvalue[$aName])) {
+					$xname = $aName;
+					$this->debug("value provided for attribute $aName with key $xname");
+				} elseif (isset($attrs['default'])) {
+					$xname = '!' . $aName;
+					$xvalue[$xname] = $attrs['default'];
+					$this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
+				} else {
+					$xname = '';
+					$this->debug("no value provided for attribute $aName");
+				}
+				if ($xname) {
+					$xml .=  " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
+				}
+			} 
+		} else {
+			$this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
+		}
+		if (isset($typeDef['extensionBase'])) {
+			$ns = $this->getPrefix($typeDef['extensionBase']);
+			$uqType = $this->getLocalPart($typeDef['extensionBase']);
+			if ($this->getNamespaceFromPrefix($ns)) {
+				$ns = $this->getNamespaceFromPrefix($ns);
+			}
+			if ($typeDef = $this->getTypeDef($uqType, $ns)) {
+				$this->debug("serialize attributes for extension base $ns:$uqType");
+				$xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
+			} else {
+				$this->debug("extension base $ns:$uqType is not a supported type");
+			}
+		}
+		return $xml;
+	}
+
+	/**
+	 * serializes the elements for a complexType
+	 *
+	 * @param array $typeDef our internal representation of an XML schema type (or element)
+	 * @param mixed $value a native PHP value (parameter value)
+	 * @param string $ns the namespace of the type
+	 * @param string $uqType the local part of the type
+	 * @param string $use use for part (encoded|literal)
+	 * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
+	 * @return string value serialized as an XML string
+	 * @access private
+	 */
+	function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
+		$xml = '';
+		if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
+			$this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
+			if (is_array($value)) {
+				$xvalue = $value;
+			} elseif (is_object($value)) {
+				$xvalue = get_object_vars($value);
+			} else {
+				$this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
+				$xvalue = array();
+			}
+			// toggle whether all elements are present - ideally should validate against schema
+			if (count($typeDef['elements']) != count($xvalue)){
+				$optionals = true;
+			}
+			foreach ($typeDef['elements'] as $eName => $attrs) {
+				if (!isset($xvalue[$eName])) {
+					if (isset($attrs['default'])) {
+						$xvalue[$eName] = $attrs['default'];
+						$this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
+					}
+				}
+				// if user took advantage of a minOccurs=0, then only serialize named parameters
+				if (isset($optionals)
+				    && (!isset($xvalue[$eName])) 
+					&& ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
+					){
+					if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
+						$this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
+					}
+					// do nothing
+					$this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
+				} else {
+					// get value
+					if (isset($xvalue[$eName])) {
+					    $v = $xvalue[$eName];
+					} else {
+					    $v = null;
+					}
+					if (isset($attrs['form'])) {
+						$unqualified = ($attrs['form'] == 'unqualified');
+					} else {
+						$unqualified = false;
+					}
+					if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
+						$vv = $v;
+						foreach ($vv as $k => $v) {
+							if (isset($attrs['type']) || isset($attrs['ref'])) {
+								// serialize schema-defined type
+							    $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
+							} else {
+								// serialize generic type (can this ever really happen?)
+							    $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
+							    $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
+							}
+						}
+					} else {
+						if (isset($attrs['type']) || isset($attrs['ref'])) {
+							// serialize schema-defined type
+						    $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
+						} else {
+							// serialize generic type (can this ever really happen?)
+						    $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
+						    $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
+						}
+					}
+				}
+			} 
+		} else {
+			$this->debug("no elements to serialize for XML Schema type $ns:$uqType");
+		}
+		if (isset($typeDef['extensionBase'])) {
+			$ns = $this->getPrefix($typeDef['extensionBase']);
+			$uqType = $this->getLocalPart($typeDef['extensionBase']);
+			if ($this->getNamespaceFromPrefix($ns)) {
+				$ns = $this->getNamespaceFromPrefix($ns);
+			}
+			if ($typeDef = $this->getTypeDef($uqType, $ns)) {
+				$this->debug("serialize elements for extension base $ns:$uqType");
+				$xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
+			} else {
+				$this->debug("extension base $ns:$uqType is not a supported type");
+			}
+		}
+		return $xml;
+	}
+
+	/**
+	* adds an XML Schema complex type to the WSDL types
+	*
+	* @param string	name
+	* @param string typeClass (complexType|simpleType|attribute)
+	* @param string phpType: currently supported are array and struct (php assoc array)
+	* @param string compositor (all|sequence|choice)
+	* @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+	* @param array elements = array ( name => array(name=>'',type=>'') )
+	* @param array attrs = 	array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))
+	* @param string arrayType: namespace:name (xsd:string)
+	* @see xmlschema
+	* @access public
+	*/
+	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
+		if (count($elements) > 0) {
+	    	foreach($elements as $n => $e){
+	            // expand each element
+	            foreach ($e as $k => $v) {
+		            $k = strpos($k,':') ? $this->expandQname($k) : $k;
+		            $v = strpos($v,':') ? $this->expandQname($v) : $v;
+		            $ee[$k] = $v;
+		    	}
+	    		$eElements[$n] = $ee;
+	    	}
+	    	$elements = $eElements;
+		}
+		
+		if (count($attrs) > 0) {
+	    	foreach($attrs as $n => $a){
+	            // expand each attribute
+	            foreach ($a as $k => $v) {
+		            $k = strpos($k,':') ? $this->expandQname($k) : $k;
+		            $v = strpos($v,':') ? $this->expandQname($v) : $v;
+		            $aa[$k] = $v;
+		    	}
+	    		$eAttrs[$n] = $aa;
+	    	}
+	    	$attrs = $eAttrs;
+		}
+
+		$restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
+		$arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
+
+		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
+		$this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
+	}
+
+	/**
+	* adds an XML Schema simple type to the WSDL types
+	*
+	* @param string $name
+	* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+	* @param string $typeClass (should always be simpleType)
+	* @param string $phpType (should always be scalar)
+	* @param array $enumeration array of values
+	* @see xmlschema
+	* @access public
+	*/
+	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
+		$restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
+
+		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
+		$this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
+	}
+
+	/**
+	* adds an element to the WSDL types
+	*
+	* @param array $attrs attributes that must include name and type
+	* @see xmlschema
+	* @access public
+	*/
+	function addElement($attrs) {
+		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
+		$this->schemas[$typens][0]->addElement($attrs);
+	}
+
+	/**
+	* register an operation with the server
+	* 
+	* @param string $name operation (method) name
+	* @param array $in assoc array of input values: key = param name, value = param type
+	* @param array $out assoc array of output values: key = param name, value = param type
+	* @param string $namespace optional The namespace for the operation
+	* @param string $soapaction optional The soapaction for the operation
+	* @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically
+	* @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now)
+	* @param string $documentation optional The description to include in the WSDL
+	* @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
+	* @access public 
+	*/
+	function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
+		if ($use == 'encoded' && $encodingStyle == '') {
+			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+		}
+
+		if ($style == 'document') {
+			$elements = array();
+			foreach ($in as $n => $t) {
+				$elements[$n] = array('name' => $n, 'type' => $t);
+			}
+			$this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
+			$this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
+			$in = array('parameters' => 'tns:' . $name);
+
+			$elements = array();
+			foreach ($out as $n => $t) {
+				$elements[$n] = array('name' => $n, 'type' => $t);
+			}
+			$this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
+			$this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType'));
+			$out = array('parameters' => 'tns:' . $name . 'Response');
+		}
+
+		// get binding
+		$this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
+		array(
+		'name' => $name,
+		'binding' => $this->serviceName . 'Binding',
+		'endpoint' => $this->endpoint,
+		'soapAction' => $soapaction,
+		'style' => $style,
+		'input' => array(
+			'use' => $use,
+			'namespace' => $namespace,
+			'encodingStyle' => $encodingStyle,
+			'message' => $name . 'Request',
+			'parts' => $in),
+		'output' => array(
+			'use' => $use,
+			'namespace' => $namespace,
+			'encodingStyle' => $encodingStyle,
+			'message' => $name . 'Response',
+			'parts' => $out),
+		'namespace' => $namespace,
+		'transport' => 'http://schemas.xmlsoap.org/soap/http',
+		'documentation' => $documentation); 
+		// add portTypes
+		// add messages
+		if($in)
+		{
+			foreach($in as $pName => $pType)
+			{
+				if(strpos($pType,':')) {
+					$pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
+				}
+				$this->messages[$name.'Request'][$pName] = $pType;
+			}
+		} else {
+            $this->messages[$name.'Request']= '0';
+        }
+		if($out)
+		{
+			foreach($out as $pName => $pType)
+			{
+				if(strpos($pType,':')) {
+					$pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
+				}
+				$this->messages[$name.'Response'][$pName] = $pType;
+			}
+		} else {
+            $this->messages[$name.'Response']= '0';
+        }
+		return true;
+	} 
+}
+
 ?>
\ No newline at end of file
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.wsdlcache.php b/htdocs/oscommerce_ws/ws_server/lib/class.wsdlcache.php
index 54956e5f262ed70aaea3a70e514a0a3494fbd5c8..8326b506d624c9f1d83bad65ad118125ab70656e 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.wsdlcache.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.wsdlcache.php
@@ -1,184 +1,184 @@
-<?php
-
-
-
-/**
-* caches instances of the wsdl class
-* 
-* @author   Scott Nichol <snichol@computer.org>
-* @author	Ingo Fischer <ingo@apollon.de>
-* @version  $Id$
-* @access public 
-*/
-class wsdlcache {
-	/**
-	 *	@var resource
-	 *	@access private
-	 */
-	var $fplock;
-	/**
-	 *	@var integer
-	 *	@access private
-	 */
-	var $cache_lifetime;
-	/**
-	 *	@var string
-	 *	@access private
-	 */
-	var $cache_dir;
-	/**
-	 *	@var string
-	 *	@access public
-	 */
-	var $debug_str = '';
-
-	/**
-	* constructor
-	*
-	* @param string $cache_dir directory for cache-files
-	* @param integer $cache_lifetime lifetime for caching-files in seconds or 0 for unlimited
-	* @access public
-	*/
-	function wsdlcache($cache_dir='.', $cache_lifetime=0) {
-		$this->fplock = array();
-		$this->cache_dir = $cache_dir != '' ? $cache_dir : '.';
-		$this->cache_lifetime = $cache_lifetime;
-	}
-
-	/**
-	* creates the filename used to cache a wsdl instance
-	*
-	* @param string $wsdl The URL of the wsdl instance
-	* @return string The filename used to cache the instance
-	* @access private
-	*/
-	function createFilename($wsdl) {
-		return $this->cache_dir.'/wsdlcache-' . md5($wsdl);
-	}
-
-	/**
-	* adds debug data to the class level debug string
-	*
-	* @param    string $string debug data
-	* @access   private
-	*/
-	function debug($string){
-		$this->debug_str .= get_class($this).": $string\n";
-	}
-
-	/**
-	* gets a wsdl instance from the cache
-	*
-	* @param string $wsdl The URL of the wsdl instance
-	* @return object wsdl The cached wsdl instance, null if the instance is not in the cache
-	* @access public
-	*/
-	function get($wsdl) {
-		$filename = $this->createFilename($wsdl);
-		if ($this->obtainMutex($filename, "r")) {
-			// check for expired WSDL that must be removed from the cache
- 			if ($this->cache_lifetime > 0) {
-				if (file_exists($filename) && (time() - filemtime($filename) > $this->cache_lifetime)) {
-					unlink($filename);
-					$this->debug("Expired $wsdl ($filename) from cache");
-					$this->releaseMutex($filename);
-					return null;
-  				}
-			}
-			// see what there is to return
-			$fp = @fopen($filename, "r");
-			if ($fp) {
-				$s = implode("", @file($filename));
-				fclose($fp);
-				$this->debug("Got $wsdl ($filename) from cache");
-			} else {
-				$s = null;
-				$this->debug("$wsdl ($filename) not in cache");
-			}
-			$this->releaseMutex($filename);
-			return (!is_null($s)) ? unserialize($s) : null;
-		} else {
-			$this->debug("Unable to obtain mutex for $filename in get");
-		}
-		return null;
-	}
-
-	/**
-	* obtains the local mutex
-	*
-	* @param string $filename The Filename of the Cache to lock
-	* @param string $mode The open-mode ("r" or "w") or the file - affects lock-mode
-	* @return boolean Lock successfully obtained ?!
-	* @access private
-	*/
-	function obtainMutex($filename, $mode) {
-		if (isset($this->fplock[md5($filename)])) {
-			$this->debug("Lock for $filename already exists");
-			return false;
-		}
-		$this->fplock[md5($filename)] = fopen($filename.".lock", "w");
-		if ($mode == "r") {
-			return flock($this->fplock[md5($filename)], LOCK_SH);
-		} else {
-			return flock($this->fplock[md5($filename)], LOCK_EX);
-		}
-	}
-
-	/**
-	* adds a wsdl instance to the cache
-	*
-	* @param object wsdl $wsdl_instance The wsdl instance to add
-	* @return boolean WSDL successfully cached
-	* @access public
-	*/
-	function put($wsdl_instance) {
-		$filename = $this->createFilename($wsdl_instance->wsdl);
-		$s = serialize($wsdl_instance);
-		if ($this->obtainMutex($filename, "w")) {
-			$fp = fopen($filename, "w");
-			fputs($fp, $s);
-			fclose($fp);
-			$this->debug("Put $wsdl_instance->wsdl ($filename) in cache");
-			$this->releaseMutex($filename);
-			return true;
-		} else {
-			$this->debug("Unable to obtain mutex for $filename in put");
-		}
-		return false;
-	}
-
-	/**
-	* releases the local mutex
-	*
-	* @param string $filename The Filename of the Cache to lock
-	* @return boolean Lock successfully released
-	* @access private
-	*/
-	function releaseMutex($filename) {
-		$ret = flock($this->fplock[md5($filename)], LOCK_UN);
-		fclose($this->fplock[md5($filename)]);
-		unset($this->fplock[md5($filename)]);
-		if (! $ret) {
-			$this->debug("Not able to release lock for $filename");
-		}
-		return $ret;
-	}
-
-	/**
-	* removes a wsdl instance from the cache
-	*
-	* @param string $wsdl The URL of the wsdl instance
-	* @return boolean Whether there was an instance to remove
-	* @access public
-	*/
-	function remove($wsdl) {
-		$filename = $this->createFilename($wsdl);
-		// ignore errors obtaining mutex
-		$this->obtainMutex($filename, "w");
-		$ret = unlink($filename);
-		$this->debug("Removed ($ret) $wsdl ($filename) from cache");
-		$this->releaseMutex($filename);
-		return $ret;
-	}
-}
-?>
+<?php
+
+
+
+/**
+* caches instances of the wsdl class
+* 
+* @author   Scott Nichol <snichol@computer.org>
+* @author	Ingo Fischer <ingo@apollon.de>
+* @version  $Id$
+* @access public 
+*/
+class wsdlcache {
+	/**
+	 *	@var resource
+	 *	@access private
+	 */
+	var $fplock;
+	/**
+	 *	@var integer
+	 *	@access private
+	 */
+	var $cache_lifetime;
+	/**
+	 *	@var string
+	 *	@access private
+	 */
+	var $cache_dir;
+	/**
+	 *	@var string
+	 *	@access public
+	 */
+	var $debug_str = '';
+
+	/**
+	* constructor
+	*
+	* @param string $cache_dir directory for cache-files
+	* @param integer $cache_lifetime lifetime for caching-files in seconds or 0 for unlimited
+	* @access public
+	*/
+	function wsdlcache($cache_dir='.', $cache_lifetime=0) {
+		$this->fplock = array();
+		$this->cache_dir = $cache_dir != '' ? $cache_dir : '.';
+		$this->cache_lifetime = $cache_lifetime;
+	}
+
+	/**
+	* creates the filename used to cache a wsdl instance
+	*
+	* @param string $wsdl The URL of the wsdl instance
+	* @return string The filename used to cache the instance
+	* @access private
+	*/
+	function createFilename($wsdl) {
+		return $this->cache_dir.'/wsdlcache-' . md5($wsdl);
+	}
+
+	/**
+	* adds debug data to the class level debug string
+	*
+	* @param    string $string debug data
+	* @access   private
+	*/
+	function debug($string){
+		$this->debug_str .= get_class($this).": $string\n";
+	}
+
+	/**
+	* gets a wsdl instance from the cache
+	*
+	* @param string $wsdl The URL of the wsdl instance
+	* @return object wsdl The cached wsdl instance, null if the instance is not in the cache
+	* @access public
+	*/
+	function get($wsdl) {
+		$filename = $this->createFilename($wsdl);
+		if ($this->obtainMutex($filename, "r")) {
+			// check for expired WSDL that must be removed from the cache
+ 			if ($this->cache_lifetime > 0) {
+				if (file_exists($filename) && (time() - filemtime($filename) > $this->cache_lifetime)) {
+					unlink($filename);
+					$this->debug("Expired $wsdl ($filename) from cache");
+					$this->releaseMutex($filename);
+					return null;
+  				}
+			}
+			// see what there is to return
+			$fp = @fopen($filename, "r");
+			if ($fp) {
+				$s = implode("", @file($filename));
+				fclose($fp);
+				$this->debug("Got $wsdl ($filename) from cache");
+			} else {
+				$s = null;
+				$this->debug("$wsdl ($filename) not in cache");
+			}
+			$this->releaseMutex($filename);
+			return (!is_null($s)) ? unserialize($s) : null;
+		} else {
+			$this->debug("Unable to obtain mutex for $filename in get");
+		}
+		return null;
+	}
+
+	/**
+	* obtains the local mutex
+	*
+	* @param string $filename The Filename of the Cache to lock
+	* @param string $mode The open-mode ("r" or "w") or the file - affects lock-mode
+	* @return boolean Lock successfully obtained ?!
+	* @access private
+	*/
+	function obtainMutex($filename, $mode) {
+		if (isset($this->fplock[md5($filename)])) {
+			$this->debug("Lock for $filename already exists");
+			return false;
+		}
+		$this->fplock[md5($filename)] = fopen($filename.".lock", "w");
+		if ($mode == "r") {
+			return flock($this->fplock[md5($filename)], LOCK_SH);
+		} else {
+			return flock($this->fplock[md5($filename)], LOCK_EX);
+		}
+	}
+
+	/**
+	* adds a wsdl instance to the cache
+	*
+	* @param object wsdl $wsdl_instance The wsdl instance to add
+	* @return boolean WSDL successfully cached
+	* @access public
+	*/
+	function put($wsdl_instance) {
+		$filename = $this->createFilename($wsdl_instance->wsdl);
+		$s = serialize($wsdl_instance);
+		if ($this->obtainMutex($filename, "w")) {
+			$fp = fopen($filename, "w");
+			fputs($fp, $s);
+			fclose($fp);
+			$this->debug("Put $wsdl_instance->wsdl ($filename) in cache");
+			$this->releaseMutex($filename);
+			return true;
+		} else {
+			$this->debug("Unable to obtain mutex for $filename in put");
+		}
+		return false;
+	}
+
+	/**
+	* releases the local mutex
+	*
+	* @param string $filename The Filename of the Cache to lock
+	* @return boolean Lock successfully released
+	* @access private
+	*/
+	function releaseMutex($filename) {
+		$ret = flock($this->fplock[md5($filename)], LOCK_UN);
+		fclose($this->fplock[md5($filename)]);
+		unset($this->fplock[md5($filename)]);
+		if (! $ret) {
+			$this->debug("Not able to release lock for $filename");
+		}
+		return $ret;
+	}
+
+	/**
+	* removes a wsdl instance from the cache
+	*
+	* @param string $wsdl The URL of the wsdl instance
+	* @return boolean Whether there was an instance to remove
+	* @access public
+	*/
+	function remove($wsdl) {
+		$filename = $this->createFilename($wsdl);
+		// ignore errors obtaining mutex
+		$this->obtainMutex($filename, "w");
+		$ret = unlink($filename);
+		$this->debug("Removed ($ret) $wsdl ($filename) from cache");
+		$this->releaseMutex($filename);
+		return $ret;
+	}
+}
+?>
diff --git a/htdocs/oscommerce_ws/ws_server/lib/class.xmlschema.php b/htdocs/oscommerce_ws/ws_server/lib/class.xmlschema.php
index f390959aa1e89a5d56acf4282a018a741744f286..db1ba0b2c46d5cfb4754f2b1571be028aa476ebd 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/class.xmlschema.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/class.xmlschema.php
@@ -1,906 +1,906 @@
-<?php
-
-
-
-
-/**
-* parses an XML Schema, allows access to it's data, other utility methods
-* no validation... yet.
-* very experimental and limited. As is discussed on XML-DEV, I'm one of the people
-* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
-* tutorials I refer to :)
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class XMLSchema extends nusoap_base  {
-	
-	// files
-	var $schema = '';
-	var $xml = '';
-	// namespaces
-	var $enclosingNamespaces;
-	// schema info
-	var $schemaInfo = array();
-	var $schemaTargetNamespace = '';
-	// types, elements, attributes defined by the schema
-	var $attributes = array();
-	var $complexTypes = array();
-	var $complexTypeStack = array();
-	var $currentComplexType = null;
-	var $elements = array();
-	var $elementStack = array();
-	var $currentElement = null;
-	var $simpleTypes = array();
-	var $simpleTypeStack = array();
-	var $currentSimpleType = null;
-	// imports
-	var $imports = array();
-	// parser vars
-	var $parser;
-	var $position = 0;
-	var $depth = 0;
-	var $depth_array = array();
-	var $message = array();
-	var $defaultNamespace = array();
-    
-	/**
-	* constructor
-	*
-	* @param    string $schema schema document URI
-	* @param    string $xml xml document URI
-	* @param	string $namespaces namespaces defined in enclosing XML
-	* @access   public
-	*/
-	function XMLSchema($schema='',$xml='',$namespaces=array()){
-		parent::nusoap_base();
-		$this->debug('xmlschema class instantiated, inside constructor');
-		// files
-		$this->schema = $schema;
-		$this->xml = $xml;
-
-		// namespaces
-		$this->enclosingNamespaces = $namespaces;
-		$this->namespaces = array_merge($this->namespaces, $namespaces);
-
-		// parse schema file
-		if($schema != ''){
-			$this->debug('initial schema file: '.$schema);
-			$this->parseFile($schema, 'schema');
-		}
-
-		// parse xml file
-		if($xml != ''){
-			$this->debug('initial xml file: '.$xml);
-			$this->parseFile($xml, 'xml');
-		}
-
-	}
-
-    /**
-    * parse an XML file
-    *
-    * @param string $xml, path/URL to XML file
-    * @param string $type, (schema | xml)
-	* @return boolean
-    * @access public
-    */
-	function parseFile($xml,$type){
-		// parse xml file
-		if($xml != ""){
-			$xmlStr = @join("",@file($xml));
-			if($xmlStr == ""){
-				$msg = 'Error reading XML from '.$xml;
-				$this->setError($msg);
-				$this->debug($msg);
-			return false;
-			} else {
-				$this->debug("parsing $xml");
-				$this->parseString($xmlStr,$type);
-				$this->debug("done parsing $xml");
-			return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	* parse an XML string
-	*
-	* @param    string $xml path or URL
-    * @param string $type, (schema|xml)
-	* @access   private
-	*/
-	function parseString($xml,$type){
-		// parse xml string
-		if($xml != ""){
-
-	    	// Create an XML parser.
-	    	$this->parser = xml_parser_create();
-	    	// Set the options for parsing the XML data.
-	    	xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
-
-	    	// Set the object for the parser.
-	    	xml_set_object($this->parser, $this);
-
-	    	// Set the element handlers for the parser.
-			if($type == "schema"){
-		    	xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
-		    	xml_set_character_data_handler($this->parser,'schemaCharacterData');
-			} elseif($type == "xml"){
-				xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
-		    	xml_set_character_data_handler($this->parser,'xmlCharacterData');
-			}
-
-		    // Parse the XML file.
-		    if(!xml_parse($this->parser,$xml,true)){
-			// Display an error message.
-				$errstr = sprintf('XML error parsing XML schema on line %d: %s',
-				xml_get_current_line_number($this->parser),
-				xml_error_string(xml_get_error_code($this->parser))
-				);
-				$this->debug($errstr);
-				$this->debug("XML payload:\n" . $xml);
-				$this->setError($errstr);
-	    	}
-            
-			xml_parser_free($this->parser);
-		} else{
-			$this->debug('no xml passed to parseString()!!');
-			$this->setError('no xml passed to parseString()!!');
-		}
-	}
-
-	/**
-	* start-element handler
-	*
-	* @param    string $parser XML parser object
-	* @param    string $name element name
-	* @param    string $attrs associative array of attributes
-	* @access   private
-	*/
-	function schemaStartElement($parser, $name, $attrs) {
-		
-		// position in the total number of elements, starting from 0
-		$pos = $this->position++;
-		$depth = $this->depth++;
-		// set self as current value for this depth
-		$this->depth_array[$depth] = $pos;
-		$this->message[$pos] = array('cdata' => ''); 
-		if ($depth > 0) {
-			$this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
-		} else {
-			$this->defaultNamespace[$pos] = false;
-		}
-
-		// get element prefix
-		if($prefix = $this->getPrefix($name)){
-			// get unqualified name
-			$name = $this->getLocalPart($name);
-		} else {
-        	$prefix = '';
-        }
-		
-        // loop thru attributes, expanding, and registering namespace declarations
-        if(count($attrs) > 0){
-        	foreach($attrs as $k => $v){
-                // if ns declarations, add to class level array of valid namespaces
-				if(ereg("^xmlns",$k)){
-                	//$this->xdebug("$k: $v");
-                	//$this->xdebug('ns_prefix: '.$this->getPrefix($k));
-                	if($ns_prefix = substr(strrchr($k,':'),1)){
-                		//$this->xdebug("Add namespace[$ns_prefix] = $v");
-						$this->namespaces[$ns_prefix] = $v;
-					} else {
-						$this->defaultNamespace[$pos] = $v;
-						if (! $this->getPrefixFromNamespace($v)) {
-							$this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
-						}
-					}
-					if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
-						$this->XMLSchemaVersion = $v;
-						$this->namespaces['xsi'] = $v.'-instance';
-					}
-				}
-        	}
-        	foreach($attrs as $k => $v){
-                // expand each attribute
-                $k = strpos($k,':') ? $this->expandQname($k) : $k;
-                $v = strpos($v,':') ? $this->expandQname($v) : $v;
-        		$eAttrs[$k] = $v;
-        	}
-        	$attrs = $eAttrs;
-        } else {
-        	$attrs = array();
-        }
-		// find status, register data
-		switch($name){
-			case 'all':			// (optional) compositor content for a complexType
-			case 'choice':
-			case 'group':
-			case 'sequence':
-				//$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
-				$this->complexTypes[$this->currentComplexType]['compositor'] = $name;
-				//if($name == 'all' || $name == 'sequence'){
-				//	$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
-				//}
-			break;
-			case 'attribute':	// complexType attribute
-            	//$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
-            	$this->xdebug("parsing attribute:");
-            	$this->appendDebug($this->varDump($attrs));
-				if (!isset($attrs['form'])) {
-					$attrs['form'] = $this->schemaInfo['attributeFormDefault'];
-				}
-            	if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
-					$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
-					if (!strpos($v, ':')) {
-						// no namespace in arrayType attribute value...
-						if ($this->defaultNamespace[$pos]) {
-							// ...so use the default
-							$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
-						}
-					}
-            	}
-                if(isset($attrs['name'])){
-					$this->attributes[$attrs['name']] = $attrs;
-					$aname = $attrs['name'];
-				} elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
-					if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
-	                	$aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
-	                } else {
-	                	$aname = '';
-	                }
-				} elseif(isset($attrs['ref'])){
-					$aname = $attrs['ref'];
-                    $this->attributes[$attrs['ref']] = $attrs;
-				}
-                
-				if($this->currentComplexType){	// This should *always* be
-					$this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
-				}
-				// arrayType attribute
-				if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
-					$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
-                	$prefix = $this->getPrefix($aname);
-					if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
-						$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
-					} else {
-						$v = '';
-					}
-                    if(strpos($v,'[,]')){
-                        $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
-                    }
-                    $v = substr($v,0,strpos($v,'[')); // clip the []
-                    if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
-                        $v = $this->XMLSchemaVersion.':'.$v;
-                    }
-                    $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
-				}
-			break;
-			case 'complexContent':	// (optional) content for a complexType
-			break;
-			case 'complexType':
-				array_push($this->complexTypeStack, $this->currentComplexType);
-				if(isset($attrs['name'])){
-					$this->xdebug('processing named complexType '.$attrs['name']);
-					//$this->currentElement = false;
-					$this->currentComplexType = $attrs['name'];
-					$this->complexTypes[$this->currentComplexType] = $attrs;
-					$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
-					// This is for constructs like
-					//           <complexType name="ListOfString" base="soap:Array">
-					//                <sequence>
-					//                    <element name="string" type="xsd:string"
-					//                        minOccurs="0" maxOccurs="unbounded" />
-					//                </sequence>
-					//            </complexType>
-					if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
-						$this->xdebug('complexType is unusual array');
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
-					} else {
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
-					}
-				}else{
-					$this->xdebug('processing unnamed complexType for element '.$this->currentElement);
-					$this->currentComplexType = $this->currentElement . '_ContainedType';
-					//$this->currentElement = false;
-					$this->complexTypes[$this->currentComplexType] = $attrs;
-					$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
-					// This is for constructs like
-					//           <complexType name="ListOfString" base="soap:Array">
-					//                <sequence>
-					//                    <element name="string" type="xsd:string"
-					//                        minOccurs="0" maxOccurs="unbounded" />
-					//                </sequence>
-					//            </complexType>
-					if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
-						$this->xdebug('complexType is unusual array');
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
-					} else {
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
-					}
-				}
-			break;
-			case 'element':
-				array_push($this->elementStack, $this->currentElement);
-				// elements defined as part of a complex type should
-				// not really be added to $this->elements, but for some
-				// reason, they are
-				if (!isset($attrs['form'])) {
-					$attrs['form'] = $this->schemaInfo['elementFormDefault'];
-				}
-				if(isset($attrs['type'])){
-					$this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
-					if (! $this->getPrefix($attrs['type'])) {
-						if ($this->defaultNamespace[$pos]) {
-							$attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
-							$this->xdebug('used default namespace to make type ' . $attrs['type']);
-						}
-					}
-					// This is for constructs like
-					//           <complexType name="ListOfString" base="soap:Array">
-					//                <sequence>
-					//                    <element name="string" type="xsd:string"
-					//                        minOccurs="0" maxOccurs="unbounded" />
-					//                </sequence>
-					//            </complexType>
-					if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
-						$this->xdebug('arrayType for unusual array is ' . $attrs['type']);
-						$this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
-					}
-					$this->currentElement = $attrs['name'];
-					$this->elements[ $attrs['name'] ] = $attrs;
-					$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
-					$ename = $attrs['name'];
-				} elseif(isset($attrs['ref'])){
-					$this->xdebug("processing element as ref to ".$attrs['ref']);
-					$this->currentElement = "ref to ".$attrs['ref'];
-					$ename = $this->getLocalPart($attrs['ref']);
-				} else {
-					$this->xdebug("processing untyped element ".$attrs['name']);
-					$this->currentElement = $attrs['name'];
-					$this->elements[ $attrs['name'] ] = $attrs;
-					$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
-					$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
-					$this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
-					$ename = $attrs['name'];
-				}
-				if(isset($ename) && $this->currentComplexType){
-					$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
-				}
-			break;
-			case 'enumeration':	//	restriction value list member
-				$this->xdebug('enumeration ' . $attrs['value']);
-				if ($this->currentSimpleType) {
-					$this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
-				} elseif ($this->currentComplexType) {
-					$this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
-				}
-			break;
-			case 'extension':	// simpleContent or complexContent type extension
-				$this->xdebug('extension ' . $attrs['base']);
-				if ($this->currentComplexType) {
-					$this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
-				}
-			break;
-			case 'import':
-			    if (isset($attrs['schemaLocation'])) {
-					//$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
-                    $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
-				} else {
-					//$this->xdebug('import namespace ' . $attrs['namespace']);
-                    $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
-					if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
-						$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
-					}
-				}
-			break;
-			case 'list':	// simpleType value list
-			break;
-			case 'restriction':	// simpleType, simpleContent or complexContent value restriction
-				$this->xdebug('restriction ' . $attrs['base']);
-				if($this->currentSimpleType){
-					$this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
-				} elseif($this->currentComplexType){
-					$this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
-					if(strstr($attrs['base'],':') == ':Array'){
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
-					}
-				}
-			break;
-			case 'schema':
-				$this->schemaInfo = $attrs;
-				$this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
-				if (isset($attrs['targetNamespace'])) {
-					$this->schemaTargetNamespace = $attrs['targetNamespace'];
-				}
-				if (!isset($attrs['elementFormDefault'])) {
-					$this->schemaInfo['elementFormDefault'] = 'unqualified';
-				}
-				if (!isset($attrs['attributeFormDefault'])) {
-					$this->schemaInfo['attributeFormDefault'] = 'unqualified';
-				}
-			break;
-			case 'simpleContent':	// (optional) content for a complexType
-			break;
-			case 'simpleType':
-				array_push($this->simpleTypeStack, $this->currentSimpleType);
-				if(isset($attrs['name'])){
-					$this->xdebug("processing simpleType for name " . $attrs['name']);
-					$this->currentSimpleType = $attrs['name'];
-					$this->simpleTypes[ $attrs['name'] ] = $attrs;
-					$this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
-					$this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
-				} else {
-					$this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
-					$this->currentSimpleType = $this->currentElement . '_ContainedType';
-					//$this->currentElement = false;
-					$this->simpleTypes[$this->currentSimpleType] = $attrs;
-					$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
-				}
-			break;
-			case 'union':	// simpleType type list
-			break;
-			default:
-				//$this->xdebug("do not have anything to do for element $name");
-		}
-	}
-
-	/**
-	* end-element handler
-	*
-	* @param    string $parser XML parser object
-	* @param    string $name element name
-	* @access   private
-	*/
-	function schemaEndElement($parser, $name) {
-		// bring depth down a notch
-		$this->depth--;
-		// position of current element is equal to the last value left in depth_array for my depth
-		if(isset($this->depth_array[$this->depth])){
-        	$pos = $this->depth_array[$this->depth];
-        }
-		// get element prefix
-		if ($prefix = $this->getPrefix($name)){
-			// get unqualified name
-			$name = $this->getLocalPart($name);
-		} else {
-        	$prefix = '';
-        }
-		// move on...
-		if($name == 'complexType'){
-			$this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
-			$this->currentComplexType = array_pop($this->complexTypeStack);
-			//$this->currentElement = false;
-		}
-		if($name == 'element'){
-			$this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
-			$this->currentElement = array_pop($this->elementStack);
-		}
-		if($name == 'simpleType'){
-			$this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
-			$this->currentSimpleType = array_pop($this->simpleTypeStack);
-		}
-	}
-
-	/**
-	* element content handler
-	*
-	* @param    string $parser XML parser object
-	* @param    string $data element content
-	* @access   private
-	*/
-	function schemaCharacterData($parser, $data){
-		$pos = $this->depth_array[$this->depth - 1];
-		$this->message[$pos]['cdata'] .= $data;
-	}
-
-	/**
-	* serialize the schema
-	*
-	* @access   public
-	*/
-	function serializeSchema(){
-
-		$schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
-		$xml = '';
-		// imports
-		if (sizeof($this->imports) > 0) {
-			foreach($this->imports as $ns => $list) {
-				foreach ($list as $ii) {
-					if ($ii['location'] != '') {
-						$xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
-					} else {
-						$xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
-					}
-				}
-			} 
-		} 
-		// complex types
-		foreach($this->complexTypes as $typeName => $attrs){
-			$contentStr = '';
-			// serialize child elements
-			if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
-				foreach($attrs['elements'] as $element => $eParts){
-					if(isset($eParts['ref'])){
-						$contentStr .= "   <$schemaPrefix:element ref=\"$element\"/>\n";
-					} else {
-						$contentStr .= "   <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
-						foreach ($eParts as $aName => $aValue) {
-							// handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
-							if ($aName != 'name' && $aName != 'type') {
-								$contentStr .= " $aName=\"$aValue\"";
-							}
-						}
-						$contentStr .= "/>\n";
-					}
-				}
-				// compositor wraps elements
-				if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
-					$contentStr = "  <$schemaPrefix:$attrs[compositor]>\n".$contentStr."  </$schemaPrefix:$attrs[compositor]>\n";
-				}
-			}
-			// attributes
-			if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
-				foreach($attrs['attrs'] as $attr => $aParts){
-					$contentStr .= "    <$schemaPrefix:attribute";
-					foreach ($aParts as $a => $v) {
-						if ($a == 'ref' || $a == 'type') {
-							$contentStr .= " $a=\"".$this->contractQName($v).'"';
-						} elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
-							$this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
-							$contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
-						} else {
-							$contentStr .= " $a=\"$v\"";
-						}
-					}
-					$contentStr .= "/>\n";
-				}
-			}
-			// if restriction
-			if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
-				$contentStr = "   <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr."   </$schemaPrefix:restriction>\n";
-				// complex or simple content
-				if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
-					$contentStr = "  <$schemaPrefix:complexContent>\n".$contentStr."  </$schemaPrefix:complexContent>\n";
-				}
-			}
-			// finalize complex type
-			if($contentStr != ''){
-				$contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
-			} else {
-				$contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
-			}
-			$xml .= $contentStr;
-		}
-		// simple types
-		if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
-			foreach($this->simpleTypes as $typeName => $eParts){
-				$xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n  <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
-				if (isset($eParts['enumeration'])) {
-					foreach ($eParts['enumeration'] as $e) {
-						$xml .= "  <$schemaPrefix:enumeration value=\"$e\"/>\n";
-					}
-				}
-				$xml .= " </$schemaPrefix:simpleType>";
-			}
-		}
-		// elements
-		if(isset($this->elements) && count($this->elements) > 0){
-			foreach($this->elements as $element => $eParts){
-				$xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
-			}
-		}
-		// attributes
-		if(isset($this->attributes) && count($this->attributes) > 0){
-			foreach($this->attributes as $attr => $aParts){
-				$xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
-			}
-		}
-		// finish 'er up
-		$el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
-		foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
-			$el .= " xmlns:$nsp=\"$ns\"\n";
-		}
-		$xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
-		return $xml;
-	}
-
-	/**
-	* adds debug data to the clas level debug string
-	*
-	* @param    string $string debug data
-	* @access   private
-	*/
-	function xdebug($string){
-		$this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
-	}
-
-    /**
-    * get the PHP type of a user defined type in the schema
-    * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
-    * returns false if no type exists, or not w/ the given namespace
-    * else returns a string that is either a native php type, or 'struct'
-    *
-    * @param string $type, name of defined type
-    * @param string $ns, namespace of type
-    * @return mixed
-    * @access public
-    * @deprecated
-    */
-	function getPHPType($type,$ns){
-		if(isset($this->typemap[$ns][$type])){
-			//print "found type '$type' and ns $ns in typemap<br>";
-			return $this->typemap[$ns][$type];
-		} elseif(isset($this->complexTypes[$type])){
-			//print "getting type '$type' and ns $ns from complexTypes array<br>";
-			return $this->complexTypes[$type]['phpType'];
-		}
-		return false;
-	}
-
-	/**
-    * returns an associative array of information about a given type
-    * returns false if no type exists by the given name
-    *
-	*	For a complexType typeDef = array(
-	*	'restrictionBase' => '',
-	*	'phpType' => '',
-	*	'compositor' => '(sequence|all)',
-	*	'elements' => array(), // refs to elements array
-	*	'attrs' => array() // refs to attributes array
-	*	... and so on (see addComplexType)
-	*	)
-	*
-	*   For simpleType or element, the array has different keys.
-    *
-    * @param string
-    * @return mixed
-    * @access public
-    * @see addComplexType
-    * @see addSimpleType
-    * @see addElement
-    */
-	function getTypeDef($type){
-		//$this->debug("in getTypeDef for type $type");
-		if(isset($this->complexTypes[$type])){
-			$this->xdebug("in getTypeDef, found complexType $type");
-			return $this->complexTypes[$type];
-		} elseif(isset($this->simpleTypes[$type])){
-			$this->xdebug("in getTypeDef, found simpleType $type");
-			if (!isset($this->simpleTypes[$type]['phpType'])) {
-				// get info for type to tack onto the simple type
-				// TODO: can this ever really apply (i.e. what is a simpleType really?)
-				$uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
-				$ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
-				$etype = $this->getTypeDef($uqType);
-				if ($etype) {
-					$this->xdebug("in getTypeDef, found type for simpleType $type:");
-					$this->xdebug($this->varDump($etype));
-					if (isset($etype['phpType'])) {
-						$this->simpleTypes[$type]['phpType'] = $etype['phpType'];
-					}
-					if (isset($etype['elements'])) {
-						$this->simpleTypes[$type]['elements'] = $etype['elements'];
-					}
-				}
-			}
-			return $this->simpleTypes[$type];
-		} elseif(isset($this->elements[$type])){
-			$this->xdebug("in getTypeDef, found element $type");
-			if (!isset($this->elements[$type]['phpType'])) {
-				// get info for type to tack onto the element
-				$uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
-				$ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
-				$etype = $this->getTypeDef($uqType);
-				if ($etype) {
-					$this->xdebug("in getTypeDef, found type for element $type:");
-					$this->xdebug($this->varDump($etype));
-					if (isset($etype['phpType'])) {
-						$this->elements[$type]['phpType'] = $etype['phpType'];
-					}
-					if (isset($etype['elements'])) {
-						$this->elements[$type]['elements'] = $etype['elements'];
-					}
-				} elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
-					$this->xdebug("in getTypeDef, element $type is an XSD type");
-					$this->elements[$type]['phpType'] = 'scalar';
-				}
-			}
-			return $this->elements[$type];
-		} elseif(isset($this->attributes[$type])){
-			$this->xdebug("in getTypeDef, found attribute $type");
-			return $this->attributes[$type];
-		} elseif (ereg('_ContainedType$', $type)) {
-			$this->xdebug("in getTypeDef, have an untyped element $type");
-			$typeDef['typeClass'] = 'simpleType';
-			$typeDef['phpType'] = 'scalar';
-			$typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
-			return $typeDef;
-		}
-		$this->xdebug("in getTypeDef, did not find $type");
-		return false;
-	}
-
-	/**
-    * returns a sample serialization of a given type, or false if no type by the given name
-    *
-    * @param string $type, name of type
-    * @return mixed
-    * @access public
-    * @deprecated
-    */
-    function serializeTypeDef($type){
-    	//print "in sTD() for type $type<br>";
-	if($typeDef = $this->getTypeDef($type)){
-		$str .= '<'.$type;
-	    if(is_array($typeDef['attrs'])){
-		foreach($attrs as $attName => $data){
-		    $str .= " $attName=\"{type = ".$data['type']."}\"";
-		}
-	    }
-	    $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
-	    if(count($typeDef['elements']) > 0){
-		$str .= ">";
-		foreach($typeDef['elements'] as $element => $eData){
-		    $str .= $this->serializeTypeDef($element);
-		}
-		$str .= "</$type>";
-	    } elseif($typeDef['typeClass'] == 'element') {
-		$str .= "></$type>";
-	    } else {
-		$str .= "/>";
-	    }
-			return $str;
-	}
-    	return false;
-    }
-
-    /**
-    * returns HTML form elements that allow a user
-    * to enter values for creating an instance of the given type.
-    *
-    * @param string $name, name for type instance
-    * @param string $type, name of type
-    * @return string
-    * @access public
-    * @deprecated
-	*/
-	function typeToForm($name,$type){
-		// get typedef
-		if($typeDef = $this->getTypeDef($type)){
-			// if struct
-			if($typeDef['phpType'] == 'struct'){
-				$buffer .= '<table>';
-				foreach($typeDef['elements'] as $child => $childDef){
-					$buffer .= "
-					<tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
-					<td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
-				}
-				$buffer .= '</table>';
-			// if array
-			} elseif($typeDef['phpType'] == 'array'){
-				$buffer .= '<table>';
-				for($i=0;$i < 3; $i++){
-					$buffer .= "
-					<tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
-					<td><input type='text' name='parameters[".$name."][]'></td></tr>";
-				}
-				$buffer .= '</table>';
-			// if scalar
-			} else {
-				$buffer .= "<input type='text' name='parameters[$name]'>";
-			}
-		} else {
-			$buffer .= "<input type='text' name='parameters[$name]'>";
-		}
-		return $buffer;
-	}
-	
-	/**
-	* adds a complex type to the schema
-	* 
-	* example: array
-	* 
-	* addType(
-	* 	'ArrayOfstring',
-	* 	'complexType',
-	* 	'array',
-	* 	'',
-	* 	'SOAP-ENC:Array',
-	* 	array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
-	* 	'xsd:string'
-	* );
-	* 
-	* example: PHP associative array ( SOAP Struct )
-	* 
-	* addType(
-	* 	'SOAPStruct',
-	* 	'complexType',
-	* 	'struct',
-	* 	'all',
-	* 	array('myVar'=> array('name'=>'myVar','type'=>'string')
-	* );
-	* 
-	* @param name
-	* @param typeClass (complexType|simpleType|attribute)
-	* @param phpType: currently supported are array and struct (php assoc array)
-	* @param compositor (all|sequence|choice)
-	* @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
-	* @param elements = array ( name = array(name=>'',type=>'') )
-	* @param attrs = array(
-	* 	array(
-	*		'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
-	*		"http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
-	* 	)
-	* )
-	* @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
-	* @access public
-	* @see getTypeDef
-	*/
-	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
-		$this->complexTypes[$name] = array(
-	    'name'		=> $name,
-	    'typeClass'	=> $typeClass,
-	    'phpType'	=> $phpType,
-		'compositor'=> $compositor,
-	    'restrictionBase' => $restrictionBase,
-		'elements'	=> $elements,
-	    'attrs'		=> $attrs,
-	    'arrayType'	=> $arrayType
-		);
-		
-		$this->xdebug("addComplexType $name:");
-		$this->appendDebug($this->varDump($this->complexTypes[$name]));
-	}
-	
-	/**
-	* adds a simple type to the schema
-	*
-	* @param string $name
-	* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
-	* @param string $typeClass (should always be simpleType)
-	* @param string $phpType (should always be scalar)
-	* @param array $enumeration array of values
-	* @access public
-	* @see xmlschema
-	* @see getTypeDef
-	*/
-	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
-		$this->simpleTypes[$name] = array(
-	    'name'			=> $name,
-	    'typeClass'		=> $typeClass,
-	    'phpType'		=> $phpType,
-	    'type'			=> $restrictionBase,
-	    'enumeration'	=> $enumeration
-		);
-		
-		$this->xdebug("addSimpleType $name:");
-		$this->appendDebug($this->varDump($this->simpleTypes[$name]));
-	}
-
-	/**
-	* adds an element to the schema
-	*
-	* @param array $attrs attributes that must include name and type
-	* @see xmlschema
-	* @access public
-	*/
-	function addElement($attrs) {
-		if (! $this->getPrefix($attrs['type'])) {
-			$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
-		}
-		$this->elements[ $attrs['name'] ] = $attrs;
-		$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
-		
-		$this->xdebug("addElement " . $attrs['name']);
-		$this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
-	}
-}
-
-
-
-
+<?php
+
+
+
+
+/**
+* parses an XML Schema, allows access to it's data, other utility methods
+* no validation... yet.
+* very experimental and limited. As is discussed on XML-DEV, I'm one of the people
+* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
+* tutorials I refer to :)
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class XMLSchema extends nusoap_base  {
+	
+	// files
+	var $schema = '';
+	var $xml = '';
+	// namespaces
+	var $enclosingNamespaces;
+	// schema info
+	var $schemaInfo = array();
+	var $schemaTargetNamespace = '';
+	// types, elements, attributes defined by the schema
+	var $attributes = array();
+	var $complexTypes = array();
+	var $complexTypeStack = array();
+	var $currentComplexType = null;
+	var $elements = array();
+	var $elementStack = array();
+	var $currentElement = null;
+	var $simpleTypes = array();
+	var $simpleTypeStack = array();
+	var $currentSimpleType = null;
+	// imports
+	var $imports = array();
+	// parser vars
+	var $parser;
+	var $position = 0;
+	var $depth = 0;
+	var $depth_array = array();
+	var $message = array();
+	var $defaultNamespace = array();
+    
+	/**
+	* constructor
+	*
+	* @param    string $schema schema document URI
+	* @param    string $xml xml document URI
+	* @param	string $namespaces namespaces defined in enclosing XML
+	* @access   public
+	*/
+	function XMLSchema($schema='',$xml='',$namespaces=array()){
+		parent::nusoap_base();
+		$this->debug('xmlschema class instantiated, inside constructor');
+		// files
+		$this->schema = $schema;
+		$this->xml = $xml;
+
+		// namespaces
+		$this->enclosingNamespaces = $namespaces;
+		$this->namespaces = array_merge($this->namespaces, $namespaces);
+
+		// parse schema file
+		if($schema != ''){
+			$this->debug('initial schema file: '.$schema);
+			$this->parseFile($schema, 'schema');
+		}
+
+		// parse xml file
+		if($xml != ''){
+			$this->debug('initial xml file: '.$xml);
+			$this->parseFile($xml, 'xml');
+		}
+
+	}
+
+    /**
+    * parse an XML file
+    *
+    * @param string $xml, path/URL to XML file
+    * @param string $type, (schema | xml)
+	* @return boolean
+    * @access public
+    */
+	function parseFile($xml,$type){
+		// parse xml file
+		if($xml != ""){
+			$xmlStr = @join("",@file($xml));
+			if($xmlStr == ""){
+				$msg = 'Error reading XML from '.$xml;
+				$this->setError($msg);
+				$this->debug($msg);
+			return false;
+			} else {
+				$this->debug("parsing $xml");
+				$this->parseString($xmlStr,$type);
+				$this->debug("done parsing $xml");
+			return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	* parse an XML string
+	*
+	* @param    string $xml path or URL
+    * @param string $type, (schema|xml)
+	* @access   private
+	*/
+	function parseString($xml,$type){
+		// parse xml string
+		if($xml != ""){
+
+	    	// Create an XML parser.
+	    	$this->parser = xml_parser_create();
+	    	// Set the options for parsing the XML data.
+	    	xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+
+	    	// Set the object for the parser.
+	    	xml_set_object($this->parser, $this);
+
+	    	// Set the element handlers for the parser.
+			if($type == "schema"){
+		    	xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
+		    	xml_set_character_data_handler($this->parser,'schemaCharacterData');
+			} elseif($type == "xml"){
+				xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
+		    	xml_set_character_data_handler($this->parser,'xmlCharacterData');
+			}
+
+		    // Parse the XML file.
+		    if(!xml_parse($this->parser,$xml,true)){
+			// Display an error message.
+				$errstr = sprintf('XML error parsing XML schema on line %d: %s',
+				xml_get_current_line_number($this->parser),
+				xml_error_string(xml_get_error_code($this->parser))
+				);
+				$this->debug($errstr);
+				$this->debug("XML payload:\n" . $xml);
+				$this->setError($errstr);
+	    	}
+            
+			xml_parser_free($this->parser);
+		} else{
+			$this->debug('no xml passed to parseString()!!');
+			$this->setError('no xml passed to parseString()!!');
+		}
+	}
+
+	/**
+	* start-element handler
+	*
+	* @param    string $parser XML parser object
+	* @param    string $name element name
+	* @param    string $attrs associative array of attributes
+	* @access   private
+	*/
+	function schemaStartElement($parser, $name, $attrs) {
+		
+		// position in the total number of elements, starting from 0
+		$pos = $this->position++;
+		$depth = $this->depth++;
+		// set self as current value for this depth
+		$this->depth_array[$depth] = $pos;
+		$this->message[$pos] = array('cdata' => ''); 
+		if ($depth > 0) {
+			$this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
+		} else {
+			$this->defaultNamespace[$pos] = false;
+		}
+
+		// get element prefix
+		if($prefix = $this->getPrefix($name)){
+			// get unqualified name
+			$name = $this->getLocalPart($name);
+		} else {
+        	$prefix = '';
+        }
+		
+        // loop thru attributes, expanding, and registering namespace declarations
+        if(count($attrs) > 0){
+        	foreach($attrs as $k => $v){
+                // if ns declarations, add to class level array of valid namespaces
+				if(ereg("^xmlns",$k)){
+                	//$this->xdebug("$k: $v");
+                	//$this->xdebug('ns_prefix: '.$this->getPrefix($k));
+                	if($ns_prefix = substr(strrchr($k,':'),1)){
+                		//$this->xdebug("Add namespace[$ns_prefix] = $v");
+						$this->namespaces[$ns_prefix] = $v;
+					} else {
+						$this->defaultNamespace[$pos] = $v;
+						if (! $this->getPrefixFromNamespace($v)) {
+							$this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
+						}
+					}
+					if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
+						$this->XMLSchemaVersion = $v;
+						$this->namespaces['xsi'] = $v.'-instance';
+					}
+				}
+        	}
+        	foreach($attrs as $k => $v){
+                // expand each attribute
+                $k = strpos($k,':') ? $this->expandQname($k) : $k;
+                $v = strpos($v,':') ? $this->expandQname($v) : $v;
+        		$eAttrs[$k] = $v;
+        	}
+        	$attrs = $eAttrs;
+        } else {
+        	$attrs = array();
+        }
+		// find status, register data
+		switch($name){
+			case 'all':			// (optional) compositor content for a complexType
+			case 'choice':
+			case 'group':
+			case 'sequence':
+				//$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
+				$this->complexTypes[$this->currentComplexType]['compositor'] = $name;
+				//if($name == 'all' || $name == 'sequence'){
+				//	$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+				//}
+			break;
+			case 'attribute':	// complexType attribute
+            	//$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
+            	$this->xdebug("parsing attribute:");
+            	$this->appendDebug($this->varDump($attrs));
+				if (!isset($attrs['form'])) {
+					$attrs['form'] = $this->schemaInfo['attributeFormDefault'];
+				}
+            	if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
+					$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+					if (!strpos($v, ':')) {
+						// no namespace in arrayType attribute value...
+						if ($this->defaultNamespace[$pos]) {
+							// ...so use the default
+							$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+						}
+					}
+            	}
+                if(isset($attrs['name'])){
+					$this->attributes[$attrs['name']] = $attrs;
+					$aname = $attrs['name'];
+				} elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
+					if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
+	                	$aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+	                } else {
+	                	$aname = '';
+	                }
+				} elseif(isset($attrs['ref'])){
+					$aname = $attrs['ref'];
+                    $this->attributes[$attrs['ref']] = $attrs;
+				}
+                
+				if($this->currentComplexType){	// This should *always* be
+					$this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
+				}
+				// arrayType attribute
+				if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
+					$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+                	$prefix = $this->getPrefix($aname);
+					if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
+						$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+					} else {
+						$v = '';
+					}
+                    if(strpos($v,'[,]')){
+                        $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
+                    }
+                    $v = substr($v,0,strpos($v,'[')); // clip the []
+                    if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
+                        $v = $this->XMLSchemaVersion.':'.$v;
+                    }
+                    $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
+				}
+			break;
+			case 'complexContent':	// (optional) content for a complexType
+			break;
+			case 'complexType':
+				array_push($this->complexTypeStack, $this->currentComplexType);
+				if(isset($attrs['name'])){
+					$this->xdebug('processing named complexType '.$attrs['name']);
+					//$this->currentElement = false;
+					$this->currentComplexType = $attrs['name'];
+					$this->complexTypes[$this->currentComplexType] = $attrs;
+					$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
+					// This is for constructs like
+					//           <complexType name="ListOfString" base="soap:Array">
+					//                <sequence>
+					//                    <element name="string" type="xsd:string"
+					//                        minOccurs="0" maxOccurs="unbounded" />
+					//                </sequence>
+					//            </complexType>
+					if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
+						$this->xdebug('complexType is unusual array');
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+					} else {
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+					}
+				}else{
+					$this->xdebug('processing unnamed complexType for element '.$this->currentElement);
+					$this->currentComplexType = $this->currentElement . '_ContainedType';
+					//$this->currentElement = false;
+					$this->complexTypes[$this->currentComplexType] = $attrs;
+					$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
+					// This is for constructs like
+					//           <complexType name="ListOfString" base="soap:Array">
+					//                <sequence>
+					//                    <element name="string" type="xsd:string"
+					//                        minOccurs="0" maxOccurs="unbounded" />
+					//                </sequence>
+					//            </complexType>
+					if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
+						$this->xdebug('complexType is unusual array');
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+					} else {
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+					}
+				}
+			break;
+			case 'element':
+				array_push($this->elementStack, $this->currentElement);
+				// elements defined as part of a complex type should
+				// not really be added to $this->elements, but for some
+				// reason, they are
+				if (!isset($attrs['form'])) {
+					$attrs['form'] = $this->schemaInfo['elementFormDefault'];
+				}
+				if(isset($attrs['type'])){
+					$this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
+					if (! $this->getPrefix($attrs['type'])) {
+						if ($this->defaultNamespace[$pos]) {
+							$attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
+							$this->xdebug('used default namespace to make type ' . $attrs['type']);
+						}
+					}
+					// This is for constructs like
+					//           <complexType name="ListOfString" base="soap:Array">
+					//                <sequence>
+					//                    <element name="string" type="xsd:string"
+					//                        minOccurs="0" maxOccurs="unbounded" />
+					//                </sequence>
+					//            </complexType>
+					if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
+						$this->xdebug('arrayType for unusual array is ' . $attrs['type']);
+						$this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
+					}
+					$this->currentElement = $attrs['name'];
+					$this->elements[ $attrs['name'] ] = $attrs;
+					$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
+					$ename = $attrs['name'];
+				} elseif(isset($attrs['ref'])){
+					$this->xdebug("processing element as ref to ".$attrs['ref']);
+					$this->currentElement = "ref to ".$attrs['ref'];
+					$ename = $this->getLocalPart($attrs['ref']);
+				} else {
+					$this->xdebug("processing untyped element ".$attrs['name']);
+					$this->currentElement = $attrs['name'];
+					$this->elements[ $attrs['name'] ] = $attrs;
+					$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
+					$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
+					$this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
+					$ename = $attrs['name'];
+				}
+				if(isset($ename) && $this->currentComplexType){
+					$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
+				}
+			break;
+			case 'enumeration':	//	restriction value list member
+				$this->xdebug('enumeration ' . $attrs['value']);
+				if ($this->currentSimpleType) {
+					$this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
+				} elseif ($this->currentComplexType) {
+					$this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
+				}
+			break;
+			case 'extension':	// simpleContent or complexContent type extension
+				$this->xdebug('extension ' . $attrs['base']);
+				if ($this->currentComplexType) {
+					$this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
+				}
+			break;
+			case 'import':
+			    if (isset($attrs['schemaLocation'])) {
+					//$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
+                    $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
+				} else {
+					//$this->xdebug('import namespace ' . $attrs['namespace']);
+                    $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
+					if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
+						$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
+					}
+				}
+			break;
+			case 'list':	// simpleType value list
+			break;
+			case 'restriction':	// simpleType, simpleContent or complexContent value restriction
+				$this->xdebug('restriction ' . $attrs['base']);
+				if($this->currentSimpleType){
+					$this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
+				} elseif($this->currentComplexType){
+					$this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
+					if(strstr($attrs['base'],':') == ':Array'){
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+					}
+				}
+			break;
+			case 'schema':
+				$this->schemaInfo = $attrs;
+				$this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
+				if (isset($attrs['targetNamespace'])) {
+					$this->schemaTargetNamespace = $attrs['targetNamespace'];
+				}
+				if (!isset($attrs['elementFormDefault'])) {
+					$this->schemaInfo['elementFormDefault'] = 'unqualified';
+				}
+				if (!isset($attrs['attributeFormDefault'])) {
+					$this->schemaInfo['attributeFormDefault'] = 'unqualified';
+				}
+			break;
+			case 'simpleContent':	// (optional) content for a complexType
+			break;
+			case 'simpleType':
+				array_push($this->simpleTypeStack, $this->currentSimpleType);
+				if(isset($attrs['name'])){
+					$this->xdebug("processing simpleType for name " . $attrs['name']);
+					$this->currentSimpleType = $attrs['name'];
+					$this->simpleTypes[ $attrs['name'] ] = $attrs;
+					$this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
+					$this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
+				} else {
+					$this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
+					$this->currentSimpleType = $this->currentElement . '_ContainedType';
+					//$this->currentElement = false;
+					$this->simpleTypes[$this->currentSimpleType] = $attrs;
+					$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
+				}
+			break;
+			case 'union':	// simpleType type list
+			break;
+			default:
+				//$this->xdebug("do not have anything to do for element $name");
+		}
+	}
+
+	/**
+	* end-element handler
+	*
+	* @param    string $parser XML parser object
+	* @param    string $name element name
+	* @access   private
+	*/
+	function schemaEndElement($parser, $name) {
+		// bring depth down a notch
+		$this->depth--;
+		// position of current element is equal to the last value left in depth_array for my depth
+		if(isset($this->depth_array[$this->depth])){
+        	$pos = $this->depth_array[$this->depth];
+        }
+		// get element prefix
+		if ($prefix = $this->getPrefix($name)){
+			// get unqualified name
+			$name = $this->getLocalPart($name);
+		} else {
+        	$prefix = '';
+        }
+		// move on...
+		if($name == 'complexType'){
+			$this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
+			$this->currentComplexType = array_pop($this->complexTypeStack);
+			//$this->currentElement = false;
+		}
+		if($name == 'element'){
+			$this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
+			$this->currentElement = array_pop($this->elementStack);
+		}
+		if($name == 'simpleType'){
+			$this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
+			$this->currentSimpleType = array_pop($this->simpleTypeStack);
+		}
+	}
+
+	/**
+	* element content handler
+	*
+	* @param    string $parser XML parser object
+	* @param    string $data element content
+	* @access   private
+	*/
+	function schemaCharacterData($parser, $data){
+		$pos = $this->depth_array[$this->depth - 1];
+		$this->message[$pos]['cdata'] .= $data;
+	}
+
+	/**
+	* serialize the schema
+	*
+	* @access   public
+	*/
+	function serializeSchema(){
+
+		$schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
+		$xml = '';
+		// imports
+		if (sizeof($this->imports) > 0) {
+			foreach($this->imports as $ns => $list) {
+				foreach ($list as $ii) {
+					if ($ii['location'] != '') {
+						$xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
+					} else {
+						$xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
+					}
+				}
+			} 
+		} 
+		// complex types
+		foreach($this->complexTypes as $typeName => $attrs){
+			$contentStr = '';
+			// serialize child elements
+			if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
+				foreach($attrs['elements'] as $element => $eParts){
+					if(isset($eParts['ref'])){
+						$contentStr .= "   <$schemaPrefix:element ref=\"$element\"/>\n";
+					} else {
+						$contentStr .= "   <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
+						foreach ($eParts as $aName => $aValue) {
+							// handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
+							if ($aName != 'name' && $aName != 'type') {
+								$contentStr .= " $aName=\"$aValue\"";
+							}
+						}
+						$contentStr .= "/>\n";
+					}
+				}
+				// compositor wraps elements
+				if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
+					$contentStr = "  <$schemaPrefix:$attrs[compositor]>\n".$contentStr."  </$schemaPrefix:$attrs[compositor]>\n";
+				}
+			}
+			// attributes
+			if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
+				foreach($attrs['attrs'] as $attr => $aParts){
+					$contentStr .= "    <$schemaPrefix:attribute";
+					foreach ($aParts as $a => $v) {
+						if ($a == 'ref' || $a == 'type') {
+							$contentStr .= " $a=\"".$this->contractQName($v).'"';
+						} elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
+							$this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
+							$contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
+						} else {
+							$contentStr .= " $a=\"$v\"";
+						}
+					}
+					$contentStr .= "/>\n";
+				}
+			}
+			// if restriction
+			if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
+				$contentStr = "   <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr."   </$schemaPrefix:restriction>\n";
+				// complex or simple content
+				if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
+					$contentStr = "  <$schemaPrefix:complexContent>\n".$contentStr."  </$schemaPrefix:complexContent>\n";
+				}
+			}
+			// finalize complex type
+			if($contentStr != ''){
+				$contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
+			} else {
+				$contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
+			}
+			$xml .= $contentStr;
+		}
+		// simple types
+		if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
+			foreach($this->simpleTypes as $typeName => $eParts){
+				$xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n  <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
+				if (isset($eParts['enumeration'])) {
+					foreach ($eParts['enumeration'] as $e) {
+						$xml .= "  <$schemaPrefix:enumeration value=\"$e\"/>\n";
+					}
+				}
+				$xml .= " </$schemaPrefix:simpleType>";
+			}
+		}
+		// elements
+		if(isset($this->elements) && count($this->elements) > 0){
+			foreach($this->elements as $element => $eParts){
+				$xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
+			}
+		}
+		// attributes
+		if(isset($this->attributes) && count($this->attributes) > 0){
+			foreach($this->attributes as $attr => $aParts){
+				$xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
+			}
+		}
+		// finish 'er up
+		$el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
+		foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
+			$el .= " xmlns:$nsp=\"$ns\"\n";
+		}
+		$xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
+		return $xml;
+	}
+
+	/**
+	* adds debug data to the clas level debug string
+	*
+	* @param    string $string debug data
+	* @access   private
+	*/
+	function xdebug($string){
+		$this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
+	}
+
+    /**
+    * get the PHP type of a user defined type in the schema
+    * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
+    * returns false if no type exists, or not w/ the given namespace
+    * else returns a string that is either a native php type, or 'struct'
+    *
+    * @param string $type, name of defined type
+    * @param string $ns, namespace of type
+    * @return mixed
+    * @access public
+    * @deprecated
+    */
+	function getPHPType($type,$ns){
+		if(isset($this->typemap[$ns][$type])){
+			//print "found type '$type' and ns $ns in typemap<br>";
+			return $this->typemap[$ns][$type];
+		} elseif(isset($this->complexTypes[$type])){
+			//print "getting type '$type' and ns $ns from complexTypes array<br>";
+			return $this->complexTypes[$type]['phpType'];
+		}
+		return false;
+	}
+
+	/**
+    * returns an associative array of information about a given type
+    * returns false if no type exists by the given name
+    *
+	*	For a complexType typeDef = array(
+	*	'restrictionBase' => '',
+	*	'phpType' => '',
+	*	'compositor' => '(sequence|all)',
+	*	'elements' => array(), // refs to elements array
+	*	'attrs' => array() // refs to attributes array
+	*	... and so on (see addComplexType)
+	*	)
+	*
+	*   For simpleType or element, the array has different keys.
+    *
+    * @param string
+    * @return mixed
+    * @access public
+    * @see addComplexType
+    * @see addSimpleType
+    * @see addElement
+    */
+	function getTypeDef($type){
+		//$this->debug("in getTypeDef for type $type");
+		if(isset($this->complexTypes[$type])){
+			$this->xdebug("in getTypeDef, found complexType $type");
+			return $this->complexTypes[$type];
+		} elseif(isset($this->simpleTypes[$type])){
+			$this->xdebug("in getTypeDef, found simpleType $type");
+			if (!isset($this->simpleTypes[$type]['phpType'])) {
+				// get info for type to tack onto the simple type
+				// TODO: can this ever really apply (i.e. what is a simpleType really?)
+				$uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
+				$ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
+				$etype = $this->getTypeDef($uqType);
+				if ($etype) {
+					$this->xdebug("in getTypeDef, found type for simpleType $type:");
+					$this->xdebug($this->varDump($etype));
+					if (isset($etype['phpType'])) {
+						$this->simpleTypes[$type]['phpType'] = $etype['phpType'];
+					}
+					if (isset($etype['elements'])) {
+						$this->simpleTypes[$type]['elements'] = $etype['elements'];
+					}
+				}
+			}
+			return $this->simpleTypes[$type];
+		} elseif(isset($this->elements[$type])){
+			$this->xdebug("in getTypeDef, found element $type");
+			if (!isset($this->elements[$type]['phpType'])) {
+				// get info for type to tack onto the element
+				$uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
+				$ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
+				$etype = $this->getTypeDef($uqType);
+				if ($etype) {
+					$this->xdebug("in getTypeDef, found type for element $type:");
+					$this->xdebug($this->varDump($etype));
+					if (isset($etype['phpType'])) {
+						$this->elements[$type]['phpType'] = $etype['phpType'];
+					}
+					if (isset($etype['elements'])) {
+						$this->elements[$type]['elements'] = $etype['elements'];
+					}
+				} elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
+					$this->xdebug("in getTypeDef, element $type is an XSD type");
+					$this->elements[$type]['phpType'] = 'scalar';
+				}
+			}
+			return $this->elements[$type];
+		} elseif(isset($this->attributes[$type])){
+			$this->xdebug("in getTypeDef, found attribute $type");
+			return $this->attributes[$type];
+		} elseif (ereg('_ContainedType$', $type)) {
+			$this->xdebug("in getTypeDef, have an untyped element $type");
+			$typeDef['typeClass'] = 'simpleType';
+			$typeDef['phpType'] = 'scalar';
+			$typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
+			return $typeDef;
+		}
+		$this->xdebug("in getTypeDef, did not find $type");
+		return false;
+	}
+
+	/**
+    * returns a sample serialization of a given type, or false if no type by the given name
+    *
+    * @param string $type, name of type
+    * @return mixed
+    * @access public
+    * @deprecated
+    */
+    function serializeTypeDef($type){
+    	//print "in sTD() for type $type<br>";
+	if($typeDef = $this->getTypeDef($type)){
+		$str .= '<'.$type;
+	    if(is_array($typeDef['attrs'])){
+		foreach($attrs as $attName => $data){
+		    $str .= " $attName=\"{type = ".$data['type']."}\"";
+		}
+	    }
+	    $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
+	    if(count($typeDef['elements']) > 0){
+		$str .= ">";
+		foreach($typeDef['elements'] as $element => $eData){
+		    $str .= $this->serializeTypeDef($element);
+		}
+		$str .= "</$type>";
+	    } elseif($typeDef['typeClass'] == 'element') {
+		$str .= "></$type>";
+	    } else {
+		$str .= "/>";
+	    }
+			return $str;
+	}
+    	return false;
+    }
+
+    /**
+    * returns HTML form elements that allow a user
+    * to enter values for creating an instance of the given type.
+    *
+    * @param string $name, name for type instance
+    * @param string $type, name of type
+    * @return string
+    * @access public
+    * @deprecated
+	*/
+	function typeToForm($name,$type){
+		// get typedef
+		if($typeDef = $this->getTypeDef($type)){
+			// if struct
+			if($typeDef['phpType'] == 'struct'){
+				$buffer .= '<table>';
+				foreach($typeDef['elements'] as $child => $childDef){
+					$buffer .= "
+					<tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
+					<td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
+				}
+				$buffer .= '</table>';
+			// if array
+			} elseif($typeDef['phpType'] == 'array'){
+				$buffer .= '<table>';
+				for($i=0;$i < 3; $i++){
+					$buffer .= "
+					<tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
+					<td><input type='text' name='parameters[".$name."][]'></td></tr>";
+				}
+				$buffer .= '</table>';
+			// if scalar
+			} else {
+				$buffer .= "<input type='text' name='parameters[$name]'>";
+			}
+		} else {
+			$buffer .= "<input type='text' name='parameters[$name]'>";
+		}
+		return $buffer;
+	}
+	
+	/**
+	* adds a complex type to the schema
+	* 
+	* example: array
+	* 
+	* addType(
+	* 	'ArrayOfstring',
+	* 	'complexType',
+	* 	'array',
+	* 	'',
+	* 	'SOAP-ENC:Array',
+	* 	array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
+	* 	'xsd:string'
+	* );
+	* 
+	* example: PHP associative array ( SOAP Struct )
+	* 
+	* addType(
+	* 	'SOAPStruct',
+	* 	'complexType',
+	* 	'struct',
+	* 	'all',
+	* 	array('myVar'=> array('name'=>'myVar','type'=>'string')
+	* );
+	* 
+	* @param name
+	* @param typeClass (complexType|simpleType|attribute)
+	* @param phpType: currently supported are array and struct (php assoc array)
+	* @param compositor (all|sequence|choice)
+	* @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+	* @param elements = array ( name = array(name=>'',type=>'') )
+	* @param attrs = array(
+	* 	array(
+	*		'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
+	*		"http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
+	* 	)
+	* )
+	* @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
+	* @access public
+	* @see getTypeDef
+	*/
+	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
+		$this->complexTypes[$name] = array(
+	    'name'		=> $name,
+	    'typeClass'	=> $typeClass,
+	    'phpType'	=> $phpType,
+		'compositor'=> $compositor,
+	    'restrictionBase' => $restrictionBase,
+		'elements'	=> $elements,
+	    'attrs'		=> $attrs,
+	    'arrayType'	=> $arrayType
+		);
+		
+		$this->xdebug("addComplexType $name:");
+		$this->appendDebug($this->varDump($this->complexTypes[$name]));
+	}
+	
+	/**
+	* adds a simple type to the schema
+	*
+	* @param string $name
+	* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+	* @param string $typeClass (should always be simpleType)
+	* @param string $phpType (should always be scalar)
+	* @param array $enumeration array of values
+	* @access public
+	* @see xmlschema
+	* @see getTypeDef
+	*/
+	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
+		$this->simpleTypes[$name] = array(
+	    'name'			=> $name,
+	    'typeClass'		=> $typeClass,
+	    'phpType'		=> $phpType,
+	    'type'			=> $restrictionBase,
+	    'enumeration'	=> $enumeration
+		);
+		
+		$this->xdebug("addSimpleType $name:");
+		$this->appendDebug($this->varDump($this->simpleTypes[$name]));
+	}
+
+	/**
+	* adds an element to the schema
+	*
+	* @param array $attrs attributes that must include name and type
+	* @see xmlschema
+	* @access public
+	*/
+	function addElement($attrs) {
+		if (! $this->getPrefix($attrs['type'])) {
+			$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
+		}
+		$this->elements[ $attrs['name'] ] = $attrs;
+		$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
+		
+		$this->xdebug("addElement " . $attrs['name']);
+		$this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
+	}
+}
+
+
+
+
 ?>
\ No newline at end of file
diff --git a/htdocs/oscommerce_ws/ws_server/lib/nusoap.php b/htdocs/oscommerce_ws/ws_server/lib/nusoap.php
index 1156e0d3a1667d489481e71a90c274ef38ba8596..5634e16e7f724759a2b999e8264883200121b9fd 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/nusoap.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/nusoap.php
@@ -1,7241 +1,7241 @@
-<?php
-
-/*
-$Id$
-
-NuSOAP - Web Services Toolkit for PHP
-
-Copyright (c) 2002 NuSphere Corporation
-
-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
-
-If you have any questions or comments, please email:
-
-Dietrich Ayala
-dietrich@ganx4.com
-http://dietrich.ganx4.com/nusoap
-
-NuSphere Corporation
-http://www.nusphere.com
-
-*/
-
-/* load classes
-
-// necessary classes
-require_once('class.soapclient.php');
-require_once('class.soap_val.php');
-require_once('class.soap_parser.php');
-require_once('class.soap_fault.php');
-
-// transport classes
-require_once('class.soap_transport_http.php');
-
-// optional add-on classes
-require_once('class.xmlschema.php');
-require_once('class.wsdl.php');
-
-// server class
-require_once('class.soap_server.php');*/
-
-// class variable emulation
-// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
-$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
-
-/**
-*
-* nusoap_base
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class nusoap_base {
-	/**
-	 * Identification for HTTP headers.
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $title = 'NuSOAP';
-	/**
-	 * Version for HTTP headers.
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $version = '0.7.2';
-	/**
-	 * CVS revision for HTTP headers.
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $revision = '$Revision$';
-    /**
-     * Current error string (manipulated by getError/setError)
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $error_str = '';
-    /**
-     * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
-	 *
-	 * @var string
-	 * @access private
-	 */
-    var $debug_str = '';
-    /**
-	 * toggles automatic encoding of special characters as entities
-	 * (should always be true, I think)
-	 *
-	 * @var boolean
-	 * @access private
-	 */
-	var $charencoding = true;
-	/**
-	 * the debug level for this instance
-	 *
-	 * @var	integer
-	 * @access private
-	 */
-	var $debugLevel;
-
-    /**
-	* set schema version
-	*
-	* @var      string
-	* @access   public
-	*/
-	var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
-	
-    /**
-	* charset encoding for outgoing messages
-	*
-	* @var      string
-	* @access   public
-	*/
-    var $soap_defencoding = 'ISO-8859-1';
-	//var $soap_defencoding = 'UTF-8';
-
-	/**
-	* namespaces in an array of prefix => uri
-	*
-	* this is "seeded" by a set of constants, but it may be altered by code
-	*
-	* @var      array
-	* @access   public
-	*/
-	var $namespaces = array(
-		'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
-		'xsd' => 'http://www.w3.org/2001/XMLSchema',
-		'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
-		'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
-		);
-
-	/**
-	* namespaces used in the current context, e.g. during serialization
-	*
-	* @var      array
-	* @access   private
-	*/
-	var $usedNamespaces = array();
-
-	/**
-	* XML Schema types in an array of uri => (array of xml type => php type)
-	* is this legacy yet?
-	* no, this is used by the xmlschema class to verify type => namespace mappings.
-	* @var      array
-	* @access   public
-	*/
-	var $typemap = array(
-	'http://www.w3.org/2001/XMLSchema' => array(
-		'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
-		'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
-		'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
-		// abstract "any" types
-		'anyType'=>'string','anySimpleType'=>'string',
-		// derived datatypes
-		'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
-		'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
-		'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
-		'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
-	'http://www.w3.org/2000/10/XMLSchema' => array(
-		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
-		'float'=>'double','dateTime'=>'string',
-		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
-	'http://www.w3.org/1999/XMLSchema' => array(
-		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
-		'float'=>'double','dateTime'=>'string',
-		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
-	'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
-	'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
-    'http://xml.apache.org/xml-soap' => array('Map')
-	);
-
-	/**
-	* XML entities to convert
-	*
-	* @var      array
-	* @access   public
-	* @deprecated
-	* @see	expandEntities
-	*/
-	var $xmlEntities = array('quot' => '"','amp' => '&',
-		'lt' => '<','gt' => '>','apos' => "'");
-
-	/**
-	* constructor
-	*
-	* @access	public
-	*/
-	function nusoap_base() {
-		$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
-	}
-
-	/**
-	* gets the global debug level, which applies to future instances
-	*
-	* @return	integer	Debug level 0-9, where 0 turns off
-	* @access	public
-	*/
-	function getGlobalDebugLevel() {
-		return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
-	}
-
-	/**
-	* sets the global debug level, which applies to future instances
-	*
-	* @param	int	$level	Debug level 0-9, where 0 turns off
-	* @access	public
-	*/
-	function setGlobalDebugLevel($level) {
-		$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
-	}
-
-	/**
-	* gets the debug level for this instance
-	*
-	* @return	int	Debug level 0-9, where 0 turns off
-	* @access	public
-	*/
-	function getDebugLevel() {
-		return $this->debugLevel;
-	}
-
-	/**
-	* sets the debug level for this instance
-	*
-	* @param	int	$level	Debug level 0-9, where 0 turns off
-	* @access	public
-	*/
-	function setDebugLevel($level) {
-		$this->debugLevel = $level;
-	}
-
-	/**
-	* adds debug data to the instance debug string with formatting
-	*
-	* @param    string $string debug data
-	* @access   private
-	*/
-	function debug($string){
-		if ($this->debugLevel > 0) {
-			$this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
-		}
-	}
-
-	/**
-	* adds debug data to the instance debug string without formatting
-	*
-	* @param    string $string debug data
-	* @access   public
-	*/
-	function appendDebug($string){
-		if ($this->debugLevel > 0) {
-			// it would be nice to use a memory stream here to use
-			// memory more efficiently
-			$this->debug_str .= $string;
-		}
-	}
-
-	/**
-	* clears the current debug data for this instance
-	*
-	* @access   public
-	*/
-	function clearDebug() {
-		// it would be nice to use a memory stream here to use
-		// memory more efficiently
-		$this->debug_str = '';
-	}
-
-	/**
-	* gets the current debug data for this instance
-	*
-	* @return   debug data
-	* @access   public
-	*/
-	function &getDebug() {
-		// it would be nice to use a memory stream here to use
-		// memory more efficiently
-		return $this->debug_str;
-	}
-
-	/**
-	* gets the current debug data for this instance as an XML comment
-	* this may change the contents of the debug data
-	*
-	* @return   debug data as an XML comment
-	* @access   public
-	*/
-	function &getDebugAsXMLComment() {
-		// it would be nice to use a memory stream here to use
-		// memory more efficiently
-		while (strpos($this->debug_str, '--')) {
-			$this->debug_str = str_replace('--', '- -', $this->debug_str);
-		}
-    	return "<!--\n" . $this->debug_str . "\n-->";
-	}
-
-	/**
-	* expands entities, e.g. changes '<' to '&lt;'.
-	*
-	* @param	string	$val	The string in which to expand entities.
-	* @access	private
-	*/
-	function expandEntities($val) {
-		if ($this->charencoding) {
-	    	$val = str_replace('&', '&amp;', $val);
-	    	$val = str_replace("'", '&apos;', $val);
-	    	$val = str_replace('"', '&quot;', $val);
-	    	$val = str_replace('<', '&lt;', $val);
-	    	$val = str_replace('>', '&gt;', $val);
-	    }
-	    return $val;
-	}
-
-	/**
-	* returns error string if present
-	*
-	* @return   mixed error string or false
-	* @access   public
-	*/
-	function getError(){
-		if($this->error_str != ''){
-			return $this->error_str;
-		}
-		return false;
-	}
-
-	/**
-	* sets error string
-	*
-	* @return   boolean $string error string
-	* @access   private
-	*/
-	function setError($str){
-		$this->error_str = $str;
-	}
-
-	/**
-	* detect if array is a simple array or a struct (associative array)
-	*
-	* @param	mixed	$val	The PHP array
-	* @return	string	(arraySimple|arrayStruct)
-	* @access	private
-	*/
-	function isArraySimpleOrStruct($val) {
-        $keyList = array_keys($val);
-		foreach ($keyList as $keyListValue) {
-			if (!is_int($keyListValue)) {
-				return 'arrayStruct';
-			}
-		}
-		return 'arraySimple';
-	}
-
-	/**
-	* serializes PHP values in accordance w/ section 5. Type information is
-	* not serialized if $use == 'literal'.
-	*
-	* @param	mixed	$val	The value to serialize
-	* @param	string	$name	The name (local part) of the XML element
-	* @param	string	$type	The XML schema type (local part) for the element
-	* @param	string	$name_ns	The namespace for the name of the XML element
-	* @param	string	$type_ns	The namespace for the type of the element
-	* @param	array	$attributes	The attributes to serialize as name=>value pairs
-	* @param	string	$use	The WSDL "use" (encoded|literal)
-	* @return	string	The serialized element, possibly with child elements
-    * @access	public
-	*/
-	function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){
-		$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use");
-		$this->appendDebug('value=' . $this->varDump($val));
-		$this->appendDebug('attributes=' . $this->varDump($attributes));
-		
-    	if(is_object($val) && get_class($val) == 'soapval'){
-        	return $val->serialize($use);
-        }
-		// force valid name if necessary
-		if (is_numeric($name)) {
-			$name = '__numeric_' . $name;
-		} elseif (! $name) {
-			$name = 'noname';
-		}
-		// if name has ns, add ns prefix to name
-		$xmlns = '';
-        if($name_ns){
-			$prefix = 'nu'.rand(1000,9999);
-			$name = $prefix.':'.$name;
-			$xmlns .= " xmlns:$prefix=\"$name_ns\"";
-		}
-		// if type is prefixed, create type prefix
-		if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
-			// need to fix this. shouldn't default to xsd if no ns specified
-		    // w/o checking against typemap
-			$type_prefix = 'xsd';
-		} elseif($type_ns){
-			$type_prefix = 'ns'.rand(1000,9999);
-			$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
-		}
-		// serialize attributes if present
-		$atts = '';
-		if($attributes){
-			foreach($attributes as $k => $v){
-				$atts .= " $k=\"".$this->expandEntities($v).'"';
-			}
-		}
-		// serialize null value
-		if (is_null($val)) {
-			if ($use == 'literal') {
-				// TODO: depends on minOccurs
-	        	return "<$name$xmlns $atts/>";
-        	} else {
-				if (isset($type) && isset($type_prefix)) {
-					$type_str = " xsi:type=\"$type_prefix:$type\"";
-				} else {
-					$type_str = '';
-				}
-	        	return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>";
-        	}
-		}
-        // serialize if an xsd built-in primitive type
-        if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
-        	if (is_bool($val)) {
-        		if ($type == 'boolean') {
-	        		$val = $val ? 'true' : 'false';
-	        	} elseif (! $val) {
-	        		$val = 0;
-	        	}
-			} else if (is_string($val)) {
-				$val = $this->expandEntities($val);
-			}
-			if ($use == 'literal') {
-	        	return "<$name$xmlns $atts>$val</$name>";
-        	} else {
-	        	return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>";
-        	}
-        }
-		// detect type and serialize
-		$xml = '';
-		switch(true) {
-			case (is_bool($val) || $type == 'boolean'):
-        		if ($type == 'boolean') {
-	        		$val = $val ? 'true' : 'false';
-	        	} elseif (! $val) {
-	        		$val = 0;
-	        	}
-				if ($use == 'literal') {
-					$xml .= "<$name$xmlns $atts>$val</$name>";
-				} else {
-					$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
-				}
-				break;
-			case (is_int($val) || is_long($val) || $type == 'int'):
-				if ($use == 'literal') {
-					$xml .= "<$name$xmlns $atts>$val</$name>";
-				} else {
-					$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
-				}
-				break;
-			case (is_float($val)|| is_double($val) || $type == 'float'):
-				if ($use == 'literal') {
-					$xml .= "<$name$xmlns $atts>$val</$name>";
-				} else {
-					$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
-				}
-				break;
-			case (is_string($val) || $type == 'string'):
-				$val = $this->expandEntities($val);
-				if ($use == 'literal') {
-					$xml .= "<$name$xmlns $atts>$val</$name>";
-				} else {
-					$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
-				}
-				break;
-			case is_object($val):
-				if (! $name) {
-					$name = get_class($val);
-					$this->debug("In serialize_val, used class name $name as element name");
-				} else {
-					$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
-				}
-				foreach(get_object_vars($val) as $k => $v){
-					$pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
-				}
-				$xml .= '<'.$name.'>'.$pXml.'</'.$name.'>';
-				break;
-			break;
-			case (is_array($val) || $type):
-				// detect if struct or array
-				$valueType = $this->isArraySimpleOrStruct($val);
-                if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
-					$i = 0;
-					if(is_array($val) && count($val)> 0){
-						foreach($val as $v){
-	                    	if(is_object($v) && get_class($v) ==  'soapval'){
-								$tt_ns = $v->type_ns;
-								$tt = $v->type;
-							} elseif (is_array($v)) {
-								$tt = $this->isArraySimpleOrStruct($v);
-							} else {
-								$tt = gettype($v);
-	                        }
-							$array_types[$tt] = 1;
-							// TODO: for literal, the name should be $name
-							$xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
-							++$i;
-						}
-						if(count($array_types) > 1){
-							$array_typename = 'xsd:anyType';
-						} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
-							if ($tt == 'integer') {
-								$tt = 'int';
-							}
-							$array_typename = 'xsd:'.$tt;
-						} elseif(isset($tt) && $tt == 'arraySimple'){
-							$array_typename = 'SOAP-ENC:Array';
-						} elseif(isset($tt) && $tt == 'arrayStruct'){
-							$array_typename = 'unnamed_struct_use_soapval';
-						} else {
-							// if type is prefixed, create type prefix
-							if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
-								 $array_typename = 'xsd:' . $tt;
-							} elseif ($tt_ns) {
-								$tt_prefix = 'ns' . rand(1000, 9999);
-								$array_typename = "$tt_prefix:$tt";
-								$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
-							} else {
-								$array_typename = $tt;
-							}
-						}
-						$array_type = $i;
-						if ($use == 'literal') {
-							$type_str = '';
-						} else if (isset($type) && isset($type_prefix)) {
-							$type_str = " xsi:type=\"$type_prefix:$type\"";
-						} else {
-							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
-						}
-					// empty array
-					} else {
-						if ($use == 'literal') {
-							$type_str = '';
-						} else if (isset($type) && isset($type_prefix)) {
-							$type_str = " xsi:type=\"$type_prefix:$type\"";
-						} else {
-							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
-						}
-					}
-					// TODO: for array in literal, there is no wrapper here
-					$xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
-				} else {
-					// got a struct
-					if(isset($type) && isset($type_prefix)){
-						$type_str = " xsi:type=\"$type_prefix:$type\"";
-					} else {
-						$type_str = '';
-					}
-					if ($use == 'literal') {
-						$xml .= "<$name$xmlns $atts>";
-					} else {
-						$xml .= "<$name$xmlns$type_str$atts>";
-					}
-					foreach($val as $k => $v){
-						// Apache Map
-						if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
-							$xml .= '<item>';
-							$xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
-							$xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
-							$xml .= '</item>';
-						} else {
-							$xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
-						}
-					}
-					$xml .= "</$name>";
-				}
-				break;
-			default:
-				$xml .= 'not detected, got '.gettype($val).' for '.$val;
-				break;
-		}
-		return $xml;
-	}
-
-    /**
-    * serializes a message
-    *
-    * @param string $body the XML of the SOAP body
-    * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
-    * @param array $namespaces optional the namespaces used in generating the body and headers
-    * @param string $style optional (rpc|document)
-    * @param string $use optional (encoded|literal)
-    * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
-    * @return string the message
-    * @access public
-    */
-    function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
-    // TODO: add an option to automatically run utf8_encode on $body and $headers
-    // if $this->soap_defencoding is UTF-8.  Not doing this automatically allows
-    // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
-
-	$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
-	$this->debug("headers:");
-	$this->appendDebug($this->varDump($headers));
-	$this->debug("namespaces:");
-	$this->appendDebug($this->varDump($namespaces));
-
-	// serialize namespaces
-    $ns_string = '';
-	foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
-		$ns_string .= " xmlns:$k=\"$v\"";
-	}
-	if($encodingStyle) {
-		$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
-	}
-
-	// serialize headers
-	if($headers){
-		if (is_array($headers)) {
-			$xml = '';
-			foreach ($headers as $header) {
-				$xml .= $this->serialize_val($header, false, false, false, false, false, $use);
-			}
-			$headers = $xml;
-			$this->debug("In serializeEnvelope, serialzied array of headers to $headers");
-		}
-		$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
-	}
-	// serialize envelope
-	return
-	'<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
-	'<SOAP-ENV:Envelope'.$ns_string.">".
-	$headers.
-	"<SOAP-ENV:Body>".
-		$body.
-	"</SOAP-ENV:Body>".
-	"</SOAP-ENV:Envelope>";
-    }
-
-	/**
-	 * formats a string to be inserted into an HTML stream
-	 *
-	 * @param string $str The string to format
-	 * @return string The formatted string
-	 * @access public
-	 * @deprecated
-	 */
-    function formatDump($str){
-		$str = htmlspecialchars($str);
-		return nl2br($str);
-    }
-
-	/**
-	* contracts (changes namespace to prefix) a qualified name
-	*
-	* @param    string $qname qname
-	* @return	string contracted qname
-	* @access   private
-	*/
-	function contractQname($qname){
-		// get element namespace
-		//$this->xdebug("Contract $qname");
-		if (strrpos($qname, ':')) {
-			// get unqualified name
-			$name = substr($qname, strrpos($qname, ':') + 1);
-			// get ns
-			$ns = substr($qname, 0, strrpos($qname, ':'));
-			$p = $this->getPrefixFromNamespace($ns);
-			if ($p) {
-				return $p . ':' . $name;
-			}
-			return $qname;
-		} else {
-			return $qname;
-		}
-	}
-
-	/**
-	* expands (changes prefix to namespace) a qualified name
-	*
-	* @param    string $string qname
-	* @return	string expanded qname
-	* @access   private
-	*/
-	function expandQname($qname){
-		// get element prefix
-		if(strpos($qname,':') && !ereg('^http://',$qname)){
-			// get unqualified name
-			$name = substr(strstr($qname,':'),1);
-			// get ns prefix
-			$prefix = substr($qname,0,strpos($qname,':'));
-			if(isset($this->namespaces[$prefix])){
-				return $this->namespaces[$prefix].':'.$name;
-			} else {
-				return $qname;
-			}
-		} else {
-			return $qname;
-		}
-	}
-
-    /**
-    * returns the local part of a prefixed string
-    * returns the original string, if not prefixed
-    *
-    * @param string $str The prefixed string
-    * @return string The local part
-    * @access public
-    */
-	function getLocalPart($str){
-		if($sstr = strrchr($str,':')){
-			// get unqualified name
-			return substr( $sstr, 1 );
-		} else {
-			return $str;
-		}
-	}
-
-	/**
-    * returns the prefix part of a prefixed string
-    * returns false, if not prefixed
-    *
-    * @param string $str The prefixed string
-    * @return mixed The prefix or false if there is no prefix
-    * @access public
-    */
-	function getPrefix($str){
-		if($pos = strrpos($str,':')){
-			// get prefix
-			return substr($str,0,$pos);
-		}
-		return false;
-	}
-
-	/**
-    * pass it a prefix, it returns a namespace
-    *
-    * @param string $prefix The prefix
-    * @return mixed The namespace, false if no namespace has the specified prefix
-    * @access public
-    */
-	function getNamespaceFromPrefix($prefix){
-		if (isset($this->namespaces[$prefix])) {
-			return $this->namespaces[$prefix];
-		}
-		//$this->setError("No namespace registered for prefix '$prefix'");
-		return false;
-	}
-
-	/**
-    * returns the prefix for a given namespace (or prefix)
-    * or false if no prefixes registered for the given namespace
-    *
-    * @param string $ns The namespace
-    * @return mixed The prefix, false if the namespace has no prefixes
-    * @access public
-    */
-	function getPrefixFromNamespace($ns) {
-		foreach ($this->namespaces as $p => $n) {
-			if ($ns == $n || $ns == $p) {
-			    $this->usedNamespaces[$p] = $n;
-				return $p;
-			}
-		}
-		return false;
-	}
-
-	/**
-    * returns the time in ODBC canonical form with microseconds
-    *
-    * @return string The time in ODBC canonical form with microseconds
-    * @access public
-    */
-	function getmicrotime() {
-		if (function_exists('gettimeofday')) {
-			$tod = gettimeofday();
-			$sec = $tod['sec'];
-			$usec = $tod['usec'];
-		} else {
-			$sec = time();
-			$usec = 0;
-		}
-		return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
-	}
-
-	/**
-	 * Returns a string with the output of var_dump
-	 *
-	 * @param mixed $data The variable to var_dump
-	 * @return string The output of var_dump
-	 * @access public
-	 */
-    function varDump($data) {
-		ob_start();
-		var_dump($data);
-		$ret_val = ob_get_contents();
-		ob_end_clean();
-		return $ret_val;
-	}
-}
-
-// XML Schema Datatype Helper Functions
-
-//xsd:dateTime helpers
-
-/**
-* convert unix timestamp to ISO 8601 compliant date string
-*
-* @param    string $timestamp Unix time stamp
-* @access   public
-*/
-function timestamp_to_iso8601($timestamp,$utc=true){
-	$datestr = date('Y-m-d\TH:i:sO',$timestamp);
-	if($utc){
-		$eregStr =
-		'([0-9]{4})-'.	// centuries & years CCYY-
-		'([0-9]{2})-'.	// months MM-
-		'([0-9]{2})'.	// days DD
-		'T'.			// separator T
-		'([0-9]{2}):'.	// hours hh:
-		'([0-9]{2}):'.	// minutes mm:
-		'([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
-		'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
-
-		if(ereg($eregStr,$datestr,$regs)){
-			return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
-		}
-		return false;
-	} else {
-		return $datestr;
-	}
-}
-
-/**
-* convert ISO 8601 compliant date string to unix timestamp
-*
-* @param    string $datestr ISO 8601 compliant date string
-* @access   public
-*/
-function iso8601_to_timestamp($datestr){
-	$eregStr =
-	'([0-9]{4})-'.	// centuries & years CCYY-
-	'([0-9]{2})-'.	// months MM-
-	'([0-9]{2})'.	// days DD
-	'T'.			// separator T
-	'([0-9]{2}):'.	// hours hh:
-	'([0-9]{2}):'.	// minutes mm:
-	'([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
-	'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
-	if(ereg($eregStr,$datestr,$regs)){
-		// not utc
-		if($regs[8] != 'Z'){
-			$op = substr($regs[8],0,1);
-			$h = substr($regs[8],1,2);
-			$m = substr($regs[8],strlen($regs[8])-2,2);
-			if($op == '-'){
-				$regs[4] = $regs[4] + $h;
-				$regs[5] = $regs[5] + $m;
-			} elseif($op == '+'){
-				$regs[4] = $regs[4] - $h;
-				$regs[5] = $regs[5] - $m;
-			}
-		}
-		return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
-	} else {
-		return false;
-	}
-}
-
-/**
-* sleeps some number of microseconds
-*
-* @param    string $usec the number of microseconds to sleep
-* @access   public
-* @deprecated
-*/
-function usleepWindows($usec)
-{
-	$start = gettimeofday();
-	
-	do
-	{
-		$stop = gettimeofday();
-		$timePassed = 1000000 * ($stop['sec'] - $start['sec'])
-		+ $stop['usec'] - $start['usec'];
-	}
-	while ($timePassed < $usec);
-}
-
-?><?php
-
-
-
-/**
-* Contains information for a SOAP fault.
-* Mainly used for returning faults from deployed functions
-* in a server instance.
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access public
-*/
-class soap_fault extends nusoap_base {
-	/**
-	 * The fault code (client|server)
-	 * @var string
-	 * @access private
-	 */
-	var $faultcode;
-	/**
-	 * The fault actor
-	 * @var string
-	 * @access private
-	 */
-	var $faultactor;
-	/**
-	 * The fault string, a description of the fault
-	 * @var string
-	 * @access private
-	 */
-	var $faultstring;
-	/**
-	 * The fault detail, typically a string or array of string
-	 * @var mixed
-	 * @access private
-	 */
-	var $faultdetail;
-
-	/**
-	* constructor
-    *
-    * @param string $faultcode (client | server)
-    * @param string $faultactor only used when msg routed between multiple actors
-    * @param string $faultstring human readable error message
-    * @param mixed $faultdetail detail, typically a string or array of string
-	*/
-	function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
-		parent::nusoap_base();
-		$this->faultcode = $faultcode;
-		$this->faultactor = $faultactor;
-		$this->faultstring = $faultstring;
-		$this->faultdetail = $faultdetail;
-	}
-
-	/**
-	* serialize a fault
-	*
-	* @return	string	The serialization of the fault instance.
-	* @access   public
-	*/
-	function serialize(){
-		$ns_string = '';
-		foreach($this->namespaces as $k => $v){
-			$ns_string .= "\n  xmlns:$k=\"$v\"";
-		}
-		$return_msg =
-			'<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
-			'<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
-				'<SOAP-ENV:Body>'.
-				'<SOAP-ENV:Fault>'.
-					$this->serialize_val($this->faultcode, 'faultcode').
-					$this->serialize_val($this->faultactor, 'faultactor').
-					$this->serialize_val($this->faultstring, 'faultstring').
-					$this->serialize_val($this->faultdetail, 'detail').
-				'</SOAP-ENV:Fault>'.
-				'</SOAP-ENV:Body>'.
-			'</SOAP-ENV:Envelope>';
-		return $return_msg;
-	}
-}
-
-
-
-?><?php
-
-
-
-/**
-* parses an XML Schema, allows access to it's data, other utility methods
-* no validation... yet.
-* very experimental and limited. As is discussed on XML-DEV, I'm one of the people
-* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
-* tutorials I refer to :)
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class XMLSchema extends nusoap_base  {
-	
-	// files
-	var $schema = '';
-	var $xml = '';
-	// namespaces
-	var $enclosingNamespaces;
-	// schema info
-	var $schemaInfo = array();
-	var $schemaTargetNamespace = '';
-	// types, elements, attributes defined by the schema
-	var $attributes = array();
-	var $complexTypes = array();
-	var $complexTypeStack = array();
-	var $currentComplexType = null;
-	var $elements = array();
-	var $elementStack = array();
-	var $currentElement = null;
-	var $simpleTypes = array();
-	var $simpleTypeStack = array();
-	var $currentSimpleType = null;
-	// imports
-	var $imports = array();
-	// parser vars
-	var $parser;
-	var $position = 0;
-	var $depth = 0;
-	var $depth_array = array();
-	var $message = array();
-	var $defaultNamespace = array();
-    
-	/**
-	* constructor
-	*
-	* @param    string $schema schema document URI
-	* @param    string $xml xml document URI
-	* @param	string $namespaces namespaces defined in enclosing XML
-	* @access   public
-	*/
-	function XMLSchema($schema='',$xml='',$namespaces=array()){
-		parent::nusoap_base();
-		$this->debug('xmlschema class instantiated, inside constructor');
-		// files
-		$this->schema = $schema;
-		$this->xml = $xml;
-
-		// namespaces
-		$this->enclosingNamespaces = $namespaces;
-		$this->namespaces = array_merge($this->namespaces, $namespaces);
-
-		// parse schema file
-		if($schema != ''){
-			$this->debug('initial schema file: '.$schema);
-			$this->parseFile($schema, 'schema');
-		}
-
-		// parse xml file
-		if($xml != ''){
-			$this->debug('initial xml file: '.$xml);
-			$this->parseFile($xml, 'xml');
-		}
-
-	}
-
-    /**
-    * parse an XML file
-    *
-    * @param string $xml, path/URL to XML file
-    * @param string $type, (schema | xml)
-	* @return boolean
-    * @access public
-    */
-	function parseFile($xml,$type){
-		// parse xml file
-		if($xml != ""){
-			$xmlStr = @join("",@file($xml));
-			if($xmlStr == ""){
-				$msg = 'Error reading XML from '.$xml;
-				$this->setError($msg);
-				$this->debug($msg);
-			return false;
-			} else {
-				$this->debug("parsing $xml");
-				$this->parseString($xmlStr,$type);
-				$this->debug("done parsing $xml");
-			return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	* parse an XML string
-	*
-	* @param    string $xml path or URL
-    * @param string $type, (schema|xml)
-	* @access   private
-	*/
-	function parseString($xml,$type){
-		// parse xml string
-		if($xml != ""){
-
-	    	// Create an XML parser.
-	    	$this->parser = xml_parser_create();
-	    	// Set the options for parsing the XML data.
-	    	xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
-
-	    	// Set the object for the parser.
-	    	xml_set_object($this->parser, $this);
-
-	    	// Set the element handlers for the parser.
-			if($type == "schema"){
-		    	xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
-		    	xml_set_character_data_handler($this->parser,'schemaCharacterData');
-			} elseif($type == "xml"){
-				xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
-		    	xml_set_character_data_handler($this->parser,'xmlCharacterData');
-			}
-
-		    // Parse the XML file.
-		    if(!xml_parse($this->parser,$xml,true)){
-			// Display an error message.
-				$errstr = sprintf('XML error parsing XML schema on line %d: %s',
-				xml_get_current_line_number($this->parser),
-				xml_error_string(xml_get_error_code($this->parser))
-				);
-				$this->debug($errstr);
-				$this->debug("XML payload:\n" . $xml);
-				$this->setError($errstr);
-	    	}
-            
-			xml_parser_free($this->parser);
-		} else{
-			$this->debug('no xml passed to parseString()!!');
-			$this->setError('no xml passed to parseString()!!');
-		}
-	}
-
-	/**
-	* start-element handler
-	*
-	* @param    string $parser XML parser object
-	* @param    string $name element name
-	* @param    string $attrs associative array of attributes
-	* @access   private
-	*/
-	function schemaStartElement($parser, $name, $attrs) {
-		
-		// position in the total number of elements, starting from 0
-		$pos = $this->position++;
-		$depth = $this->depth++;
-		// set self as current value for this depth
-		$this->depth_array[$depth] = $pos;
-		$this->message[$pos] = array('cdata' => ''); 
-		if ($depth > 0) {
-			$this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
-		} else {
-			$this->defaultNamespace[$pos] = false;
-		}
-
-		// get element prefix
-		if($prefix = $this->getPrefix($name)){
-			// get unqualified name
-			$name = $this->getLocalPart($name);
-		} else {
-        	$prefix = '';
-        }
-		
-        // loop thru attributes, expanding, and registering namespace declarations
-        if(count($attrs) > 0){
-        	foreach($attrs as $k => $v){
-                // if ns declarations, add to class level array of valid namespaces
-				if(ereg("^xmlns",$k)){
-                	//$this->xdebug("$k: $v");
-                	//$this->xdebug('ns_prefix: '.$this->getPrefix($k));
-                	if($ns_prefix = substr(strrchr($k,':'),1)){
-                		//$this->xdebug("Add namespace[$ns_prefix] = $v");
-						$this->namespaces[$ns_prefix] = $v;
-					} else {
-						$this->defaultNamespace[$pos] = $v;
-						if (! $this->getPrefixFromNamespace($v)) {
-							$this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
-						}
-					}
-					if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
-						$this->XMLSchemaVersion = $v;
-						$this->namespaces['xsi'] = $v.'-instance';
-					}
-				}
-        	}
-        	foreach($attrs as $k => $v){
-                // expand each attribute
-                $k = strpos($k,':') ? $this->expandQname($k) : $k;
-                $v = strpos($v,':') ? $this->expandQname($v) : $v;
-        		$eAttrs[$k] = $v;
-        	}
-        	$attrs = $eAttrs;
-        } else {
-        	$attrs = array();
-        }
-		// find status, register data
-		switch($name){
-			case 'all':			// (optional) compositor content for a complexType
-			case 'choice':
-			case 'group':
-			case 'sequence':
-				//$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
-				$this->complexTypes[$this->currentComplexType]['compositor'] = $name;
-				//if($name == 'all' || $name == 'sequence'){
-				//	$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
-				//}
-			break;
-			case 'attribute':	// complexType attribute
-            	//$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
-            	$this->xdebug("parsing attribute:");
-            	$this->appendDebug($this->varDump($attrs));
-				if (!isset($attrs['form'])) {
-					$attrs['form'] = $this->schemaInfo['attributeFormDefault'];
-				}
-            	if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
-					$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
-					if (!strpos($v, ':')) {
-						// no namespace in arrayType attribute value...
-						if ($this->defaultNamespace[$pos]) {
-							// ...so use the default
-							$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
-						}
-					}
-            	}
-                if(isset($attrs['name'])){
-					$this->attributes[$attrs['name']] = $attrs;
-					$aname = $attrs['name'];
-				} elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
-					if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
-	                	$aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
-	                } else {
-	                	$aname = '';
-	                }
-				} elseif(isset($attrs['ref'])){
-					$aname = $attrs['ref'];
-                    $this->attributes[$attrs['ref']] = $attrs;
-				}
-                
-				if($this->currentComplexType){	// This should *always* be
-					$this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
-				}
-				// arrayType attribute
-				if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
-					$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
-                	$prefix = $this->getPrefix($aname);
-					if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
-						$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
-					} else {
-						$v = '';
-					}
-                    if(strpos($v,'[,]')){
-                        $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
-                    }
-                    $v = substr($v,0,strpos($v,'[')); // clip the []
-                    if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
-                        $v = $this->XMLSchemaVersion.':'.$v;
-                    }
-                    $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
-				}
-			break;
-			case 'complexContent':	// (optional) content for a complexType
-			break;
-			case 'complexType':
-				array_push($this->complexTypeStack, $this->currentComplexType);
-				if(isset($attrs['name'])){
-					$this->xdebug('processing named complexType '.$attrs['name']);
-					//$this->currentElement = false;
-					$this->currentComplexType = $attrs['name'];
-					$this->complexTypes[$this->currentComplexType] = $attrs;
-					$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
-					// This is for constructs like
-					//           <complexType name="ListOfString" base="soap:Array">
-					//                <sequence>
-					//                    <element name="string" type="xsd:string"
-					//                        minOccurs="0" maxOccurs="unbounded" />
-					//                </sequence>
-					//            </complexType>
-					if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
-						$this->xdebug('complexType is unusual array');
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
-					} else {
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
-					}
-				}else{
-					$this->xdebug('processing unnamed complexType for element '.$this->currentElement);
-					$this->currentComplexType = $this->currentElement . '_ContainedType';
-					//$this->currentElement = false;
-					$this->complexTypes[$this->currentComplexType] = $attrs;
-					$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
-					// This is for constructs like
-					//           <complexType name="ListOfString" base="soap:Array">
-					//                <sequence>
-					//                    <element name="string" type="xsd:string"
-					//                        minOccurs="0" maxOccurs="unbounded" />
-					//                </sequence>
-					//            </complexType>
-					if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
-						$this->xdebug('complexType is unusual array');
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
-					} else {
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
-					}
-				}
-			break;
-			case 'element':
-				array_push($this->elementStack, $this->currentElement);
-				// elements defined as part of a complex type should
-				// not really be added to $this->elements, but for some
-				// reason, they are
-				if (!isset($attrs['form'])) {
-					$attrs['form'] = $this->schemaInfo['elementFormDefault'];
-				}
-				if(isset($attrs['type'])){
-					$this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
-					if (! $this->getPrefix($attrs['type'])) {
-						if ($this->defaultNamespace[$pos]) {
-							$attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
-							$this->xdebug('used default namespace to make type ' . $attrs['type']);
-						}
-					}
-					// This is for constructs like
-					//           <complexType name="ListOfString" base="soap:Array">
-					//                <sequence>
-					//                    <element name="string" type="xsd:string"
-					//                        minOccurs="0" maxOccurs="unbounded" />
-					//                </sequence>
-					//            </complexType>
-					if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
-						$this->xdebug('arrayType for unusual array is ' . $attrs['type']);
-						$this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
-					}
-					$this->currentElement = $attrs['name'];
-					$this->elements[ $attrs['name'] ] = $attrs;
-					$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
-					$ename = $attrs['name'];
-				} elseif(isset($attrs['ref'])){
-					$this->xdebug("processing element as ref to ".$attrs['ref']);
-					$this->currentElement = "ref to ".$attrs['ref'];
-					$ename = $this->getLocalPart($attrs['ref']);
-				} else {
-					$this->xdebug("processing untyped element ".$attrs['name']);
-					$this->currentElement = $attrs['name'];
-					$this->elements[ $attrs['name'] ] = $attrs;
-					$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
-					$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
-					$this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
-					$ename = $attrs['name'];
-				}
-				if(isset($ename) && $this->currentComplexType){
-					$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
-				}
-			break;
-			case 'enumeration':	//	restriction value list member
-				$this->xdebug('enumeration ' . $attrs['value']);
-				if ($this->currentSimpleType) {
-					$this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
-				} elseif ($this->currentComplexType) {
-					$this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
-				}
-			break;
-			case 'extension':	// simpleContent or complexContent type extension
-				$this->xdebug('extension ' . $attrs['base']);
-				if ($this->currentComplexType) {
-					$this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
-				}
-			break;
-			case 'import':
-			    if (isset($attrs['schemaLocation'])) {
-					//$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
-                    $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
-				} else {
-					//$this->xdebug('import namespace ' . $attrs['namespace']);
-                    $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
-					if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
-						$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
-					}
-				}
-			break;
-			case 'list':	// simpleType value list
-			break;
-			case 'restriction':	// simpleType, simpleContent or complexContent value restriction
-				$this->xdebug('restriction ' . $attrs['base']);
-				if($this->currentSimpleType){
-					$this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
-				} elseif($this->currentComplexType){
-					$this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
-					if(strstr($attrs['base'],':') == ':Array'){
-						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
-					}
-				}
-			break;
-			case 'schema':
-				$this->schemaInfo = $attrs;
-				$this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
-				if (isset($attrs['targetNamespace'])) {
-					$this->schemaTargetNamespace = $attrs['targetNamespace'];
-				}
-				if (!isset($attrs['elementFormDefault'])) {
-					$this->schemaInfo['elementFormDefault'] = 'unqualified';
-				}
-				if (!isset($attrs['attributeFormDefault'])) {
-					$this->schemaInfo['attributeFormDefault'] = 'unqualified';
-				}
-			break;
-			case 'simpleContent':	// (optional) content for a complexType
-			break;
-			case 'simpleType':
-				array_push($this->simpleTypeStack, $this->currentSimpleType);
-				if(isset($attrs['name'])){
-					$this->xdebug("processing simpleType for name " . $attrs['name']);
-					$this->currentSimpleType = $attrs['name'];
-					$this->simpleTypes[ $attrs['name'] ] = $attrs;
-					$this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
-					$this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
-				} else {
-					$this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
-					$this->currentSimpleType = $this->currentElement . '_ContainedType';
-					//$this->currentElement = false;
-					$this->simpleTypes[$this->currentSimpleType] = $attrs;
-					$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
-				}
-			break;
-			case 'union':	// simpleType type list
-			break;
-			default:
-				//$this->xdebug("do not have anything to do for element $name");
-		}
-	}
-
-	/**
-	* end-element handler
-	*
-	* @param    string $parser XML parser object
-	* @param    string $name element name
-	* @access   private
-	*/
-	function schemaEndElement($parser, $name) {
-		// bring depth down a notch
-		$this->depth--;
-		// position of current element is equal to the last value left in depth_array for my depth
-		if(isset($this->depth_array[$this->depth])){
-        	$pos = $this->depth_array[$this->depth];
-        }
-		// get element prefix
-		if ($prefix = $this->getPrefix($name)){
-			// get unqualified name
-			$name = $this->getLocalPart($name);
-		} else {
-        	$prefix = '';
-        }
-		// move on...
-		if($name == 'complexType'){
-			$this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
-			$this->currentComplexType = array_pop($this->complexTypeStack);
-			//$this->currentElement = false;
-		}
-		if($name == 'element'){
-			$this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
-			$this->currentElement = array_pop($this->elementStack);
-		}
-		if($name == 'simpleType'){
-			$this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
-			$this->currentSimpleType = array_pop($this->simpleTypeStack);
-		}
-	}
-
-	/**
-	* element content handler
-	*
-	* @param    string $parser XML parser object
-	* @param    string $data element content
-	* @access   private
-	*/
-	function schemaCharacterData($parser, $data){
-		$pos = $this->depth_array[$this->depth - 1];
-		$this->message[$pos]['cdata'] .= $data;
-	}
-
-	/**
-	* serialize the schema
-	*
-	* @access   public
-	*/
-	function serializeSchema(){
-
-		$schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
-		$xml = '';
-		// imports
-		if (sizeof($this->imports) > 0) {
-			foreach($this->imports as $ns => $list) {
-				foreach ($list as $ii) {
-					if ($ii['location'] != '') {
-						$xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
-					} else {
-						$xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
-					}
-				}
-			} 
-		} 
-		// complex types
-		foreach($this->complexTypes as $typeName => $attrs){
-			$contentStr = '';
-			// serialize child elements
-			if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
-				foreach($attrs['elements'] as $element => $eParts){
-					if(isset($eParts['ref'])){
-						$contentStr .= "   <$schemaPrefix:element ref=\"$element\"/>\n";
-					} else {
-						$contentStr .= "   <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
-						foreach ($eParts as $aName => $aValue) {
-							// handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
-							if ($aName != 'name' && $aName != 'type') {
-								$contentStr .= " $aName=\"$aValue\"";
-							}
-						}
-						$contentStr .= "/>\n";
-					}
-				}
-				// compositor wraps elements
-				if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
-					$contentStr = "  <$schemaPrefix:$attrs[compositor]>\n".$contentStr."  </$schemaPrefix:$attrs[compositor]>\n";
-				}
-			}
-			// attributes
-			if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
-				foreach($attrs['attrs'] as $attr => $aParts){
-					$contentStr .= "    <$schemaPrefix:attribute";
-					foreach ($aParts as $a => $v) {
-						if ($a == 'ref' || $a == 'type') {
-							$contentStr .= " $a=\"".$this->contractQName($v).'"';
-						} elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
-							$this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
-							$contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
-						} else {
-							$contentStr .= " $a=\"$v\"";
-						}
-					}
-					$contentStr .= "/>\n";
-				}
-			}
-			// if restriction
-			if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
-				$contentStr = "   <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr."   </$schemaPrefix:restriction>\n";
-				// complex or simple content
-				if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
-					$contentStr = "  <$schemaPrefix:complexContent>\n".$contentStr."  </$schemaPrefix:complexContent>\n";
-				}
-			}
-			// finalize complex type
-			if($contentStr != ''){
-				$contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
-			} else {
-				$contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
-			}
-			$xml .= $contentStr;
-		}
-		// simple types
-		if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
-			foreach($this->simpleTypes as $typeName => $eParts){
-				$xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n  <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
-				if (isset($eParts['enumeration'])) {
-					foreach ($eParts['enumeration'] as $e) {
-						$xml .= "  <$schemaPrefix:enumeration value=\"$e\"/>\n";
-					}
-				}
-				$xml .= " </$schemaPrefix:simpleType>";
-			}
-		}
-		// elements
-		if(isset($this->elements) && count($this->elements) > 0){
-			foreach($this->elements as $element => $eParts){
-				$xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
-			}
-		}
-		// attributes
-		if(isset($this->attributes) && count($this->attributes) > 0){
-			foreach($this->attributes as $attr => $aParts){
-				$xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
-			}
-		}
-		// finish 'er up
-		$el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
-		foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
-			$el .= " xmlns:$nsp=\"$ns\"\n";
-		}
-		$xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
-		return $xml;
-	}
-
-	/**
-	* adds debug data to the clas level debug string
-	*
-	* @param    string $string debug data
-	* @access   private
-	*/
-	function xdebug($string){
-		$this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
-	}
-
-    /**
-    * get the PHP type of a user defined type in the schema
-    * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
-    * returns false if no type exists, or not w/ the given namespace
-    * else returns a string that is either a native php type, or 'struct'
-    *
-    * @param string $type, name of defined type
-    * @param string $ns, namespace of type
-    * @return mixed
-    * @access public
-    * @deprecated
-    */
-	function getPHPType($type,$ns){
-		if(isset($this->typemap[$ns][$type])){
-			//print "found type '$type' and ns $ns in typemap<br>";
-			return $this->typemap[$ns][$type];
-		} elseif(isset($this->complexTypes[$type])){
-			//print "getting type '$type' and ns $ns from complexTypes array<br>";
-			return $this->complexTypes[$type]['phpType'];
-		}
-		return false;
-	}
-
-	/**
-    * returns an associative array of information about a given type
-    * returns false if no type exists by the given name
-    *
-	*	For a complexType typeDef = array(
-	*	'restrictionBase' => '',
-	*	'phpType' => '',
-	*	'compositor' => '(sequence|all)',
-	*	'elements' => array(), // refs to elements array
-	*	'attrs' => array() // refs to attributes array
-	*	... and so on (see addComplexType)
-	*	)
-	*
-	*   For simpleType or element, the array has different keys.
-    *
-    * @param string
-    * @return mixed
-    * @access public
-    * @see addComplexType
-    * @see addSimpleType
-    * @see addElement
-    */
-	function getTypeDef($type){
-		//$this->debug("in getTypeDef for type $type");
-		if(isset($this->complexTypes[$type])){
-			$this->xdebug("in getTypeDef, found complexType $type");
-			return $this->complexTypes[$type];
-		} elseif(isset($this->simpleTypes[$type])){
-			$this->xdebug("in getTypeDef, found simpleType $type");
-			if (!isset($this->simpleTypes[$type]['phpType'])) {
-				// get info for type to tack onto the simple type
-				// TODO: can this ever really apply (i.e. what is a simpleType really?)
-				$uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
-				$ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
-				$etype = $this->getTypeDef($uqType);
-				if ($etype) {
-					$this->xdebug("in getTypeDef, found type for simpleType $type:");
-					$this->xdebug($this->varDump($etype));
-					if (isset($etype['phpType'])) {
-						$this->simpleTypes[$type]['phpType'] = $etype['phpType'];
-					}
-					if (isset($etype['elements'])) {
-						$this->simpleTypes[$type]['elements'] = $etype['elements'];
-					}
-				}
-			}
-			return $this->simpleTypes[$type];
-		} elseif(isset($this->elements[$type])){
-			$this->xdebug("in getTypeDef, found element $type");
-			if (!isset($this->elements[$type]['phpType'])) {
-				// get info for type to tack onto the element
-				$uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
-				$ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
-				$etype = $this->getTypeDef($uqType);
-				if ($etype) {
-					$this->xdebug("in getTypeDef, found type for element $type:");
-					$this->xdebug($this->varDump($etype));
-					if (isset($etype['phpType'])) {
-						$this->elements[$type]['phpType'] = $etype['phpType'];
-					}
-					if (isset($etype['elements'])) {
-						$this->elements[$type]['elements'] = $etype['elements'];
-					}
-				} elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
-					$this->xdebug("in getTypeDef, element $type is an XSD type");
-					$this->elements[$type]['phpType'] = 'scalar';
-				}
-			}
-			return $this->elements[$type];
-		} elseif(isset($this->attributes[$type])){
-			$this->xdebug("in getTypeDef, found attribute $type");
-			return $this->attributes[$type];
-		} elseif (ereg('_ContainedType$', $type)) {
-			$this->xdebug("in getTypeDef, have an untyped element $type");
-			$typeDef['typeClass'] = 'simpleType';
-			$typeDef['phpType'] = 'scalar';
-			$typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
-			return $typeDef;
-		}
-		$this->xdebug("in getTypeDef, did not find $type");
-		return false;
-	}
-
-	/**
-    * returns a sample serialization of a given type, or false if no type by the given name
-    *
-    * @param string $type, name of type
-    * @return mixed
-    * @access public
-    * @deprecated
-    */
-    function serializeTypeDef($type){
-    	//print "in sTD() for type $type<br>";
-	if($typeDef = $this->getTypeDef($type)){
-		$str .= '<'.$type;
-	    if(is_array($typeDef['attrs'])){
-		foreach($attrs as $attName => $data){
-		    $str .= " $attName=\"{type = ".$data['type']."}\"";
-		}
-	    }
-	    $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
-	    if(count($typeDef['elements']) > 0){
-		$str .= ">";
-		foreach($typeDef['elements'] as $element => $eData){
-		    $str .= $this->serializeTypeDef($element);
-		}
-		$str .= "</$type>";
-	    } elseif($typeDef['typeClass'] == 'element') {
-		$str .= "></$type>";
-	    } else {
-		$str .= "/>";
-	    }
-			return $str;
-	}
-    	return false;
-    }
-
-    /**
-    * returns HTML form elements that allow a user
-    * to enter values for creating an instance of the given type.
-    *
-    * @param string $name, name for type instance
-    * @param string $type, name of type
-    * @return string
-    * @access public
-    * @deprecated
-	*/
-	function typeToForm($name,$type){
-		// get typedef
-		if($typeDef = $this->getTypeDef($type)){
-			// if struct
-			if($typeDef['phpType'] == 'struct'){
-				$buffer .= '<table>';
-				foreach($typeDef['elements'] as $child => $childDef){
-					$buffer .= "
-					<tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
-					<td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
-				}
-				$buffer .= '</table>';
-			// if array
-			} elseif($typeDef['phpType'] == 'array'){
-				$buffer .= '<table>';
-				for($i=0;$i < 3; $i++){
-					$buffer .= "
-					<tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
-					<td><input type='text' name='parameters[".$name."][]'></td></tr>";
-				}
-				$buffer .= '</table>';
-			// if scalar
-			} else {
-				$buffer .= "<input type='text' name='parameters[$name]'>";
-			}
-		} else {
-			$buffer .= "<input type='text' name='parameters[$name]'>";
-		}
-		return $buffer;
-	}
-	
-	/**
-	* adds a complex type to the schema
-	* 
-	* example: array
-	* 
-	* addType(
-	* 	'ArrayOfstring',
-	* 	'complexType',
-	* 	'array',
-	* 	'',
-	* 	'SOAP-ENC:Array',
-	* 	array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
-	* 	'xsd:string'
-	* );
-	* 
-	* example: PHP associative array ( SOAP Struct )
-	* 
-	* addType(
-	* 	'SOAPStruct',
-	* 	'complexType',
-	* 	'struct',
-	* 	'all',
-	* 	array('myVar'=> array('name'=>'myVar','type'=>'string')
-	* );
-	* 
-	* @param name
-	* @param typeClass (complexType|simpleType|attribute)
-	* @param phpType: currently supported are array and struct (php assoc array)
-	* @param compositor (all|sequence|choice)
-	* @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
-	* @param elements = array ( name = array(name=>'',type=>'') )
-	* @param attrs = array(
-	* 	array(
-	*		'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
-	*		"http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
-	* 	)
-	* )
-	* @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
-	* @access public
-	* @see getTypeDef
-	*/
-	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
-		$this->complexTypes[$name] = array(
-	    'name'		=> $name,
-	    'typeClass'	=> $typeClass,
-	    'phpType'	=> $phpType,
-		'compositor'=> $compositor,
-	    'restrictionBase' => $restrictionBase,
-		'elements'	=> $elements,
-	    'attrs'		=> $attrs,
-	    'arrayType'	=> $arrayType
-		);
-		
-		$this->xdebug("addComplexType $name:");
-		$this->appendDebug($this->varDump($this->complexTypes[$name]));
-	}
-	
-	/**
-	* adds a simple type to the schema
-	*
-	* @param string $name
-	* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
-	* @param string $typeClass (should always be simpleType)
-	* @param string $phpType (should always be scalar)
-	* @param array $enumeration array of values
-	* @access public
-	* @see xmlschema
-	* @see getTypeDef
-	*/
-	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
-		$this->simpleTypes[$name] = array(
-	    'name'			=> $name,
-	    'typeClass'		=> $typeClass,
-	    'phpType'		=> $phpType,
-	    'type'			=> $restrictionBase,
-	    'enumeration'	=> $enumeration
-		);
-		
-		$this->xdebug("addSimpleType $name:");
-		$this->appendDebug($this->varDump($this->simpleTypes[$name]));
-	}
-
-	/**
-	* adds an element to the schema
-	*
-	* @param array $attrs attributes that must include name and type
-	* @see xmlschema
-	* @access public
-	*/
-	function addElement($attrs) {
-		if (! $this->getPrefix($attrs['type'])) {
-			$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
-		}
-		$this->elements[ $attrs['name'] ] = $attrs;
-		$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
-		
-		$this->xdebug("addElement " . $attrs['name']);
-		$this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
-	}
-}
-
-
-
-?><?php
-
-
-
-/**
-* For creating serializable abstractions of native PHP types.  This class
-* allows element name/namespace, XSD type, and XML attributes to be
-* associated with a value.  This is extremely useful when WSDL is not
-* used, but is also useful when WSDL is used with polymorphic types, including
-* xsd:anyType and user-defined types.
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class soapval extends nusoap_base {
-	/**
-	 * The XML element name
-	 *
-	 * @var string
-	 * @access private
-	 */
-	var $name;
-	/**
-	 * The XML type name (string or false)
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $type;
-	/**
-	 * The PHP value
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $value;
-	/**
-	 * The XML element namespace (string or false)
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $element_ns;
-	/**
-	 * The XML type namespace (string or false)
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $type_ns;
-	/**
-	 * The XML element attributes (array or false)
-	 *
-	 * @var mixed
-	 * @access private
-	 */
-	var $attributes;
-
-	/**
-	* constructor
-	*
-	* @param    string $name optional name
-	* @param    mixed $type optional type name
-	* @param	mixed $value optional value
-	* @param	mixed $element_ns optional namespace of value
-	* @param	mixed $type_ns optional namespace of type
-	* @param	mixed $attributes associative array of attributes to add to element serialization
-	* @access   public
-	*/
-  	function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
-		parent::nusoap_base();
-		$this->name = $name;
-		$this->type = $type;
-		$this->value = $value;
-		$this->element_ns = $element_ns;
-		$this->type_ns = $type_ns;
-		$this->attributes = $attributes;
-    }
-
-	/**
-	* return serialized value
-	*
-	* @param	string $use The WSDL use value (encoded|literal)
-	* @return	string XML data
-	* @access   public
-	*/
-	function serialize($use='encoded') {
-		return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use);
-    }
-
-	/**
-	* decodes a soapval object into a PHP native type
-	*
-	* @return	mixed
-	* @access   public
-	*/
-	function decode(){
-		return $this->value;
-	}
-}
-
-
-
-?><?php
-
-
-
-/**
-* transport class for sending/receiving data via HTTP and HTTPS
-* NOTE: PHP must be compiled with the CURL extension for HTTPS support
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access public
-*/
-class soap_transport_http extends nusoap_base {
-
-	var $url = '';
-	var $uri = '';
-	var $digest_uri = '';
-	var $scheme = '';
-	var $host = '';
-	var $port = '';
-	var $path = '';
-	var $request_method = 'POST';
-	var $protocol_version = '1.0';
-	var $encoding = '';
-	var $outgoing_headers = array();
-	var $incoming_headers = array();
-	var $incoming_cookies = array();
-	var $outgoing_payload = '';
-	var $incoming_payload = '';
-	var $useSOAPAction = true;
-	var $persistentConnection = false;
-	var $ch = false;	// cURL handle
-	var $username = '';
-	var $password = '';
-	var $authtype = '';
-	var $digestRequest = array();
-	var $certRequest = array();	// keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional)
-								// cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
-								// sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
-								// sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem'
-								// passphrase: SSL key password/passphrase
-								// verifypeer: default is 1
-								// verifyhost: default is 1
-
-	/**
-	* constructor
-	*/
-	function soap_transport_http($url){
-		parent::nusoap_base();
-		$this->setURL($url);
-		ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
-		$this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')';
-		$this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']);
-	}
-
-	function setURL($url) {
-		$this->url = $url;
-
-		$u = parse_url($url);
-		foreach($u as $k => $v){
-			$this->debug("$k = $v");
-			$this->$k = $v;
-		}
-		
-		// add any GET params to path
-		if(isset($u['query']) && $u['query'] != ''){
-            $this->path .= '?' . $u['query'];
-		}
-		
-		// set default port
-		if(!isset($u['port'])){
-			if($u['scheme'] == 'https'){
-				$this->port = 443;
-			} else {
-				$this->port = 80;
-			}
-		}
-		
-		$this->uri = $this->path;
-		$this->digest_uri = $this->uri;
-		
-		// build headers
-		if (!isset($u['port'])) {
-			$this->outgoing_headers['Host'] = $this->host;
-		} else {
-			$this->outgoing_headers['Host'] = $this->host.':'.$this->port;
-		}
-		$this->debug('set Host: ' . $this->outgoing_headers['Host']);
-
-		if (isset($u['user']) && $u['user'] != '') {
-			$this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
-		}
-	}
-	
-	function connect($connection_timeout=0,$response_timeout=30){
-	  	// For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like
-	  	// "regular" socket.
-	  	// TODO: disabled for now because OpenSSL must be *compiled* in (not just
-	  	//       loaded), and until PHP5 stream_get_wrappers is not available.
-//	  	if ($this->scheme == 'https') {
-//		  	if (version_compare(phpversion(), '4.3.0') >= 0) {
-//		  		if (extension_loaded('openssl')) {
-//		  			$this->scheme = 'ssl';
-//		  			$this->debug('Using SSL over OpenSSL');
-//		  		}
-//		  	}
-//		}
-		$this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
-	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
-		// use persistent connection
-		if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
-			if (!feof($this->fp)) {
-				$this->debug('Re-use persistent connection');
-				return true;
-			}
-			fclose($this->fp);
-			$this->debug('Closed persistent connection at EOF');
-		}
-
-		// munge host if using OpenSSL
-		if ($this->scheme == 'ssl') {
-			$host = 'ssl://' . $this->host;
-		} else {
-			$host = $this->host;
-		}
-		$this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
-
-		// open socket
-		if($connection_timeout > 0){
-			$this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
-		} else {
-			$this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
-		}
-		
-		// test pointer
-		if(!$this->fp) {
-			$msg = 'Couldn\'t open socket connection to server ' . $this->url;
-			if ($this->errno) {
-				$msg .= ', Error ('.$this->errno.'): '.$this->error_str;
-			} else {
-				$msg .= ' prior to connect().  This is often a problem looking up the host name.';
-			}
-			$this->debug($msg);
-			$this->setError($msg);
-			return false;
-		}
-		
-		// set response timeout
-		$this->debug('set response timeout to ' . $response_timeout);
-		socket_set_timeout( $this->fp, $response_timeout);
-
-		$this->debug('socket connected');
-		return true;
-	  } else if ($this->scheme == 'https') {
-		if (!extension_loaded('curl')) {
-			$this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
-			return false;
-		}
-		$this->debug('connect using https');
-		// init CURL
-		$this->ch = curl_init();
-		// set url
-		$hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host";
-		// add path
-		$hostURL .= $this->path;
-		curl_setopt($this->ch, CURLOPT_URL, $hostURL);
-		// follow location headers (re-directs)
-		curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1);
-		// ask for headers in the response output
-		curl_setopt($this->ch, CURLOPT_HEADER, 1);
-		// ask for the response output as the return value
-		curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
-		// encode
-		// We manage this ourselves through headers and encoding
-//		if(function_exists('gzuncompress')){
-//			curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate');
-//		}
-		// persistent connection
-		if ($this->persistentConnection) {
-			// The way we send data, we cannot use persistent connections, since
-			// there will be some "junk" at the end of our request.
-			//curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true);
-			$this->persistentConnection = false;
-			$this->outgoing_headers['Connection'] = 'close';
-			$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
-		}
-		// set timeout
-		if ($connection_timeout != 0) {
-			curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout);
-		}
-		// TODO: cURL has added a connection timeout separate from the response timeout
-		//if ($connection_timeout != 0) {
-		//	curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
-		//}
-		//if ($response_timeout != 0) {
-		//	curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout);
-		//}
-
-		// recent versions of cURL turn on peer/host checking by default,
-		// while PHP binaries are not compiled with a default location for the
-		// CA cert bundle, so disable peer/host checking.
-//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');		
-		curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
-		curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
-
-		// support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
-		if ($this->authtype == 'certificate') {
-			if (isset($this->certRequest['cainfofile'])) {
-				curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']);
-			}
-			if (isset($this->certRequest['verifypeer'])) {
-				curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
-			} else {
-				curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1);
-			}
-			if (isset($this->certRequest['verifyhost'])) {
-				curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
-			} else {
-				curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1);
-			}
-			if (isset($this->certRequest['sslcertfile'])) {
-				curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
-			}
-			if (isset($this->certRequest['sslkeyfile'])) {
-				curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
-			}
-			if (isset($this->certRequest['passphrase'])) {
-				curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']);
-			}
-		}
-		$this->debug('cURL connection set up');
-		return true;
-	  } else {
-		$this->setError('Unknown scheme ' . $this->scheme);
-		$this->debug('Unknown scheme ' . $this->scheme);
-		return false;
-	  }
-	}
-	
-	/**
-	* send the SOAP message via HTTP
-	*
-	* @param    string $data message data
-	* @param    integer $timeout set connection timeout in seconds
-	* @param	integer $response_timeout set response timeout in seconds
-	* @param	array $cookies cookies to send
-	* @return	string data
-	* @access   public
-	*/
-	function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) {
-		
-		$this->debug('entered send() with data of length: '.strlen($data));
-
-		$this->tryagain = true;
-		$tries = 0;
-		while ($this->tryagain) {
-			$this->tryagain = false;
-			if ($tries++ < 2) {
-				// make connnection
-				if (!$this->connect($timeout, $response_timeout)){
-					return false;
-				}
-				
-				// send request
-				if (!$this->sendRequest($data, $cookies)){
-					return false;
-				}
-				
-				// get response
-				$respdata = $this->getResponse();
-			} else {
-				$this->setError('Too many tries to get an OK response');
-			}
-		}		
-		$this->debug('end of send()');
-		return $respdata;
-	}
-
-
-	/**
-	* send the SOAP message via HTTPS 1.0 using CURL
-	*
-	* @param    string $msg message data
-	* @param    integer $timeout set connection timeout in seconds
-	* @param	integer $response_timeout set response timeout in seconds
-	* @param	array $cookies cookies to send
-	* @return	string data
-	* @access   public
-	*/
-	function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
-		return $this->send($data, $timeout, $response_timeout, $cookies);
-	}
-	
-	/**
-	* if authenticating, set user credentials here
-	*
-	* @param    string $username
-	* @param    string $password
-	* @param	string $authtype (basic, digest, certificate)
-	* @param	array $digestRequest (keys must be nonce, nc, realm, qop)
-	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
-	* @access   public
-	*/
-	function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) {
-		$this->debug("Set credentials for authtype $authtype");
-		// cf. RFC 2617
-		if ($authtype == 'basic') {
-			$this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password);
-		} elseif ($authtype == 'digest') {
-			if (isset($digestRequest['nonce'])) {
-				$digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
-				
-				// calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html)
-	
-				// A1 = unq(username-value) ":" unq(realm-value) ":" passwd
-				$A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
-	
-				// H(A1) = MD5(A1)
-				$HA1 = md5($A1);
-	
-				// A2 = Method ":" digest-uri-value
-				$A2 = 'POST:' . $this->digest_uri;
-	
-				// H(A2)
-				$HA2 =  md5($A2);
-	
-				// KD(secret, data) = H(concat(secret, ":", data))
-				// if qop == auth:
-				// request-digest  = <"> < KD ( H(A1),     unq(nonce-value)
-				//                              ":" nc-value
-				//                              ":" unq(cnonce-value)
-				//                              ":" unq(qop-value)
-				//                              ":" H(A2)
-				//                            ) <">
-				// if qop is missing,
-				// request-digest  = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">
-	
-				$unhashedDigest = '';
-				$nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
-				$cnonce = $nonce;
-				if ($digestRequest['qop'] != '') {
-					$unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
-				} else {
-					$unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
-				}
-	
-				$hashedDigest = md5($unhashedDigest);
-	
-				$this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"';
-			}
-		} elseif ($authtype == 'certificate') {
-			$this->certRequest = $certRequest;
-		}
-		$this->username = $username;
-		$this->password = $password;
-		$this->authtype = $authtype;
-		$this->digestRequest = $digestRequest;
-		
-		if (isset($this->outgoing_headers['Authorization'])) {
-			$this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...');
-		} else {
-			$this->debug('Authorization header not set');
-		}
-	}
-	
-	/**
-	* set the soapaction value
-	*
-	* @param    string $soapaction
-	* @access   public
-	*/
-	function setSOAPAction($soapaction) {
-		$this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"';
-		$this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']);
-	}
-	
-	/**
-	* use http encoding
-	*
-	* @param    string $enc encoding style. supported values: gzip, deflate, or both
-	* @access   public
-	*/
-	function setEncoding($enc='gzip, deflate') {
-		if (function_exists('gzdeflate')) {
-			$this->protocol_version = '1.1';
-			$this->outgoing_headers['Accept-Encoding'] = $enc;
-			$this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']);
-			if (!isset($this->outgoing_headers['Connection'])) {
-				$this->outgoing_headers['Connection'] = 'close';
-				$this->persistentConnection = false;
-				$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
-			}
-			set_magic_quotes_runtime(0);
-			// deprecated
-			$this->encoding = $enc;
-		}
-	}
-	
-	/**
-	* set proxy info here
-	*
-	* @param    string $proxyhost
-	* @param    string $proxyport
-	* @param	string $proxyusername
-	* @param	string $proxypassword
-	* @access   public
-	*/
-	function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
-		$this->uri = $this->url;
-		$this->host = $proxyhost;
-		$this->port = $proxyport;
-		if ($proxyusername != '' && $proxypassword != '') {
-			$this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword);
-			$this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']);
-		}
-	}
-	
-	/**
-	* decode a string that is encoded w/ "chunked' transfer encoding
- 	* as defined in RFC2068 19.4.6
-	*
-	* @param    string $buffer
-	* @param    string $lb
-	* @returns	string
-	* @access   public
-	* @deprecated
-	*/
-	function decodeChunked($buffer, $lb){
-		// length := 0
-		$length = 0;
-		$new = '';
-		
-		// read chunk-size, chunk-extension (if any) and CRLF
-		// get the position of the linebreak
-		$chunkend = strpos($buffer, $lb);
-		if ($chunkend == FALSE) {
-			$this->debug('no linebreak found in decodeChunked');
-			return $new;
-		}
-		$temp = substr($buffer,0,$chunkend);
-		$chunk_size = hexdec( trim($temp) );
-		$chunkstart = $chunkend + strlen($lb);
-		// while (chunk-size > 0) {
-		while ($chunk_size > 0) {
-			$this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
-			$chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
-		  	
-			// Just in case we got a broken connection
-		  	if ($chunkend == FALSE) {
-		  	    $chunk = substr($buffer,$chunkstart);
-				// append chunk-data to entity-body
-		    	$new .= $chunk;
-		  	    $length += strlen($chunk);
-		  	    break;
-			}
-			
-		  	// read chunk-data and CRLF
-		  	$chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
-		  	// append chunk-data to entity-body
-		  	$new .= $chunk;
-		  	// length := length + chunk-size
-		  	$length += strlen($chunk);
-		  	// read chunk-size and CRLF
-		  	$chunkstart = $chunkend + strlen($lb);
-			
-		  	$chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
-			if ($chunkend == FALSE) {
-				break; //Just in case we got a broken connection
-			}
-			$temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
-			$chunk_size = hexdec( trim($temp) );
-			$chunkstart = $chunkend;
-		}
-		return $new;
-	}
-	
-	/*
-	 *	Writes payload, including HTTP headers, to $this->outgoing_payload.
-	 */
-	function buildPayload($data, $cookie_str = '') {
-		// add content-length header
-		$this->outgoing_headers['Content-Length'] = strlen($data);
-		$this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']);
-
-		// start building outgoing payload:
-		$req = "$this->request_method $this->uri HTTP/$this->protocol_version";
-		$this->debug("HTTP request: $req");
-		$this->outgoing_payload = "$req\r\n";
-
-		// loop thru headers, serializing
-		foreach($this->outgoing_headers as $k => $v){
-			$hdr = $k.': '.$v;
-			$this->debug("HTTP header: $hdr");
-			$this->outgoing_payload .= "$hdr\r\n";
-		}
-
-		// add any cookies
-		if ($cookie_str != '') {
-			$hdr = 'Cookie: '.$cookie_str;
-			$this->debug("HTTP header: $hdr");
-			$this->outgoing_payload .= "$hdr\r\n";
-		}
-
-		// header/body separator
-		$this->outgoing_payload .= "\r\n";
-		
-		// add data
-		$this->outgoing_payload .= $data;
-	}
-
-	function sendRequest($data, $cookies = NULL) {
-		// build cookie string
-		$cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
-
-		// build payload
-		$this->buildPayload($data, $cookie_str);
-
-	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
-		// send payload
-		if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
-			$this->setError('couldn\'t write message data to socket');
-			$this->debug('couldn\'t write message data to socket');
-			return false;
-		}
-		$this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
-		return true;
-	  } else if ($this->scheme == 'https') {
-		// set payload
-		// TODO: cURL does say this should only be the verb, and in fact it
-		// turns out that the URI and HTTP version are appended to this, which
-		// some servers refuse to work with
-		//curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
-		foreach($this->outgoing_headers as $k => $v){
-			$curl_headers[] = "$k: $v";
-		}
-		if ($cookie_str != '') {
-			$curl_headers[] = 'Cookie: ' . $cookie_str;
-		}
-		curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers);
-		if ($this->request_method == "POST") {
-	  		curl_setopt($this->ch, CURLOPT_POST, 1);
-	  		curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
-	  	} else {
-	  	}
-		$this->debug('set cURL payload');
-		return true;
-	  }
-	}
-
-	function getResponse(){
-		$this->incoming_payload = '';
-	    
-	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
-	    // loop until headers have been retrieved
-	    $data = '';
-	    while (!isset($lb)){
-
-			// We might EOF during header read.
-			if(feof($this->fp)) {
-				$this->incoming_payload = $data;
-				$this->debug('found no headers before EOF after length ' . strlen($data));
-				$this->debug("received before EOF:\n" . $data);
-				$this->setError('server failed to send headers');
-				return false;
-			}
-
-			$tmp = fgets($this->fp, 256);
-			$tmplen = strlen($tmp);
-			$this->debug("read line of $tmplen bytes: " . trim($tmp));
-
-			if ($tmplen == 0) {
-				$this->incoming_payload = $data;
-				$this->debug('socket read of headers timed out after length ' . strlen($data));
-				$this->debug("read before timeout: " . $data);
-				$this->setError('socket read of headers timed out');
-				return false;
-			}
-
-			$data .= $tmp;
-			$pos = strpos($data,"\r\n\r\n");
-			if($pos > 1){
-				$lb = "\r\n";
-			} else {
-				$pos = strpos($data,"\n\n");
-				if($pos > 1){
-					$lb = "\n";
-				}
-			}
-			// remove 100 header
-			if(isset($lb) && ereg('^HTTP/1.1 100',$data)){
-				unset($lb);
-				$data = '';
-			}//
-		}
-		// store header data
-		$this->incoming_payload .= $data;
-		$this->debug('found end of headers after length ' . strlen($data));
-		// process headers
-		$header_data = trim(substr($data,0,$pos));
-		$header_array = explode($lb,$header_data);
-		$this->incoming_headers = array();
-		$this->incoming_cookies = array();
-		foreach($header_array as $header_line){
-			$arr = explode(':',$header_line, 2);
-			if(count($arr) > 1){
-				$header_name = strtolower(trim($arr[0]));
-				$this->incoming_headers[$header_name] = trim($arr[1]);
-				if ($header_name == 'set-cookie') {
-					// TODO: allow multiple cookies from parseCookie
-					$cookie = $this->parseCookie(trim($arr[1]));
-					if ($cookie) {
-						$this->incoming_cookies[] = $cookie;
-						$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
-					} else {
-						$this->debug('did not find cookie in ' . trim($arr[1]));
-					}
-    			}
-			} else if (isset($header_name)) {
-				// append continuation line to previous header
-				$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
-			}
-		}
-		
-		// loop until msg has been received
-		if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
-			$content_length =  2147483647;	// ignore any content-length header
-			$chunked = true;
-			$this->debug("want to read chunked content");
-		} elseif (isset($this->incoming_headers['content-length'])) {
-			$content_length = $this->incoming_headers['content-length'];
-			$chunked = false;
-			$this->debug("want to read content of length $content_length");
-		} else {
-			$content_length =  2147483647;
-			$chunked = false;
-			$this->debug("want to read content to EOF");
-		}
-		$data = '';
-		do {
-			if ($chunked) {
-				$tmp = fgets($this->fp, 256);
-				$tmplen = strlen($tmp);
-				$this->debug("read chunk line of $tmplen bytes");
-				if ($tmplen == 0) {
-					$this->incoming_payload = $data;
-					$this->debug('socket read of chunk length timed out after length ' . strlen($data));
-					$this->debug("read before timeout:\n" . $data);
-					$this->setError('socket read of chunk length timed out');
-					return false;
-				}
-				$content_length = hexdec(trim($tmp));
-				$this->debug("chunk length $content_length");
-			}
-			$strlen = 0;
-		    while (($strlen < $content_length) && (!feof($this->fp))) {
-		    	$readlen = min(8192, $content_length - $strlen);
-				$tmp = fread($this->fp, $readlen);
-				$tmplen = strlen($tmp);
-				$this->debug("read buffer of $tmplen bytes");
-				if (($tmplen == 0) && (!feof($this->fp))) {
-					$this->incoming_payload = $data;
-					$this->debug('socket read of body timed out after length ' . strlen($data));
-					$this->debug("read before timeout:\n" . $data);
-					$this->setError('socket read of body timed out');
-					return false;
-				}
-				$strlen += $tmplen;
-				$data .= $tmp;
-			}
-			if ($chunked && ($content_length > 0)) {
-				$tmp = fgets($this->fp, 256);
-				$tmplen = strlen($tmp);
-				$this->debug("read chunk terminator of $tmplen bytes");
-				if ($tmplen == 0) {
-					$this->incoming_payload = $data;
-					$this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
-					$this->debug("read before timeout:\n" . $data);
-					$this->setError('socket read of chunk terminator timed out');
-					return false;
-				}
-			}
-		} while ($chunked && ($content_length > 0) && (!feof($this->fp)));
-		if (feof($this->fp)) {
-			$this->debug('read to EOF');
-		}
-		$this->debug('read body of length ' . strlen($data));
-		$this->incoming_payload .= $data;
-		$this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server');
-		
-		// close filepointer
-		if(
-			(isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || 
-			(! $this->persistentConnection) || feof($this->fp)){
-			fclose($this->fp);
-			$this->fp = false;
-			$this->debug('closed socket');
-		}
-		
-		// connection was closed unexpectedly
-		if($this->incoming_payload == ''){
-			$this->setError('no response from server');
-			return false;
-		}
-		
-		// decode transfer-encoding
-//		if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){
-//			if(!$data = $this->decodeChunked($data, $lb)){
-//				$this->setError('Decoding of chunked data failed');
-//				return false;
-//			}
-			//print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>";
-			// set decoded payload
-//			$this->incoming_payload = $header_data.$lb.$lb.$data;
-//		}
-	
-	  } else if ($this->scheme == 'https') {
-		// send and receive
-		$this->debug('send and receive with cURL');
-		$this->incoming_payload = curl_exec($this->ch);
-		$data = $this->incoming_payload;
-
-        $cErr = curl_error($this->ch);
-		if ($cErr != '') {
-        	$err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>';
-        	// TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE
-			foreach(curl_getinfo($this->ch) as $k => $v){
-				$err .= "$k: $v<br>";
-			}
-			$this->debug($err);
-			$this->setError($err);
-			curl_close($this->ch);
-	    	return false;
-		} else {
-			//echo '<pre>';
-			//var_dump(curl_getinfo($this->ch));
-			//echo '</pre>';
-		}
-		// close curl
-		$this->debug('No cURL error, closing cURL');
-		curl_close($this->ch);
-		
-		// remove 100 header(s)
-		while (ereg('^HTTP/1.1 100',$data)) {
-			if ($pos = strpos($data,"\r\n\r\n")) {
-				$data = ltrim(substr($data,$pos));
-			} elseif($pos = strpos($data,"\n\n") ) {
-				$data = ltrim(substr($data,$pos));
-			}
-		}
-		
-		// separate content from HTTP headers
-		if ($pos = strpos($data,"\r\n\r\n")) {
-			$lb = "\r\n";
-		} elseif( $pos = strpos($data,"\n\n")) {
-			$lb = "\n";
-		} else {
-			$this->debug('no proper separation of headers and document');
-			$this->setError('no proper separation of headers and document');
-			return false;
-		}
-		$header_data = trim(substr($data,0,$pos));
-		$header_array = explode($lb,$header_data);
-		$data = ltrim(substr($data,$pos));
-		$this->debug('found proper separation of headers and document');
-		$this->debug('cleaned data, stringlen: '.strlen($data));
-		// clean headers
-		foreach ($header_array as $header_line) {
-			$arr = explode(':',$header_line,2);
-			if(count($arr) > 1){
-				$header_name = strtolower(trim($arr[0]));
-				$this->incoming_headers[$header_name] = trim($arr[1]);
-				if ($header_name == 'set-cookie') {
-					// TODO: allow multiple cookies from parseCookie
-					$cookie = $this->parseCookie(trim($arr[1]));
-					if ($cookie) {
-						$this->incoming_cookies[] = $cookie;
-						$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
-					} else {
-						$this->debug('did not find cookie in ' . trim($arr[1]));
-					}
-    			}
-			} else if (isset($header_name)) {
-				// append continuation line to previous header
-				$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
-			}
-		}
-	  }
-
-		$arr = explode(' ', $header_array[0], 3);
-		$http_version = $arr[0];
-		$http_status = intval($arr[1]);
-		$http_reason = count($arr) > 2 ? $arr[2] : '';
-
- 		// see if we need to resend the request with http digest authentication
- 		if (isset($this->incoming_headers['location']) && $http_status == 301) {
- 			$this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']);
- 			$this->setURL($this->incoming_headers['location']);
-			$this->tryagain = true;
-			return false;
-		}
-
- 		// see if we need to resend the request with http digest authentication
- 		if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
- 			$this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
- 			if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
- 				$this->debug('Server wants digest authentication');
- 				// remove "Digest " from our elements
- 				$digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
- 				
- 				// parse elements into array
- 				$digestElements = explode(',', $digestString);
- 				foreach ($digestElements as $val) {
- 					$tempElement = explode('=', trim($val), 2);
- 					$digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
- 				}
-
-				// should have (at least) qop, realm, nonce
- 				if (isset($digestRequest['nonce'])) {
- 					$this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
- 					$this->tryagain = true;
- 					return false;
- 				}
- 			}
-			$this->debug('HTTP authentication failed');
-			$this->setError('HTTP authentication failed');
-			return false;
- 		}
-		
-		if (
-			($http_status >= 300 && $http_status <= 307) ||
-			($http_status >= 400 && $http_status <= 417) ||
-			($http_status >= 501 && $http_status <= 505)
-		   ) {
-			$this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient_nusoap->response has contents of the response)");
-			return false;
-		}
-
-		// decode content-encoding
-		if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){
-			if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){
-    			// if decoding works, use it. else assume data wasn't gzencoded
-    			if(function_exists('gzinflate')){
-					//$timer->setMarker('starting decoding of gzip/deflated content');
-					// IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress)
-					// this means there are no Zlib headers, although there should be
-					$this->debug('The gzinflate function exists');
-					$datalen = strlen($data);
-					if ($this->incoming_headers['content-encoding'] == 'deflate') {
-						if ($degzdata = @gzinflate($data)) {
-	    					$data = $degzdata;
-	    					$this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
-	    					if (strlen($data) < $datalen) {
-	    						// test for the case that the payload has been compressed twice
-		    					$this->debug('The inflated payload is smaller than the gzipped one; try again');
-								if ($degzdata = @gzinflate($data)) {
-			    					$data = $degzdata;
-			    					$this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
-								}
-	    					}
-	    				} else {
-	    					$this->debug('Error using gzinflate to inflate the payload');
-	    					$this->setError('Error using gzinflate to inflate the payload');
-	    				}
-					} elseif ($this->incoming_headers['content-encoding'] == 'gzip') {
-						if ($degzdata = @gzinflate(substr($data, 10))) {	// do our best
-							$data = $degzdata;
-	    					$this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
-	    					if (strlen($data) < $datalen) {
-	    						// test for the case that the payload has been compressed twice
-		    					$this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
-								if ($degzdata = @gzinflate(substr($data, 10))) {
-			    					$data = $degzdata;
-			    					$this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
-								}
-	    					}
-	    				} else {
-	    					$this->debug('Error using gzinflate to un-gzip the payload');
-							$this->setError('Error using gzinflate to un-gzip the payload');
-	    				}
-					}
-					//$timer->setMarker('finished decoding of gzip/deflated content');
-					//print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>";
-					// set decoded payload
-					$this->incoming_payload = $header_data.$lb.$lb.$data;
-    			} else {
-					$this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
-					$this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
-				}
-			} else {
-				$this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
-				$this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
-			}
-		} else {
-			$this->debug('No Content-Encoding header');
-		}
-		
-		if(strlen($data) == 0){
-			$this->debug('no data after headers!');
-			$this->setError('no data present after HTTP headers');
-			return false;
-		}
-		
-		return $data;
-	}
-
-	function setContentType($type, $charset = false) {
-		$this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : '');
-		$this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']);
-	}
-
-	function usePersistentConnection(){
-		if (isset($this->outgoing_headers['Accept-Encoding'])) {
-			return false;
-		}
-		$this->protocol_version = '1.1';
-		$this->persistentConnection = true;
-		$this->outgoing_headers['Connection'] = 'Keep-Alive';
-		$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
-		return true;
-	}
-
-	/**
-	 * parse an incoming Cookie into it's parts
-	 *
-	 * @param	string $cookie_str content of cookie
-	 * @return	array with data of that cookie
-	 * @access	private
-	 */
-	/*
-	 * TODO: allow a Set-Cookie string to be parsed into multiple cookies
-	 */
-	function parseCookie($cookie_str) {
-		$cookie_str = str_replace('; ', ';', $cookie_str) . ';';
-		$data = split(';', $cookie_str);
-		$value_str = $data[0];
-
-		$cookie_param = 'domain=';
-		$start = strpos($cookie_str, $cookie_param);
-		if ($start > 0) {
-			$domain = substr($cookie_str, $start + strlen($cookie_param));
-			$domain = substr($domain, 0, strpos($domain, ';'));
-		} else {
-			$domain = '';
-		}
-
-		$cookie_param = 'expires=';
-		$start = strpos($cookie_str, $cookie_param);
-		if ($start > 0) {
-			$expires = substr($cookie_str, $start + strlen($cookie_param));
-			$expires = substr($expires, 0, strpos($expires, ';'));
-		} else {
-			$expires = '';
-		}
-
-		$cookie_param = 'path=';
-		$start = strpos($cookie_str, $cookie_param);
-		if ( $start > 0 ) {
-			$path = substr($cookie_str, $start + strlen($cookie_param));
-			$path = substr($path, 0, strpos($path, ';'));
-		} else {
-			$path = '/';
-		}
-						
-		$cookie_param = ';secure;';
-		if (strpos($cookie_str, $cookie_param) !== FALSE) {
-			$secure = true;
-		} else {
-			$secure = false;
-		}
-
-		$sep_pos = strpos($value_str, '=');
-
-		if ($sep_pos) {
-			$name = substr($value_str, 0, $sep_pos);
-			$value = substr($value_str, $sep_pos + 1);
-			$cookie= array(	'name' => $name,
-			                'value' => $value,
-							'domain' => $domain,
-							'path' => $path,
-							'expires' => $expires,
-							'secure' => $secure
-							);		
-			return $cookie;
-		}
-		return false;
-	}
-  
-	/**
-	 * sort out cookies for the current request
-	 *
-	 * @param	array $cookies array with all cookies
-	 * @param	boolean $secure is the send-content secure or not?
-	 * @return	string for Cookie-HTTP-Header
-	 * @access	private
-	 */
-	function getCookiesForRequest($cookies, $secure=false) {
-		$cookie_str = '';
-		if ((! is_null($cookies)) && (is_array($cookies))) {
-			foreach ($cookies as $cookie) {
-				if (! is_array($cookie)) {
-					continue;
-				}
-	    		$this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']);
-				if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
-					if (strtotime($cookie['expires']) <= time()) {
-						$this->debug('cookie has expired');
-						continue;
-					}
-				}
-				if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) {
-					$domain = preg_quote($cookie['domain']);
-					if (! preg_match("'.*$domain$'i", $this->host)) {
-						$this->debug('cookie has different domain');
-						continue;
-					}
-				}
-				if ((isset($cookie['path'])) && (! empty($cookie['path']))) {
-					$path = preg_quote($cookie['path']);
-					if (! preg_match("'^$path.*'i", $this->path)) {
-						$this->debug('cookie is for a different path');
-						continue;
-					}
-				}
-				if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
-					$this->debug('cookie is secure, transport is not');
-					continue;
-				}
-				$cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
-	    		$this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
-			}
-		}
-		return $cookie_str;
-  }
-}
-
-?><?php
-
-
-
-/**
-*
-* soap_server allows the user to create a SOAP server
-* that is capable of receiving messages and returning responses
-*
-* NOTE: WSDL functionality is experimental
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class soap_server extends nusoap_base {
-	/**
-	 * HTTP headers of request
-	 * @var array
-	 * @access private
-	 */
-	var $headers = array();
-	/**
-	 * HTTP request
-	 * @var string
-	 * @access private
-	 */
-	var $request = '';
-	/**
-	 * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text)
-	 * @var string
-	 * @access public
-	 */
-	var $requestHeaders = '';
-	/**
-	 * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text)
-	 * @var string
-	 * @access public
-	 */
-	var $document = '';
-	/**
-	 * SOAP payload for request (text)
-	 * @var string
-	 * @access public
-	 */
-	var $requestSOAP = '';
-	/**
-	 * requested method namespace URI
-	 * @var string
-	 * @access private
-	 */
-	var $methodURI = '';
-	/**
-	 * name of method requested
-	 * @var string
-	 * @access private
-	 */
-	var $methodname = '';
-	/**
-	 * method parameters from request
-	 * @var array
-	 * @access private
-	 */
-	var $methodparams = array();
-	/**
-	 * SOAP Action from request
-	 * @var string
-	 * @access private
-	 */
-	var $SOAPAction = '';
-	/**
-	 * character set encoding of incoming (request) messages
-	 * @var string
-	 * @access public
-	 */
-	var $xml_encoding = '';
-	/**
-	 * toggles whether the parser decodes element content w/ utf8_decode()
-	 * @var boolean
-	 * @access public
-	 */
-    var $decode_utf8 = true;
-
-	/**
-	 * HTTP headers of response
-	 * @var array
-	 * @access public
-	 */
-	var $outgoing_headers = array();
-	/**
-	 * HTTP response
-	 * @var string
-	 * @access private
-	 */
-	var $response = '';
-	/**
-	 * SOAP headers for response (text)
-	 * @var string
-	 * @access public
-	 */
-	var $responseHeaders = '';
-	/**
-	 * SOAP payload for response (text)
-	 * @var string
-	 * @access private
-	 */
-	var $responseSOAP = '';
-	/**
-	 * method return value to place in response
-	 * @var mixed
-	 * @access private
-	 */
-	var $methodreturn = false;
-	/**
-	 * whether $methodreturn is a string of literal XML
-	 * @var boolean
-	 * @access public
-	 */
-	var $methodreturnisliteralxml = false;
-	/**
-	 * SOAP fault for response (or false)
-	 * @var mixed
-	 * @access private
-	 */
-	var $fault = false;
-	/**
-	 * text indication of result (for debugging)
-	 * @var string
-	 * @access private
-	 */
-	var $result = 'successful';
-
-	/**
-	 * assoc array of operations => opData; operations are added by the register()
-	 * method or by parsing an external WSDL definition
-	 * @var array
-	 * @access private
-	 */
-	var $operations = array();
-	/**
-	 * wsdl instance (if one)
-	 * @var mixed
-	 * @access private
-	 */
-	var $wsdl = false;
-	/**
-	 * URL for WSDL (if one)
-	 * @var mixed
-	 * @access private
-	 */
-	var $externalWSDLURL = false;
-	/**
-	 * whether to append debug to response as XML comment
-	 * @var boolean
-	 * @access public
-	 */
-	var $debug_flag = false;
-
-
-	/**
-	* constructor
-    * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to.
-	*
-    * @param mixed $wsdl file path or URL (string), or wsdl instance (object)
-	* @access   public
-	*/
-	function soap_server($wsdl=false){
-		parent::nusoap_base();
-		// turn on debugging?
-		global $debug;
-		global $HTTP_SERVER_VARS;
-
-		if (isset($_SERVER)) {
-			$this->debug("_SERVER is defined:");
-			$this->appendDebug($this->varDump($_SERVER));
-		} elseif (isset($HTTP_SERVER_VARS)) {
-			$this->debug("HTTP_SERVER_VARS is defined:");
-			$this->appendDebug($this->varDump($HTTP_SERVER_VARS));
-		} else {
-			$this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
-		}
-
-		if (isset($debug)) {
-			$this->debug("In soap_server, set debug_flag=$debug based on global flag");
-			$this->debug_flag = $debug;
-		} elseif (isset($_SERVER['QUERY_STRING'])) {
-			$qs = explode('&', $_SERVER['QUERY_STRING']);
-			foreach ($qs as $v) {
-				if (substr($v, 0, 6) == 'debug=') {
-					$this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
-					$this->debug_flag = substr($v, 6);
-				}
-			}
-		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
-			$qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
-			foreach ($qs as $v) {
-				if (substr($v, 0, 6) == 'debug=') {
-					$this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
-					$this->debug_flag = substr($v, 6);
-				}
-			}
-		}
-
-		// wsdl
-		if($wsdl){
-			$this->debug("In soap_server, WSDL is specified");
-			if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
-				$this->wsdl = $wsdl;
-				$this->externalWSDLURL = $this->wsdl->wsdl;
-				$this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
-			} else {
-				$this->debug('Create wsdl from ' . $wsdl);
-				$this->wsdl = new wsdl($wsdl);
-				$this->externalWSDLURL = $wsdl;
-			}
-			$this->appendDebug($this->wsdl->getDebug());
-			$this->wsdl->clearDebug();
-			if($err = $this->wsdl->getError()){
-				die('WSDL ERROR: '.$err);
-			}
-		}
-	}
-
-	/**
-	* processes request and returns response
-	*
-	* @param    string $data usually is the value of $HTTP_RAW_POST_DATA
-	* @access   public
-	*/
-	function service($data){
-		global $HTTP_SERVER_VARS;
-
-		if (isset($_SERVER['QUERY_STRING'])) {
-			$qs = $_SERVER['QUERY_STRING'];
-		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
-			$qs = $HTTP_SERVER_VARS['QUERY_STRING'];
-		} else {
-			$qs = '';
-		}
-		$this->debug("In service, query string=$qs");
-
-		if (ereg('wsdl', $qs) ){
-			$this->debug("In service, this is a request for WSDL");
-			if($this->externalWSDLURL){
-              if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL
-				header('Location: '.$this->externalWSDLURL);
-              } else { // assume file
-                header("Content-Type: text/xml\r\n");
-                $fp = fopen($this->externalWSDLURL, 'r');
-                fpassthru($fp);
-              }
-			} elseif ($this->wsdl) {
-				header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
-				print $this->wsdl->serialize($this->debug_flag);
-				if ($this->debug_flag) {
-					$this->debug('wsdl:');
-					$this->appendDebug($this->varDump($this->wsdl));
-					print $this->getDebugAsXMLComment();
-				}
-			} else {
-				header("Content-Type: text/html; charset=ISO-8859-1\r\n");
-				print "This service does not provide WSDL";
-			}
-		} elseif ($data == '' && $this->wsdl) {
-			$this->debug("In service, there is no data, so return Web description");
-			print $this->wsdl->webDescription();
-		} else {
-			$this->debug("In service, invoke the request");
-			$this->parse_request($data);
-			if (! $this->fault) {
-				$this->invoke_method();
-			}
-			if (! $this->fault) {
-				$this->serialize_return();
-			}
-			$this->send_response();
-		}
-	}
-
-	/**
-	* parses HTTP request headers.
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* headers
-	* request
-	* xml_encoding
-	* SOAPAction
-	*
-	* @access   private
-	*/
-	function parse_http_headers() {
-		global $HTTP_SERVER_VARS;
-
-		$this->request = '';
-		$this->SOAPAction = '';
-		if(function_exists('getallheaders')){
-			$this->debug("In parse_http_headers, use getallheaders");
-			$headers = getallheaders();
-			foreach($headers as $k=>$v){
-				$k = strtolower($k);
-				$this->headers[$k] = $v;
-				$this->request .= "$k: $v\r\n";
-				$this->debug("$k: $v");
-			}
-			// get SOAPAction header
-			if(isset($this->headers['soapaction'])){
-				$this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
-			}
-			// get the character encoding of the incoming request
-			if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
-				$enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
-				if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
-					$this->xml_encoding = strtoupper($enc);
-				} else {
-					$this->xml_encoding = 'US-ASCII';
-				}
-			} else {
-				// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-				$this->xml_encoding = 'ISO-8859-1';
-			}
-		} elseif(isset($_SERVER) && is_array($_SERVER)){
-			$this->debug("In parse_http_headers, use _SERVER");
-			foreach ($_SERVER as $k => $v) {
-				if (substr($k, 0, 5) == 'HTTP_') {
-					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
-				} else {
-					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
-				}
-				if ($k == 'soapaction') {
-					// get SOAPAction header
-					$k = 'SOAPAction';
-					$v = str_replace('"', '', $v);
-					$v = str_replace('\\', '', $v);
-					$this->SOAPAction = $v;
-				} else if ($k == 'content-type') {
-					// get the character encoding of the incoming request
-					if (strpos($v, '=')) {
-						$enc = substr(strstr($v, '='), 1);
-						$enc = str_replace('"', '', $enc);
-						$enc = str_replace('\\', '', $enc);
-						if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
-							$this->xml_encoding = strtoupper($enc);
-						} else {
-							$this->xml_encoding = 'US-ASCII';
-						}
-					} else {
-						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-						$this->xml_encoding = 'ISO-8859-1';
-					}
-				}
-				$this->headers[$k] = $v;
-				$this->request .= "$k: $v\r\n";
-				$this->debug("$k: $v");
-			}
-		} elseif (is_array($HTTP_SERVER_VARS)) {
-			$this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
-			foreach ($HTTP_SERVER_VARS as $k => $v) {
-				if (substr($k, 0, 5) == 'HTTP_') {
-					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
-				} else {
-					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
-				}
-				if ($k == 'soapaction') {
-					// get SOAPAction header
-					$k = 'SOAPAction';
-					$v = str_replace('"', '', $v);
-					$v = str_replace('\\', '', $v);
-					$this->SOAPAction = $v;
-				} else if ($k == 'content-type') {
-					// get the character encoding of the incoming request
-					if (strpos($v, '=')) {
-						$enc = substr(strstr($v, '='), 1);
-						$enc = str_replace('"', '', $enc);
-						$enc = str_replace('\\', '', $enc);
-						if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
-							$this->xml_encoding = strtoupper($enc);
-						} else {
-							$this->xml_encoding = 'US-ASCII';
-						}
-					} else {
-						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-						$this->xml_encoding = 'ISO-8859-1';
-					}
-				}
-				$this->headers[$k] = $v;
-				$this->request .= "$k: $v\r\n";
-				$this->debug("$k: $v");
-			}
-		} else {
-			$this->debug("In parse_http_headers, HTTP headers not accessible");
-			$this->setError("HTTP headers not accessible");
-		}
-	}
-
-	/**
-	* parses a request
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* headers
-	* request
-	* xml_encoding
-	* SOAPAction
-	* request
-	* requestSOAP
-	* methodURI
-	* methodname
-	* methodparams
-	* requestHeaders
-	* document
-	*
-	* This sets the fault field on error
-	*
-	* @param    string $data XML string
-	* @access   private
-	*/
-	function parse_request($data='') {
-		$this->debug('entering parse_request()');
-		$this->parse_http_headers();
-		$this->debug('got character encoding: '.$this->xml_encoding);
-		// uncompress if necessary
-		if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
-			$this->debug('got content encoding: ' . $this->headers['content-encoding']);
-			if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
-		    	// if decoding works, use it. else assume data wasn't gzencoded
-				if (function_exists('gzuncompress')) {
-					if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
-						$data = $degzdata;
-					} elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
-						$data = $degzdata;
-					} else {
-						$this->fault('Client', 'Errors occurred when trying to decode the data');
-						return;
-					}
-				} else {
-					$this->fault('Client', 'This Server does not support compressed data');
-					return;
-				}
-			}
-		}
-		$this->request .= "\r\n".$data;
-		$data = $this->parseRequest($this->headers, $data);
-		$this->requestSOAP = $data;
-		$this->debug('leaving parse_request');
-	}
-
-	/**
-	* invokes a PHP function for the requested SOAP method
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* methodreturn
-	*
-	* Note that the PHP function that is called may also set the following
-	* fields to affect the response sent to the client
-	*
-	* responseHeaders
-	* outgoing_headers
-	*
-	* This sets the fault field on error
-	*
-	* @access   private
-	*/
-	function invoke_method() {
-		$this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
-
-		if ($this->wsdl) {
-			if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
-				$this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
-				$this->appendDebug('opData=' . $this->varDump($this->opData));
-			} elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
-				// Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
-				$this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
-				$this->appendDebug('opData=' . $this->varDump($this->opData));
-				$this->methodname = $this->opData['name'];
-			} else {
-				$this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
-				$this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
-				return;
-			}
-		} else {
-			$this->debug('in invoke_method, no WSDL to validate method');
-		}
-
-		// if a . is present in $this->methodname, we see if there is a class in scope,
-		// which could be referred to. We will also distinguish between two deliminators,
-		// to allow methods to be called a the class or an instance
-		$class = '';
-		$method = '';
-		if (strpos($this->methodname, '..') > 0) {
-			$delim = '..';
-		} else if (strpos($this->methodname, '.') > 0) {
-			$delim = '.';
-		} else {
-			$delim = '';
-		}
-
-		if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
-			class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
-			// get the class and method name
-			$class = substr($this->methodname, 0, strpos($this->methodname, $delim));
-			$method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
-			$this->debug("in invoke_method, class=$class method=$method delim=$delim");
-		}
-
-		// does method exist?
-		if ($class == '') {
-			if (!function_exists($this->methodname)) {
-				$this->debug("in invoke_method, function '$this->methodname' not found!");
-				$this->result = 'fault: method not found';
-				$this->fault('Client',"method '$this->methodname' not defined in service");
-				return;
-			}
-		} else {
-			$method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
-			if (!in_array($method_to_compare, get_class_methods($class))) {
-				$this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
-				$this->result = 'fault: method not found';
-				$this->fault('Client',"method '$this->methodname' not defined in service");
-				return;
-			}
-		}
-
-		// evaluate message, getting back parameters
-		// verify that request parameters match the method's signature
-		if(! $this->verify_method($this->methodname,$this->methodparams)){
-			// debug
-			$this->debug('ERROR: request not verified against method signature');
-			$this->result = 'fault: request failed validation against method signature';
-			// return fault
-			$this->fault('Client',"Operation '$this->methodname' not defined in service.");
-			return;
-		}
-
-		// if there are parameters to pass
-		$this->debug('in invoke_method, params:');
-		$this->appendDebug($this->varDump($this->methodparams));
-		$this->debug("in invoke_method, calling '$this->methodname'");
-		if (!function_exists('call_user_func_array')) {
-			if ($class == '') {
-				$this->debug('in invoke_method, calling function using eval()');
-				$funcCall = "\$this->methodreturn = $this->methodname(";
-			} else {
-				if ($delim == '..') {
-					$this->debug('in invoke_method, calling class method using eval()');
-					$funcCall = "\$this->methodreturn = ".$class."::".$method."(";
-				} else {
-					$this->debug('in invoke_method, calling instance method using eval()');
-					// generate unique instance name
-					$instname = "\$inst_".time();
-					$funcCall = $instname." = new ".$class."(); ";
-					$funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
-				}
-			}
-			if ($this->methodparams) {
-				foreach ($this->methodparams as $param) {
-					if (is_array($param)) {
-						$this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
-						return;
-					}
-					$funcCall .= "\"$param\",";
-				}
-				$funcCall = substr($funcCall, 0, -1);
-			}
-			$funcCall .= ');';
-			$this->debug('in invoke_method, function call: '.$funcCall);
-			@eval($funcCall);
-		} else {
-			if ($class == '') {
-				$this->debug('in invoke_method, calling function using call_user_func_array()');
-				$call_arg = "$this->methodname";	// straight assignment changes $this->methodname to lower case after call_user_func_array()
-			} elseif ($delim == '..') {
-				$this->debug('in invoke_method, calling class method using call_user_func_array()');
-				$call_arg = array ($class, $method);
-			} else {
-				$this->debug('in invoke_method, calling instance method using call_user_func_array()');
-				$instance = new $class ();
-				$call_arg = array(&$instance, $method);
-			}
-			$this->methodreturn = call_user_func_array($call_arg, $this->methodparams);
-		}
-        $this->debug('in invoke_method, methodreturn:');
-        $this->appendDebug($this->varDump($this->methodreturn));
-		$this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn));
-	}
-
-	/**
-	* serializes the return value from a PHP function into a full SOAP Envelope
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* responseSOAP
-	*
-	* This sets the fault field on error
-	*
-	* @access   private
-	*/
-	function serialize_return() {
-		$this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
-		// if fault
-		if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) {
-			$this->debug('got a fault object from method');
-			$this->fault = $this->methodreturn;
-			return;
-		} elseif ($this->methodreturnisliteralxml) {
-			$return_val = $this->methodreturn;
-		// returned value(s)
-		} else {
-			$this->debug('got a(n) '.gettype($this->methodreturn).' from method');
-			$this->debug('serializing return value');
-			if($this->wsdl){
-				// weak attempt at supporting multiple output params
-				if(sizeof($this->opData['output']['parts']) > 1){
-			    	$opParams = $this->methodreturn;
-			    } else {
-			    	// TODO: is this really necessary?
-			    	$opParams = array($this->methodreturn);
-			    }
-			    $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
-			    $this->appendDebug($this->wsdl->getDebug());
-			    $this->wsdl->clearDebug();
-				if($errstr = $this->wsdl->getError()){
-					$this->debug('got wsdl error: '.$errstr);
-					$this->fault('Server', 'unable to serialize result');
-					return;
-				}
-			} else {
-				if (isset($this->methodreturn)) {
-					$return_val = $this->serialize_val($this->methodreturn, 'return');
-				} else {
-					$return_val = '';
-					$this->debug('in absence of WSDL, assume void return for backward compatibility');
-				}
-			}
-		}
-		$this->debug('return value:');
-		$this->appendDebug($this->varDump($return_val));
-
-		$this->debug('serializing response');
-		if ($this->wsdl) {
-			$this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
-			if ($this->opData['style'] == 'rpc') {
-				$this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
-				if ($this->opData['output']['use'] == 'literal') {
-					$payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>";
-				} else {
-					$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
-				}
-			} else {
-				$this->debug('style is not rpc for serialization: assume document');
-				$payload = $return_val;
-			}
-		} else {
-			$this->debug('do not have WSDL for serialization: assume rpc/encoded');
-			$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
-		}
-		$this->result = 'successful';
-		if($this->wsdl){
-			//if($this->debug_flag){
-            	$this->appendDebug($this->wsdl->getDebug());
-            //	}
-			if (isset($opData['output']['encodingStyle'])) {
-				$encodingStyle = $opData['output']['encodingStyle'];
-			} else {
-				$encodingStyle = '';
-			}
-			// Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
-			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle);
-		} else {
-			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
-		}
-		$this->debug("Leaving serialize_return");
-	}
-
-	/**
-	* sends an HTTP response
-	*
-	* The following fields are set by this function (when successful)
-	*
-	* outgoing_headers
-	* response
-	*
-	* @access   private
-	*/
-	function send_response() {
-		$this->debug('Enter send_response');
-		if ($this->fault) {
-			$payload = $this->fault->serialize();
-			$this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
-			$this->outgoing_headers[] = "Status: 500 Internal Server Error";
-		} else {
-			$payload = $this->responseSOAP;
-			// Some combinations of PHP+Web server allow the Status
-			// to come through as a header.  Since OK is the default
-			// just do nothing.
-			// $this->outgoing_headers[] = "HTTP/1.0 200 OK";
-			// $this->outgoing_headers[] = "Status: 200 OK";
-		}
-        // add debug data if in debug mode
-		if(isset($this->debug_flag) && $this->debug_flag){
-        	$payload .= $this->getDebugAsXMLComment();
-        }
-		$this->outgoing_headers[] = "Server: $this->title Server v$this->version";
-		ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
-		$this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
-		// Let the Web server decide about this
-		//$this->outgoing_headers[] = "Connection: Close\r\n";
-		$payload = $this->getHTTPBody($payload);
-		$type = $this->getHTTPContentType();
-		$charset = $this->getHTTPContentTypeCharset();
-		$this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
-		//begin code to compress payload - by John
-		// NOTE: there is no way to know whether the Web server will also compress
-		// this data.
-		if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {	
-			if (strstr($this->headers['accept-encoding'], 'gzip')) {
-				if (function_exists('gzencode')) {
-					if (isset($this->debug_flag) && $this->debug_flag) {
-						$payload .= "<!-- Content being gzipped -->";
-					}
-					$this->outgoing_headers[] = "Content-Encoding: gzip";
-					$payload = gzencode($payload);
-				} else {
-					if (isset($this->debug_flag) && $this->debug_flag) {
-						$payload .= "<!-- Content will not be gzipped: no gzencode -->";
-					}
-				}
-			} elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
-				// Note: MSIE requires gzdeflate output (no Zlib header and checksum),
-				// instead of gzcompress output,
-				// which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
-				if (function_exists('gzdeflate')) {
-					if (isset($this->debug_flag) && $this->debug_flag) {
-						$payload .= "<!-- Content being deflated -->";
-					}
-					$this->outgoing_headers[] = "Content-Encoding: deflate";
-					$payload = gzdeflate($payload);
-				} else {
-					if (isset($this->debug_flag) && $this->debug_flag) {
-						$payload .= "<!-- Content will not be deflated: no gzcompress -->";
-					}
-				}
-			}
-		}
-		//end code
-		$this->outgoing_headers[] = "Content-Length: ".strlen($payload);
-		reset($this->outgoing_headers);
-		foreach($this->outgoing_headers as $hdr){
-			header($hdr, false);
-		}
-		print $payload;
-		$this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
-	}
-
-	/**
-	* takes the value that was created by parsing the request
-	* and compares to the method's signature, if available.
-	*
-	* @param	string	$operation	The operation to be invoked
-	* @param	array	$request	The array of parameter values
-	* @return	boolean	Whether the operation was found
-	* @access   private
-	*/
-	function verify_method($operation,$request){
-		if(isset($this->wsdl) && is_object($this->wsdl)){
-			if($this->wsdl->getOperationData($operation)){
-				return true;
-			}
-	    } elseif(isset($this->operations[$operation])){
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	* processes SOAP message received from client
-	*
-	* @param	array	$headers	The HTTP headers
-	* @param	string	$data		unprocessed request data from client
-	* @return	mixed	value of the message, decoded into a PHP type
-	* @access   private
-	*/
-    function parseRequest($headers, $data) {
-		$this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
-		if (!strstr($headers['content-type'], 'text/xml')) {
-			$this->setError('Request not of type text/xml');
-			return false;
-		}
-		if (strpos($headers['content-type'], '=')) {
-			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
-			$this->debug('Got response encoding: ' . $enc);
-			if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
-				$this->xml_encoding = strtoupper($enc);
-			} else {
-				$this->xml_encoding = 'US-ASCII';
-			}
-		} else {
-			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-			$this->xml_encoding = 'ISO-8859-1';
-		}
-		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
-		// parse response, get soap parser obj
-		$parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
-		// parser debug
-		$this->debug("parser debug: \n".$parser->getDebug());
-		// if fault occurred during message parsing
-		if($err = $parser->getError()){
-			$this->result = 'fault: error in msg parsing: '.$err;
-			$this->fault('Client',"error in msg parsing:\n".$err);
-		// else successfully parsed request into soapval object
-		} else {
-			// get/set methodname
-			$this->methodURI = $parser->root_struct_namespace;
-			$this->methodname = $parser->root_struct_name;
-			$this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
-			$this->debug('calling parser->get_response()');
-			$this->methodparams = $parser->get_response();
-			// get SOAP headers
-			$this->requestHeaders = $parser->getHeaders();
-            // add document for doclit support
-            $this->document = $parser->document;
-		}
-	 }
-
-	/**
-	* gets the HTTP body for the current response.
-	*
-	* @param string $soapmsg The SOAP payload
-	* @return string The HTTP body, which includes the SOAP payload
-	* @access private
-	*/
-	function getHTTPBody($soapmsg) {
-		return $soapmsg;
-	}
-	
-	/**
-	* gets the HTTP content type for the current response.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type for the current response.
-	* @access private
-	*/
-	function getHTTPContentType() {
-		return 'text/xml';
-	}
-	
-	/**
-	* gets the HTTP content type charset for the current response.
-	* returns false for non-text content types.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type charset for the current response.
-	* @access private
-	*/
-	function getHTTPContentTypeCharset() {
-		return $this->soap_defencoding;
-	}
-
-	/**
-	* add a method to the dispatch map (this has been replaced by the register method)
-	*
-	* @param    string $methodname
-	* @param    string $in array of input values
-	* @param    string $out array of output values
-	* @access   public
-	* @deprecated
-	*/
-	function add_to_map($methodname,$in,$out){
-			$this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
-	}
-
-	/**
-	* register a service function with the server
-	*
-	* @param    string $name the name of the PHP function, class.method or class..method
-	* @param    array $in assoc array of input values: key = param name, value = param type
-	* @param    array $out assoc array of output values: key = param name, value = param type
-	* @param	mixed $namespace the element namespace for the method or false
-	* @param	mixed $soapaction the soapaction for the method or false
-	* @param	mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically
-	* @param	mixed $use optional (encoded|literal) or false
-	* @param	string $documentation optional Description to include in WSDL
-	* @param	string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
-	* @access   public
-	*/
-	function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
-		global $HTTP_SERVER_VARS;
-
-		if($this->externalWSDLURL){
-			die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
-		}
-		if (! $name) {
-			die('You must specify a name when you register an operation');
-		}
-		if (!is_array($in)) {
-			die('You must provide an array for operation inputs');
-		}
-		if (!is_array($out)) {
-			die('You must provide an array for operation outputs');
-		}
-		if(false == $namespace) {
-		}
-		if(false == $soapaction) {
-			if (isset($_SERVER)) {
-				$SERVER_NAME = $_SERVER['SERVER_NAME'];
-				$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
-			} elseif (isset($HTTP_SERVER_VARS)) {
-				$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
-				$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
-			} else {
-				$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
-			}
-			$soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name";
-		}
-		if(false == $style) {
-			$style = "rpc";
-		}
-		if(false == $use) {
-			$use = "encoded";
-		}
-		if ($use == 'encoded' && $encodingStyle = '') {
-			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-		}
-
-		$this->operations[$name] = array(
-	    'name' => $name,
-	    'in' => $in,
-	    'out' => $out,
-	    'namespace' => $namespace,
-	    'soapaction' => $soapaction,
-	    'style' => $style);
-        if($this->wsdl){
-        	$this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
-	    }
-		return true;
-	}
-
-	/**
-	* Specify a fault to be returned to the client.
-	* This also acts as a flag to the server that a fault has occured.
-	*
-	* @param	string $faultcode
-	* @param	string $faultstring
-	* @param	string $faultactor
-	* @param	string $faultdetail
-	* @access   public
-	*/
-	function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
-		if ($faultdetail == '' && $this->debug_flag) {
-			$faultdetail = $this->getDebug();
-		}
-		$this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
-		$this->fault->soap_defencoding = $this->soap_defencoding;
-	}
-
-    /**
-    * Sets up wsdl object.
-    * Acts as a flag to enable internal WSDL generation
-    *
-    * @param string $serviceName, name of the service
-    * @param mixed $namespace optional 'tns' service namespace or false
-    * @param mixed $endpoint optional URL of service endpoint or false
-    * @param string $style optional (rpc|document) WSDL style (also specified by operation)
-    * @param string $transport optional SOAP transport
-    * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false
-    */
-    function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
-    {
-    	global $HTTP_SERVER_VARS;
-
-		if (isset($_SERVER)) {
-			$SERVER_NAME = $_SERVER['SERVER_NAME'];
-			$SERVER_PORT = $_SERVER['SERVER_PORT'];
-			$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
-			$HTTPS = $_SERVER['HTTPS'];
-		} elseif (isset($HTTP_SERVER_VARS)) {
-			$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
-			$SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
-			$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
-			$HTTPS = $HTTP_SERVER_VARS['HTTPS'];
-		} else {
-			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
-		}
-		if ($SERVER_PORT == 80) {
-			$SERVER_PORT = '';
-		} else {
-			$SERVER_PORT = ':' . $SERVER_PORT;
-		}
-        if(false == $namespace) {
-            $namespace = "http://$SERVER_NAME/soap/$serviceName";
-        }
-        
-        if(false == $endpoint) {
-        	if ($HTTPS == '1' || $HTTPS == 'on') {
-        		$SCHEME = 'https';
-        	} else {
-        		$SCHEME = 'http';
-        	}
-            $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
-        }
-        
-        if(false == $schemaTargetNamespace) {
-            $schemaTargetNamespace = $namespace;
-        }
-        
-		$this->wsdl = new wsdl;
-		$this->wsdl->serviceName = $serviceName;
-        $this->wsdl->endpoint = $endpoint;
-		$this->wsdl->namespaces['tns'] = $namespace;
-		$this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
-		$this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
-		if ($schemaTargetNamespace != $namespace) {
-			$this->wsdl->namespaces['types'] = $schemaTargetNamespace;
-		}
-        $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces);
-        $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
-        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
-        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
-        $this->wsdl->bindings[$serviceName.'Binding'] = array(
-        	'name'=>$serviceName.'Binding',
-            'style'=>$style,
-            'transport'=>$transport,
-            'portType'=>$serviceName.'PortType');
-        $this->wsdl->ports[$serviceName.'Port'] = array(
-        	'binding'=>$serviceName.'Binding',
-            'location'=>$endpoint,
-            'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
-    }
-}
-
-
-
-?><?php
-
-
-
-/**
-* parses a WSDL file, allows access to it's data, other utility methods
-* 
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access public 
-*/
-class wsdl extends nusoap_base {
-	// URL or filename of the root of this WSDL
-    var $wsdl; 
-    // define internal arrays of bindings, ports, operations, messages, etc.
-    var $schemas = array();
-    var $currentSchema;
-    var $message = array();
-    var $complexTypes = array();
-    var $messages = array();
-    var $currentMessage;
-    var $currentOperation;
-    var $portTypes = array();
-    var $currentPortType;
-    var $bindings = array();
-    var $currentBinding;
-    var $ports = array();
-    var $currentPort;
-    var $opData = array();
-    var $status = '';
-    var $documentation = false;
-    var $endpoint = ''; 
-    // array of wsdl docs to import
-    var $import = array(); 
-    // parser vars
-    var $parser;
-    var $position = 0;
-    var $depth = 0;
-    var $depth_array = array();
-	// for getting wsdl
-	var $proxyhost = '';
-    var $proxyport = '';
-	var $proxyusername = '';
-	var $proxypassword = '';
-	var $timeout = 0;
-	var $response_timeout = 30;
-
-    /**
-     * constructor
-     * 
-     * @param string $wsdl WSDL document URL
-	 * @param string $proxyhost
-	 * @param string $proxyport
-	 * @param string $proxyusername
-	 * @param string $proxypassword
-	 * @param integer $timeout set the connection timeout
-	 * @param integer $response_timeout set the response timeout
-     * @access public 
-     */
-    function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){
-		parent::nusoap_base();
-        $this->wsdl = $wsdl;
-        $this->proxyhost = $proxyhost;
-        $this->proxyport = $proxyport;
-		$this->proxyusername = $proxyusername;
-		$this->proxypassword = $proxypassword;
-		$this->timeout = $timeout;
-		$this->response_timeout = $response_timeout;
-        
-        // parse wsdl file
-        if ($wsdl != "") {
-            $this->debug('initial wsdl URL: ' . $wsdl);
-            $this->parseWSDL($wsdl);
-        }
-        // imports
-        // TODO: handle imports more properly, grabbing them in-line and nesting them
-        	$imported_urls = array();
-        	$imported = 1;
-        	while ($imported > 0) {
-        		$imported = 0;
-        		// Schema imports
-        		foreach ($this->schemas as $ns => $list) {
-        			foreach ($list as $xs) {
-						$wsdlparts = parse_url($this->wsdl);	// this is bogusly simple!
-			            foreach ($xs->imports as $ns2 => $list2) {
-			                for ($ii = 0; $ii < count($list2); $ii++) {
-			                	if (! $list2[$ii]['loaded']) {
-			                		$this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
-			                		$url = $list2[$ii]['location'];
-									if ($url != '') {
-										$urlparts = parse_url($url);
-										if (!isset($urlparts['host'])) {
-											$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
-													substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
-										}
-										if (! in_array($url, $imported_urls)) {
-						                	$this->parseWSDL($url);
-					                		$imported++;
-					                		$imported_urls[] = $url;
-					                	}
-									} else {
-										$this->debug("Unexpected scenario: empty URL for unloaded import");
-									}
-								}
-							}
-			            } 
-        			}
-        		}
-        		// WSDL imports
-				$wsdlparts = parse_url($this->wsdl);	// this is bogusly simple!
-	            foreach ($this->import as $ns => $list) {
-	                for ($ii = 0; $ii < count($list); $ii++) {
-	                	if (! $list[$ii]['loaded']) {
-	                		$this->import[$ns][$ii]['loaded'] = true;
-	                		$url = $list[$ii]['location'];
-							if ($url != '') {
-								$urlparts = parse_url($url);
-								if (!isset($urlparts['host'])) {
-									$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
-											substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
-								}
-								if (! in_array($url, $imported_urls)) {
-				                	$this->parseWSDL($url);
-			                		$imported++;
-			                		$imported_urls[] = $url;
-			                	}
-							} else {
-								$this->debug("Unexpected scenario: empty URL for unloaded import");
-							}
-						}
-					}
-	            } 
-			}
-        // add new data to operation data
-        foreach($this->bindings as $binding => $bindingData) {
-            if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
-                foreach($bindingData['operations'] as $operation => $data) {
-                    $this->debug('post-parse data gathering for ' . $operation);
-                    $this->bindings[$binding]['operations'][$operation]['input'] = 
-						isset($this->bindings[$binding]['operations'][$operation]['input']) ? 
-						array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
-						$this->portTypes[ $bindingData['portType'] ][$operation]['input'];
-                    $this->bindings[$binding]['operations'][$operation]['output'] = 
-						isset($this->bindings[$binding]['operations'][$operation]['output']) ?
-						array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
-						$this->portTypes[ $bindingData['portType'] ][$operation]['output'];
-                    if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
-						$this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
-					}
-					if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
-                   		$this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
-                    }
-					if (isset($bindingData['style'])) {
-                        $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
-                    }
-                    $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
-                    $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
-                    $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
-                } 
-            } 
-        }
-    }
-
-    /**
-     * parses the wsdl document
-     * 
-     * @param string $wsdl path or URL
-     * @access private 
-     */
-    function parseWSDL($wsdl = '')
-    {
-        if ($wsdl == '') {
-            $this->debug('no wsdl passed to parseWSDL()!!');
-            $this->setError('no wsdl passed to parseWSDL()!!');
-            return false;
-        }
-        
-        // parse $wsdl for url format
-        $wsdl_props = parse_url($wsdl);
-
-        if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
-            $this->debug('getting WSDL http(s) URL ' . $wsdl);
-        	// get wsdl
-	        $tr = new soap_transport_http($wsdl);
-			$tr->request_method = 'GET';
-			$tr->useSOAPAction = false;
-			if($this->proxyhost && $this->proxyport){
-				$tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
-			}
-			$tr->setEncoding('gzip, deflate');
-			$wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
-			//$this->debug("WSDL request\n" . $tr->outgoing_payload);
-			//$this->debug("WSDL response\n" . $tr->incoming_payload);
-			$this->appendDebug($tr->getDebug());
-			// catch errors
-			if($err = $tr->getError() ){
-				$errstr = 'HTTP ERROR: '.$err;
-				$this->debug($errstr);
-	            $this->setError($errstr);
-				unset($tr);
-	            return false;
-			}
-			unset($tr);
-			$this->debug("got WSDL URL");
-        } else {
-            // $wsdl is not http(s), so treat it as a file URL or plain file path
-        	if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
-        		$path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
-        	} else {
-        		$path = $wsdl;
-        	}
-            $this->debug('getting WSDL file ' . $path);
-            if ($fp = @fopen($path, 'r')) {
-                $wsdl_string = '';
-                while ($data = fread($fp, 32768)) {
-                    $wsdl_string .= $data;
-                } 
-                fclose($fp);
-            } else {
-            	$errstr = "Bad path to WSDL file $path";
-            	$this->debug($errstr);
-                $this->setError($errstr);
-                return false;
-            } 
-        }
-        $this->debug('Parse WSDL');
-        // end new code added
-        // Create an XML parser.
-        $this->parser = xml_parser_create(); 
-        // Set the options for parsing the XML data.
-        // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
-        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 
-        // Set the object for the parser.
-        xml_set_object($this->parser, $this); 
-        // Set the element handlers for the parser.
-        xml_set_element_handler($this->parser, 'start_element', 'end_element');
-        xml_set_character_data_handler($this->parser, 'character_data');
-        // Parse the XML file.
-        if (!xml_parse($this->parser, $wsdl_string, true)) {
-            // Display an error message.
-            $errstr = sprintf(
-				'XML error parsing WSDL from %s on line %d: %s',
-				$wsdl,
-                xml_get_current_line_number($this->parser),
-                xml_error_string(xml_get_error_code($this->parser))
-                );
-            $this->debug($errstr);
-			$this->debug("XML payload:\n" . $wsdl_string);
-            $this->setError($errstr);
-            return false;
-        } 
-		// free the parser
-        xml_parser_free($this->parser);
-        $this->debug('Parsing WSDL done');
-		// catch wsdl parse errors
-		if($this->getError()){
-			return false;
-		}
-        return true;
-    } 
-
-    /**
-     * start-element handler
-     * 
-     * @param string $parser XML parser object
-     * @param string $name element name
-     * @param string $attrs associative array of attributes
-     * @access private 
-     */
-    function start_element($parser, $name, $attrs)
-    {
-        if ($this->status == 'schema') {
-            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
-            $this->appendDebug($this->currentSchema->getDebug());
-            $this->currentSchema->clearDebug();
-        } elseif (ereg('schema$', $name)) {
-        	$this->debug('Parsing WSDL schema');
-            // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
-            $this->status = 'schema';
-            $this->currentSchema = new xmlschema('', '', $this->namespaces);
-            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
-            $this->appendDebug($this->currentSchema->getDebug());
-            $this->currentSchema->clearDebug();
-        } else {
-            // position in the total number of elements, starting from 0
-            $pos = $this->position++;
-            $depth = $this->depth++; 
-            // set self as current value for this depth
-            $this->depth_array[$depth] = $pos;
-            $this->message[$pos] = array('cdata' => ''); 
-            // process attributes
-            if (count($attrs) > 0) {
-				// register namespace declarations
-                foreach($attrs as $k => $v) {
-                    if (ereg("^xmlns", $k)) {
-                        if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
-                            $this->namespaces[$ns_prefix] = $v;
-                        } else {
-                            $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
-                        } 
-                        if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
-                            $this->XMLSchemaVersion = $v;
-                            $this->namespaces['xsi'] = $v . '-instance';
-                        } 
-                    }
-                }
-                // expand each attribute prefix to its namespace
-                foreach($attrs as $k => $v) {
-                    $k = strpos($k, ':') ? $this->expandQname($k) : $k;
-                    if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
-                        $v = strpos($v, ':') ? $this->expandQname($v) : $v;
-                    } 
-                    $eAttrs[$k] = $v;
-                } 
-                $attrs = $eAttrs;
-            } else {
-                $attrs = array();
-            } 
-            // get element prefix, namespace and name
-            if (ereg(':', $name)) {
-                // get ns prefix
-                $prefix = substr($name, 0, strpos($name, ':')); 
-                // get ns
-                $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; 
-                // get unqualified name
-                $name = substr(strstr($name, ':'), 1);
-            } 
-			// process attributes, expanding any prefixes to namespaces
-            // find status, register data
-            switch ($this->status) {
-                case 'message':
-                    if ($name == 'part') {
-			            if (isset($attrs['type'])) {
-		                    $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
-		                    $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
-            			} 
-			            if (isset($attrs['element'])) {
-		                    $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
-			                $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'];
-			            } 
-        			} 
-        			break;
-			    case 'portType':
-			        switch ($name) {
-			            case 'operation':
-			                $this->currentPortOperation = $attrs['name'];
-			                $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
-			                if (isset($attrs['parameterOrder'])) {
-			                	$this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
-			        		} 
-			        		break;
-					    case 'documentation':
-					        $this->documentation = true;
-					        break; 
-					    // merge input/output data
-					    default:
-					        $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
-					        $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
-					        break;
-					} 
-			    	break;
-				case 'binding':
-				    switch ($name) {
-				        case 'binding': 
-				            // get ns prefix
-				            if (isset($attrs['style'])) {
-				            $this->bindings[$this->currentBinding]['prefix'] = $prefix;
-					    	} 
-					    	$this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
-					    	break;
-						case 'header':
-						    $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
-						    break;
-						case 'operation':
-						    if (isset($attrs['soapAction'])) {
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
-						    } 
-						    if (isset($attrs['style'])) {
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
-						    } 
-						    if (isset($attrs['name'])) {
-						        $this->currentOperation = $attrs['name'];
-						        $this->debug("current binding operation: $this->currentOperation");
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
-						    } 
-						    break;
-						case 'input':
-						    $this->opStatus = 'input';
-						    break;
-						case 'output':
-						    $this->opStatus = 'output';
-						    break;
-						case 'body':
-						    if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
-						    } else {
-						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
-						    } 
-						    break;
-					} 
-					break;
-				case 'service':
-					switch ($name) {
-					    case 'port':
-					        $this->currentPort = $attrs['name'];
-					        $this->debug('current port: ' . $this->currentPort);
-					        $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
-					
-					        break;
-					    case 'address':
-					        $this->ports[$this->currentPort]['location'] = $attrs['location'];
-					        $this->ports[$this->currentPort]['bindingType'] = $namespace;
-					        $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
-					        $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
-					        break;
-					} 
-					break;
-			} 
-		// set status
-		switch ($name) {
-			case 'import':
-			    if (isset($attrs['location'])) {
-                    $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
-                    $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
-				} else {
-                    $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
-					if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
-						$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
-					}
-                    $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
-				}
-				break;
-			//wait for schema
-			//case 'types':
-			//	$this->status = 'schema';
-			//	break;
-			case 'message':
-				$this->status = 'message';
-				$this->messages[$attrs['name']] = array();
-				$this->currentMessage = $attrs['name'];
-				break;
-			case 'portType':
-				$this->status = 'portType';
-				$this->portTypes[$attrs['name']] = array();
-				$this->currentPortType = $attrs['name'];
-				break;
-			case "binding":
-				if (isset($attrs['name'])) {
-				// get binding name
-					if (strpos($attrs['name'], ':')) {
-			    		$this->currentBinding = $this->getLocalPart($attrs['name']);
-					} else {
-			    		$this->currentBinding = $attrs['name'];
-					} 
-					$this->status = 'binding';
-					$this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
-					$this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
-				} 
-				break;
-			case 'service':
-				$this->serviceName = $attrs['name'];
-				$this->status = 'service';
-				$this->debug('current service: ' . $this->serviceName);
-				break;
-			case 'definitions':
-				foreach ($attrs as $name => $value) {
-					$this->wsdl_info[$name] = $value;
-				} 
-				break;
-			} 
-		} 
-	} 
-
-	/**
-	* end-element handler
-	* 
-	* @param string $parser XML parser object
-	* @param string $name element name
-	* @access private 
-	*/
-	function end_element($parser, $name){ 
-		// unset schema status
-		if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) {
-			$this->status = "";
-            $this->appendDebug($this->currentSchema->getDebug());
-            $this->currentSchema->clearDebug();
-			$this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
-        	$this->debug('Parsing WSDL schema done');
-		} 
-		if ($this->status == 'schema') {
-			$this->currentSchema->schemaEndElement($parser, $name);
-		} else {
-			// bring depth down a notch
-			$this->depth--;
-		} 
-		// end documentation
-		if ($this->documentation) {
-			//TODO: track the node to which documentation should be assigned; it can be a part, message, etc.
-			//$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
-			$this->documentation = false;
-		} 
-	} 
-
-	/**
-	 * element content handler
-	 * 
-	 * @param string $parser XML parser object
-	 * @param string $data element content
-	 * @access private 
-	 */
-	function character_data($parser, $data)
-	{
-		$pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
-		if (isset($this->message[$pos]['cdata'])) {
-			$this->message[$pos]['cdata'] .= $data;
-		} 
-		if ($this->documentation) {
-			$this->documentation .= $data;
-		} 
-	} 
-	
-	function getBindingData($binding)
-	{
-		if (is_array($this->bindings[$binding])) {
-			return $this->bindings[$binding];
-		} 
-	}
-	
-	/**
-	 * returns an assoc array of operation names => operation data
-	 * 
-	 * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported)
-	 * @return array 
-	 * @access public 
-	 */
-	function getOperations($bindingType = 'soap')
-	{
-		$ops = array();
-		if ($bindingType == 'soap') {
-			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
-		}
-		// loop thru ports
-		foreach($this->ports as $port => $portData) {
-			// binding type of port matches parameter
-			if ($portData['bindingType'] == $bindingType) {
-				//$this->debug("getOperations for port $port");
-				//$this->debug("port data: " . $this->varDump($portData));
-				//$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));
-				// merge bindings
-				if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
-					$ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
-				}
-			}
-		} 
-		return $ops;
-	} 
-	
-	/**
-	 * returns an associative array of data necessary for calling an operation
-	 * 
-	 * @param string $operation , name of operation
-	 * @param string $bindingType , type of binding eg: soap
-	 * @return array 
-	 * @access public 
-	 */
-	function getOperationData($operation, $bindingType = 'soap')
-	{
-		if ($bindingType == 'soap') {
-			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
-		}
-		// loop thru ports
-		foreach($this->ports as $port => $portData) {
-			// binding type of port matches parameter
-			if ($portData['bindingType'] == $bindingType) {
-				// get binding
-				//foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
-				foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
-					// note that we could/should also check the namespace here
-					if ($operation == $bOperation) {
-						$opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
-					    return $opData;
-					} 
-				} 
-			}
-		} 
-	}
-	
-	/**
-	 * returns an associative array of data necessary for calling an operation
-	 * 
-	 * @param string $soapAction soapAction for operation
-	 * @param string $bindingType type of binding eg: soap
-	 * @return array 
-	 * @access public 
-	 */
-	function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
-		if ($bindingType == 'soap') {
-			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
-		}
-		// loop thru ports
-		foreach($this->ports as $port => $portData) {
-			// binding type of port matches parameter
-			if ($portData['bindingType'] == $bindingType) {
-				// loop through operations for the binding
-				foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
-					if ($opData['soapAction'] == $soapAction) {
-					    return $opData;
-					} 
-				} 
-			}
-		} 
-	}
-	
-	/**
-    * returns an array of information about a given type
-    * returns false if no type exists by the given name
-    *
-	*	 typeDef = array(
-	*	 'elements' => array(), // refs to elements array
-	*	'restrictionBase' => '',
-	*	'phpType' => '',
-	*	'order' => '(sequence|all)',
-	*	'attrs' => array() // refs to attributes array
-	*	)
-    *
-    * @param $type string the type
-    * @param $ns string namespace (not prefix) of the type
-    * @return mixed
-    * @access public
-    * @see xmlschema
-    */
-	function getTypeDef($type, $ns) {
-		$this->debug("in getTypeDef: type=$type, ns=$ns");
-		if ((! $ns) && isset($this->namespaces['tns'])) {
-			$ns = $this->namespaces['tns'];
-			$this->debug("in getTypeDef: type namespace forced to $ns");
-		}
-		if (isset($this->schemas[$ns])) {
-			$this->debug("in getTypeDef: have schema for namespace $ns");
-			for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
-				$xs = &$this->schemas[$ns][$i];
-				$t = $xs->getTypeDef($type);
-				$this->appendDebug($xs->getDebug());
-				$xs->clearDebug();
-				if ($t) {
-					if (!isset($t['phpType'])) {
-						// get info for type to tack onto the element
-						$uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
-						$ns = substr($t['type'], 0, strrpos($t['type'], ':'));
-						$etype = $this->getTypeDef($uqType, $ns);
-						if ($etype) {
-							$this->debug("found type for [element] $type:");
-							$this->debug($this->varDump($etype));
-							if (isset($etype['phpType'])) {
-								$t['phpType'] = $etype['phpType'];
-							}
-							if (isset($etype['elements'])) {
-								$t['elements'] = $etype['elements'];
-							}
-							if (isset($etype['attrs'])) {
-								$t['attrs'] = $etype['attrs'];
-							}
-						}
-					}
-					return $t;
-				}
-			}
-		} else {
-			$this->debug("in getTypeDef: do not have schema for namespace $ns");
-		}
-		return false;
-	}
-
-    /**
-    * prints html description of services
-    *
-    * @access private
-    */
-    function webDescription(){
-    	global $HTTP_SERVER_VARS;
-
-		if (isset($_SERVER)) {
-			$PHP_SELF = $_SERVER['PHP_SELF'];
-		} elseif (isset($HTTP_SERVER_VARS)) {
-			$PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
-		} else {
-			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
-		}
-
-		$b = '
-		<html><head><title>NuSOAP: '.$this->serviceName.'</title>
-		<style type="text/css">
-		    body    { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
-		    p       { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
-		    pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
-		    ul      { margin-top: 10px; margin-left: 20px; }
-		    li      { list-style-type: none; margin-top: 10px; color: #000000; }
-		    .content{
-			margin-left: 0px; padding-bottom: 2em; }
-		    .nav {
-			padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
-			margin-top: 10px; margin-left: 0px; color: #000000;
-			background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
-		    .title {
-			font-family: arial; font-size: 26px; color: #ffffff;
-			background-color: #999999; width: 105%; margin-left: 0px;
-			padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
-		    .hidden {
-			position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
-			font-family: arial; overflow: hidden; width: 600;
-			padding: 20px; font-size: 10px; background-color: #999999;
-			layer-background-color:#FFFFFF; }
-		    a,a:active  { color: charcoal; font-weight: bold; }
-		    a:visited   { color: #666666; font-weight: bold; }
-		    a:hover     { color: cc3300; font-weight: bold; }
-		</style>
-		<script language="JavaScript" type="text/javascript">
-		<!--
-		// POP-UP CAPTIONS...
-		function lib_bwcheck(){ //Browsercheck (needed)
-		    this.ver=navigator.appVersion
-		    this.agent=navigator.userAgent
-		    this.dom=document.getElementById?1:0
-		    this.opera5=this.agent.indexOf("Opera 5")>-1
-		    this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
-		    this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
-		    this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
-		    this.ie=this.ie4||this.ie5||this.ie6
-		    this.mac=this.agent.indexOf("Mac")>-1
-		    this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
-		    this.ns4=(document.layers && !this.dom)?1:0;
-		    this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
-		    return this
-		}
-		var bw = new lib_bwcheck()
-		//Makes crossbrowser object.
-		function makeObj(obj){
-		    this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
-		    if(!this.evnt) return false
-		    this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
-		    this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
-		    this.writeIt=b_writeIt;
-		    return this
-		}
-		// A unit of measure that will be added when setting the position of a layer.
-		//var px = bw.ns4||window.opera?"":"px";
-		function b_writeIt(text){
-		    if (bw.ns4){this.wref.write(text);this.wref.close()}
-		    else this.wref.innerHTML = text
-		}
-		//Shows the messages
-		var oDesc;
-		function popup(divid){
-		    if(oDesc = new makeObj(divid)){
-			oDesc.css.visibility = "visible"
-		    }
-		}
-		function popout(){ // Hides message
-		    if(oDesc) oDesc.css.visibility = "hidden"
-		}
-		//-->
-		</script>
-		</head>
-		<body>
-		<div class=content>
-			<br><br>
-			<div class=title>'.$this->serviceName.'</div>
-			<div class=nav>
-				<p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
-				Click on an operation name to view it&apos;s details.</p>
-				<ul>';
-				foreach($this->getOperations() as $op => $data){
-				    $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
-				    // create hidden div
-				    $b .= "<div id='$op' class='hidden'>
-				    <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
-				    foreach($data as $donnie => $marie){ // loop through opdata
-						if($donnie == 'input' || $donnie == 'output'){ // show input/output data
-						    $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
-						    foreach($marie as $captain => $tenille){ // loop through data
-								if($captain == 'parts'){ // loop thru parts
-								    $b .= "&nbsp;&nbsp;$captain:<br>";
-					                //if(is_array($tenille)){
-								    	foreach($tenille as $joanie => $chachi){
-											$b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
-								    	}
-					        		//}
-								} else {
-								    $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
-								}
-						    }
-						} else {
-						    $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
-						}
-				    }
-					$b .= '</div>';
-				}
-				$b .= '
-				<ul>
-			</div>
-		</div></body></html>';
-		return $b;
-    }
-
-	/**
-	* serialize the parsed wsdl
-	*
-	* @param mixed $debug whether to put debug=1 in endpoint URL
-	* @return string serialization of WSDL
-	* @access public 
-	*/
-	function serialize($debug = 0)
-	{
-		$xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
-		$xml .= "\n<definitions";
-		foreach($this->namespaces as $k => $v) {
-			$xml .= " xmlns:$k=\"$v\"";
-		} 
-		// 10.9.02 - add poulter fix for wsdl and tns declarations
-		if (isset($this->namespaces['wsdl'])) {
-			$xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
-		} 
-		if (isset($this->namespaces['tns'])) {
-			$xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
-		} 
-		$xml .= '>'; 
-		// imports
-		if (sizeof($this->import) > 0) {
-			foreach($this->import as $ns => $list) {
-				foreach ($list as $ii) {
-					if ($ii['location'] != '') {
-						$xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
-					} else {
-						$xml .= '<import namespace="' . $ns . '" />';
-					}
-				}
-			} 
-		} 
-		// types
-		if (count($this->schemas)>=1) {
-			$xml .= "\n<types>";
-			foreach ($this->schemas as $ns => $list) {
-				foreach ($list as $xs) {
-					$xml .= $xs->serializeSchema();
-				}
-			}
-			$xml .= '</types>';
-		} 
-		// messages
-		if (count($this->messages) >= 1) {
-			foreach($this->messages as $msgName => $msgParts) {
-				$xml .= "\n<message name=\"" . $msgName . '">';
-				if(is_array($msgParts)){
-					foreach($msgParts as $partName => $partType) {
-						// print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';
-						if (strpos($partType, ':')) {
-						    $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
-						} elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
-						    // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';
-						    $typePrefix = 'xsd';
-						} else {
-						    foreach($this->typemap as $ns => $types) {
-						        if (isset($types[$partType])) {
-						            $typePrefix = $this->getPrefixFromNamespace($ns);
-						        } 
-						    } 
-						    if (!isset($typePrefix)) {
-						        die("$partType has no namespace!");
-						    } 
-						}
-						$ns = $this->getNamespaceFromPrefix($typePrefix);
-						$typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns);
-						if ($typeDef['typeClass'] == 'element') {
-							$elementortype = 'element';
-						} else {
-							$elementortype = 'type';
-						}
-						$xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />';
-					}
-				}
-				$xml .= '</message>';
-			} 
-		} 
-		// bindings & porttypes
-		if (count($this->bindings) >= 1) {
-			$binding_xml = '';
-			$portType_xml = '';
-			foreach($this->bindings as $bindingName => $attrs) {
-				$binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
-				$binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
-				$portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
-				foreach($attrs['operations'] as $opName => $opParts) {
-					$binding_xml .= '<operation name="' . $opName . '">';
-					$binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
-					if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
-						$enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
-					} else {
-						$enc_style = '';
-					}
-					$binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
-					if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
-						$enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
-					} else {
-						$enc_style = '';
-					}
-					$binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
-					$binding_xml .= '</operation>';
-					$portType_xml .= '<operation name="' . $opParts['name'] . '"';
-					if (isset($opParts['parameterOrder'])) {
-					    $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
-					} 
-					$portType_xml .= '>';
-					if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
-						$portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
-					}
-					$portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>';
-					$portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>';
-					$portType_xml .= '</operation>';
-				} 
-				$portType_xml .= '</portType>';
-				$binding_xml .= '</binding>';
-			} 
-			$xml .= $portType_xml . $binding_xml;
-		} 
-		// services
-		$xml .= "\n<service name=\"" . $this->serviceName . '">';
-		if (count($this->ports) >= 1) {
-			foreach($this->ports as $pName => $attrs) {
-				$xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
-				$xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
-				$xml .= '</port>';
-			} 
-		} 
-		$xml .= '</service>';
-		return $xml . "\n</definitions>";
-	} 
-	
-	/**
-	 * serialize PHP values according to a WSDL message definition
-	 *
-	 * TODO
-	 * - multi-ref serialization
-	 * - validate PHP values against type definitions, return errors if invalid
-	 * 
-	 * @param string $operation operation name
-	 * @param string $direction (input|output)
-	 * @param mixed $parameters parameter value(s)
-	 * @return mixed parameters serialized as XML or false on error (e.g. operation not found)
-	 * @access public
-	 */
-	function serializeRPCParameters($operation, $direction, $parameters)
-	{
-		$this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
-		$this->appendDebug('parameters=' . $this->varDump($parameters));
-		
-		if ($direction != 'input' && $direction != 'output') {
-			$this->debug('The value of the \$direction argument needs to be either "input" or "output"');
-			$this->setError('The value of the \$direction argument needs to be either "input" or "output"');
-			return false;
-		} 
-		if (!$opData = $this->getOperationData($operation)) {
-			$this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
-			$this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
-			return false;
-		}
-		$this->debug('opData:');
-		$this->appendDebug($this->varDump($opData));
-
-		// Get encoding style for output and set to current
-		$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-		if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
-			$encodingStyle = $opData['output']['encodingStyle'];
-			$enc_style = $encodingStyle;
-		}
-
-		// set input params
-		$xml = '';
-		if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
-			
-			$use = $opData[$direction]['use'];
-			$this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize');
-			if (is_array($parameters)) {
-				$parametersArrayType = $this->isArraySimpleOrStruct($parameters);
-				$this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize');
-				foreach($opData[$direction]['parts'] as $name => $type) {
-					$this->debug('serializing part "'.$name.'" of type "'.$type.'"');
-					// Track encoding style
-					if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
-						$encodingStyle = $opData[$direction]['encodingStyle'];			
-						$enc_style = $encodingStyle;
-					} else {
-						$enc_style = false;
-					}
-					// NOTE: add error handling here
-					// if serializeType returns false, then catch global error and fault
-					if ($parametersArrayType == 'arraySimple') {
-						$p = array_shift($parameters);
-						$this->debug('calling serializeType w/indexed param');
-						$xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
-					} elseif (isset($parameters[$name])) {
-						$this->debug('calling serializeType w/named param');
-						$xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
-					} else {
-						// TODO: only send nillable
-						$this->debug('calling serializeType w/null param');
-						$xml .= $this->serializeType($name, $type, null, $use, $enc_style);
-					}
-				}
-			} else {
-				$this->debug('no parameters passed.');
-			}
-		}
-		$this->debug("serializeRPCParameters returning: $xml");
-		return $xml;
-	} 
-	
-	/**
-	 * serialize a PHP value according to a WSDL message definition
-	 * 
-	 * TODO
-	 * - multi-ref serialization
-	 * - validate PHP values against type definitions, return errors if invalid
-	 * 
-	 * @param string $ type name
-	 * @param mixed $ param value
-	 * @return mixed new param or false if initial value didn't validate
-	 * @access public
-	 * @deprecated
-	 */
-	function serializeParameters($operation, $direction, $parameters)
-	{
-		$this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
-		$this->appendDebug('parameters=' . $this->varDump($parameters));
-		
-		if ($direction != 'input' && $direction != 'output') {
-			$this->debug('The value of the \$direction argument needs to be either "input" or "output"');
-			$this->setError('The value of the \$direction argument needs to be either "input" or "output"');
-			return false;
-		} 
-		if (!$opData = $this->getOperationData($operation)) {
-			$this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
-			$this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
-			return false;
-		}
-		$this->debug('opData:');
-		$this->appendDebug($this->varDump($opData));
-		
-		// Get encoding style for output and set to current
-		$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-		if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
-			$encodingStyle = $opData['output']['encodingStyle'];
-			$enc_style = $encodingStyle;
-		}
-		
-		// set input params
-		$xml = '';
-		if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
-			
-			$use = $opData[$direction]['use'];
-			$this->debug("use=$use");
-			$this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
-			if (is_array($parameters)) {
-				$parametersArrayType = $this->isArraySimpleOrStruct($parameters);
-				$this->debug('have ' . $parametersArrayType . ' parameters');
-				foreach($opData[$direction]['parts'] as $name => $type) {
-					$this->debug('serializing part "'.$name.'" of type "'.$type.'"');
-					// Track encoding style
-					if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
-						$encodingStyle = $opData[$direction]['encodingStyle'];			
-						$enc_style = $encodingStyle;
-					} else {
-						$enc_style = false;
-					}
-					// NOTE: add error handling here
-					// if serializeType returns false, then catch global error and fault
-					if ($parametersArrayType == 'arraySimple') {
-						$p = array_shift($parameters);
-						$this->debug('calling serializeType w/indexed param');
-						$xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
-					} elseif (isset($parameters[$name])) {
-						$this->debug('calling serializeType w/named param');
-						$xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
-					} else {
-						// TODO: only send nillable
-						$this->debug('calling serializeType w/null param');
-						$xml .= $this->serializeType($name, $type, null, $use, $enc_style);
-					}
-				}
-			} else {
-				$this->debug('no parameters passed.');
-			}
-		}
-		$this->debug("serializeParameters returning: $xml");
-		return $xml;
-	} 
-	
-	/**
-	 * serializes a PHP value according a given type definition
-	 * 
-	 * @param string $name name of value (part or element)
-	 * @param string $type XML schema type of value (type or element)
-	 * @param mixed $value a native PHP value (parameter value)
-	 * @param string $use use for part (encoded|literal)
-	 * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
-	 * @param boolean $unqualified a kludge for what should be XML namespace form handling
-	 * @return string value serialized as an XML string
-	 * @access private
-	 */
-	function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
-	{
-		$this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
-		$this->appendDebug("value=" . $this->varDump($value));
-		if($use == 'encoded' && $encodingStyle) {
-			$encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
-		}
-
-		// if a soapval has been supplied, let its type override the WSDL
-    	if (is_object($value) && get_class($value) == 'soapval') {
-    		if ($value->type_ns) {
-    			$type = $value->type_ns . ':' . $value->type;
-		    	$forceType = true;
-		    	$this->debug("in serializeType: soapval overrides type to $type");
-    		} elseif ($value->type) {
-	    		$type = $value->type;
-		    	$forceType = true;
-		    	$this->debug("in serializeType: soapval overrides type to $type");
-	    	} else {
-	    		$forceType = false;
-		    	$this->debug("in serializeType: soapval does not override type");
-	    	}
-	    	$attrs = $value->attributes;
-	    	$value = $value->value;
-	    	$this->debug("in serializeType: soapval overrides value to $value");
-	    	if ($attrs) {
-	    		if (!is_array($value)) {
-	    			$value['!'] = $value;
-	    		}
-	    		foreach ($attrs as $n => $v) {
-	    			$value['!' . $n] = $v;
-	    		}
-		    	$this->debug("in serializeType: soapval provides attributes");
-		    }
-        } else {
-        	$forceType = false;
-        }
-
-		$xml = '';
-		if (strpos($type, ':')) {
-			$uqType = substr($type, strrpos($type, ':') + 1);
-			$ns = substr($type, 0, strrpos($type, ':'));
-			$this->debug("in serializeType: got a prefixed type: $uqType, $ns");
-			if ($this->getNamespaceFromPrefix($ns)) {
-				$ns = $this->getNamespaceFromPrefix($ns);
-				$this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
-			}
-
-			if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
-				$this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
-				if ($unqualified  && $use == 'literal') {
-					$elementNS = " xmlns=\"\"";
-				} else {
-					$elementNS = '';
-				}
-				if (is_null($value)) {
-					if ($use == 'literal') {
-						// TODO: depends on minOccurs
-						$xml = "<$name$elementNS/>";
-					} else {
-						// TODO: depends on nillable, which should be checked before calling this method
-						$xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
-					}
-					$this->debug("in serializeType: returning: $xml");
-					return $xml;
-				}
-		    	if ($uqType == 'boolean') {
-		    		if ((is_string($value) && $value == 'false') || (! $value)) {
-						$value = 'false';
-					} else {
-						$value = 'true';
-					}
-				} 
-				if ($uqType == 'string' && gettype($value) == 'string') {
-					$value = $this->expandEntities($value);
-				}
-				if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
-					$value = sprintf("%.0lf", $value);
-				}
-				// it's a scalar
-				// TODO: what about null/nil values?
-				// check type isn't a custom type extending xmlschema namespace
-				if (!$this->getTypeDef($uqType, $ns)) {
-					if ($use == 'literal') {
-						if ($forceType) {
-							$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
-						} else {
-							$xml = "<$name$elementNS>$value</$name>";
-						}
-					} else {
-						$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
-					}
-					$this->debug("in serializeType: returning: $xml");
-					return $xml;
-				}
-				$this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
-			} else if ($ns == 'http://xml.apache.org/xml-soap') {
-				$this->debug('in serializeType: appears to be Apache SOAP type');
-				if ($uqType == 'Map') {
-					$tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
-					if (! $tt_prefix) {
-						$this->debug('in serializeType: Add namespace for Apache SOAP type');
-						$tt_prefix = 'ns' . rand(1000, 9999);
-						$this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
-						// force this to be added to usedNamespaces
-						$tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
-					}
-					$contents = '';
-					foreach($value as $k => $v) {
-						$this->debug("serializing map element: key $k, value $v");
-						$contents .= '<item>';
-						$contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
-						$contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
-						$contents .= '</item>';
-					}
-					if ($use == 'literal') {
-						if ($forceType) {
-							$xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
-						} else {
-							$xml = "<$name>$contents</$name>";
-						}
-					} else {
-						$xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
-					}
-					$this->debug("in serializeType: returning: $xml");
-					return $xml;
-				}
-				$this->debug('in serializeType: Apache SOAP type, but only support Map');
-			}
-		} else {
-			// TODO: should the type be compared to types in XSD, and the namespace
-			// set to XSD if the type matches?
-			$this->debug("in serializeType: No namespace for type $type");
-			$ns = '';
-			$uqType = $type;
-		}
-		if(!$typeDef = $this->getTypeDef($uqType, $ns)){
-			$this->setError("$type ($uqType) is not a supported type.");
-			$this->debug("in serializeType: $type ($uqType) is not a supported type.");
-			return false;
-		} else {
-			$this->debug("in serializeType: found typeDef");
-			$this->appendDebug('typeDef=' . $this->varDump($typeDef));
-		}
-		$phpType = $typeDef['phpType'];
-		$this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); 
-		// if php type == struct, map value to the <all> element names
-		if ($phpType == 'struct') {
-			if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
-				$elementName = $uqType;
-				if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
-					$elementNS = " xmlns=\"$ns\"";
-				} else {
-					$elementNS = " xmlns=\"\"";
-				}
-			} else {
-				$elementName = $name;
-				if ($unqualified) {
-					$elementNS = " xmlns=\"\"";
-				} else {
-					$elementNS = '';
-				}
-			}
-			if (is_null($value)) {
-				if ($use == 'literal') {
-					// TODO: depends on minOccurs
-					$xml = "<$elementName$elementNS/>";
-				} else {
-					$xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
-				}
-				$this->debug("in serializeType: returning: $xml");
-				return $xml;
-			}
-			if (is_object($value)) {
-				$value = get_object_vars($value);
-			}
-			if (is_array($value)) {
-				$elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
-				if ($use == 'literal') {
-					if ($forceType) {
-						$xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
-					} else {
-						$xml = "<$elementName$elementNS$elementAttrs>";
-					}
-				} else {
-					$xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
-				}
-	
-				$xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
-				$xml .= "</$elementName>";
-			} else {
-				$this->debug("in serializeType: phpType is struct, but value is not an array");
-				$this->setError("phpType is struct, but value is not an array: see debug output for details");
-				$xml = '';
-			}
-		} elseif ($phpType == 'array') {
-			if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
-				$elementNS = " xmlns=\"$ns\"";
-			} else {
-				if ($unqualified) {
-					$elementNS = " xmlns=\"\"";
-				} else {
-					$elementNS = '';
-				}
-			}
-			if (is_null($value)) {
-				if ($use == 'literal') {
-					// TODO: depends on minOccurs
-					$xml = "<$name$elementNS/>";
-				} else {
-					$xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
-						$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
-						":Array\" " .
-						$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
-						':arrayType="' .
-						$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
-						':' .
-						$this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
-				}
-				$this->debug("in serializeType: returning: $xml");
-				return $xml;
-			}
-			if (isset($typeDef['multidimensional'])) {
-				$nv = array();
-				foreach($value as $v) {
-					$cols = ',' . sizeof($v);
-					$nv = array_merge($nv, $v);
-				} 
-				$value = $nv;
-			} else {
-				$cols = '';
-			} 
-			if (is_array($value) && sizeof($value) >= 1) {
-				$rows = sizeof($value);
-				$contents = '';
-				foreach($value as $k => $v) {
-					$this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
-					//if (strpos($typeDef['arrayType'], ':') ) {
-					if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
-					    $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
-					} else {
-					    $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
-					} 
-				}
-			} else {
-				$rows = 0;
-				$contents = null;
-			}
-			// TODO: for now, an empty value will be serialized as a zero element
-			// array.  Revisit this when coding the handling of null/nil values.
-			if ($use == 'literal') {
-				$xml = "<$name$elementNS>"
-					.$contents
-					."</$name>";
-			} else {
-				$xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
-					$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
-					.':arrayType="'
-					.$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
-					.":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
-					.$contents
-					."</$name>";
-			}
-		} elseif ($phpType == 'scalar') {
-			if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
-				$elementNS = " xmlns=\"$ns\"";
-			} else {
-				if ($unqualified) {
-					$elementNS = " xmlns=\"\"";
-				} else {
-					$elementNS = '';
-				}
-			}
-			if ($use == 'literal') {
-				if ($forceType) {
-					$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
-				} else {
-					$xml = "<$name$elementNS>$value</$name>";
-				}
-			} else {
-				$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
-			}
-		}
-		$this->debug("in serializeType: returning: $xml");
-		return $xml;
-	}
-	
-	/**
-	 * serializes the attributes for a complexType
-	 *
-	 * @param array $typeDef our internal representation of an XML schema type (or element)
-	 * @param mixed $value a native PHP value (parameter value)
-	 * @param string $ns the namespace of the type
-	 * @param string $uqType the local part of the type
-	 * @return string value serialized as an XML string
-	 * @access private
-	 */
-	function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
-		$xml = '';
-		if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
-			$this->debug("serialize attributes for XML Schema type $ns:$uqType");
-			if (is_array($value)) {
-				$xvalue = $value;
-			} elseif (is_object($value)) {
-				$xvalue = get_object_vars($value);
-			} else {
-				$this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
-				$xvalue = array();
-			}
-			foreach ($typeDef['attrs'] as $aName => $attrs) {
-				if (isset($xvalue['!' . $aName])) {
-					$xname = '!' . $aName;
-					$this->debug("value provided for attribute $aName with key $xname");
-				} elseif (isset($xvalue[$aName])) {
-					$xname = $aName;
-					$this->debug("value provided for attribute $aName with key $xname");
-				} elseif (isset($attrs['default'])) {
-					$xname = '!' . $aName;
-					$xvalue[$xname] = $attrs['default'];
-					$this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
-				} else {
-					$xname = '';
-					$this->debug("no value provided for attribute $aName");
-				}
-				if ($xname) {
-					$xml .=  " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
-				}
-			} 
-		} else {
-			$this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
-		}
-		if (isset($typeDef['extensionBase'])) {
-			$ns = $this->getPrefix($typeDef['extensionBase']);
-			$uqType = $this->getLocalPart($typeDef['extensionBase']);
-			if ($this->getNamespaceFromPrefix($ns)) {
-				$ns = $this->getNamespaceFromPrefix($ns);
-			}
-			if ($typeDef = $this->getTypeDef($uqType, $ns)) {
-				$this->debug("serialize attributes for extension base $ns:$uqType");
-				$xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
-			} else {
-				$this->debug("extension base $ns:$uqType is not a supported type");
-			}
-		}
-		return $xml;
-	}
-
-	/**
-	 * serializes the elements for a complexType
-	 *
-	 * @param array $typeDef our internal representation of an XML schema type (or element)
-	 * @param mixed $value a native PHP value (parameter value)
-	 * @param string $ns the namespace of the type
-	 * @param string $uqType the local part of the type
-	 * @param string $use use for part (encoded|literal)
-	 * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
-	 * @return string value serialized as an XML string
-	 * @access private
-	 */
-	function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
-		$xml = '';
-		if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
-			$this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
-			if (is_array($value)) {
-				$xvalue = $value;
-			} elseif (is_object($value)) {
-				$xvalue = get_object_vars($value);
-			} else {
-				$this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
-				$xvalue = array();
-			}
-			// toggle whether all elements are present - ideally should validate against schema
-			if (count($typeDef['elements']) != count($xvalue)){
-				$optionals = true;
-			}
-			foreach ($typeDef['elements'] as $eName => $attrs) {
-				if (!isset($xvalue[$eName])) {
-					if (isset($attrs['default'])) {
-						$xvalue[$eName] = $attrs['default'];
-						$this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
-					}
-				}
-				// if user took advantage of a minOccurs=0, then only serialize named parameters
-				if (isset($optionals)
-				    && (!isset($xvalue[$eName])) 
-					&& ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
-					){
-					if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
-						$this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
-					}
-					// do nothing
-					$this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
-				} else {
-					// get value
-					if (isset($xvalue[$eName])) {
-					    $v = $xvalue[$eName];
-					} else {
-					    $v = null;
-					}
-					if (isset($attrs['form'])) {
-						$unqualified = ($attrs['form'] == 'unqualified');
-					} else {
-						$unqualified = false;
-					}
-					if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
-						$vv = $v;
-						foreach ($vv as $k => $v) {
-							if (isset($attrs['type']) || isset($attrs['ref'])) {
-								// serialize schema-defined type
-							    $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
-							} else {
-								// serialize generic type (can this ever really happen?)
-							    $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
-							    $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
-							}
-						}
-					} else {
-						if (isset($attrs['type']) || isset($attrs['ref'])) {
-							// serialize schema-defined type
-						    $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
-						} else {
-							// serialize generic type (can this ever really happen?)
-						    $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
-						    $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
-						}
-					}
-				}
-			} 
-		} else {
-			$this->debug("no elements to serialize for XML Schema type $ns:$uqType");
-		}
-		if (isset($typeDef['extensionBase'])) {
-			$ns = $this->getPrefix($typeDef['extensionBase']);
-			$uqType = $this->getLocalPart($typeDef['extensionBase']);
-			if ($this->getNamespaceFromPrefix($ns)) {
-				$ns = $this->getNamespaceFromPrefix($ns);
-			}
-			if ($typeDef = $this->getTypeDef($uqType, $ns)) {
-				$this->debug("serialize elements for extension base $ns:$uqType");
-				$xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
-			} else {
-				$this->debug("extension base $ns:$uqType is not a supported type");
-			}
-		}
-		return $xml;
-	}
-
-	/**
-	* adds an XML Schema complex type to the WSDL types
-	*
-	* @param string	name
-	* @param string typeClass (complexType|simpleType|attribute)
-	* @param string phpType: currently supported are array and struct (php assoc array)
-	* @param string compositor (all|sequence|choice)
-	* @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
-	* @param array elements = array ( name => array(name=>'',type=>'') )
-	* @param array attrs = 	array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))
-	* @param string arrayType: namespace:name (xsd:string)
-	* @see xmlschema
-	* @access public
-	*/
-	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
-		if (count($elements) > 0) {
-	    	foreach($elements as $n => $e){
-	            // expand each element
-	            foreach ($e as $k => $v) {
-		            $k = strpos($k,':') ? $this->expandQname($k) : $k;
-		            $v = strpos($v,':') ? $this->expandQname($v) : $v;
-		            $ee[$k] = $v;
-		    	}
-	    		$eElements[$n] = $ee;
-	    	}
-	    	$elements = $eElements;
-		}
-		
-		if (count($attrs) > 0) {
-	    	foreach($attrs as $n => $a){
-	            // expand each attribute
-	            foreach ($a as $k => $v) {
-		            $k = strpos($k,':') ? $this->expandQname($k) : $k;
-		            $v = strpos($v,':') ? $this->expandQname($v) : $v;
-		            $aa[$k] = $v;
-		    	}
-	    		$eAttrs[$n] = $aa;
-	    	}
-	    	$attrs = $eAttrs;
-		}
-
-		$restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
-		$arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
-
-		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
-		$this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
-	}
-
-	/**
-	* adds an XML Schema simple type to the WSDL types
-	*
-	* @param string $name
-	* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
-	* @param string $typeClass (should always be simpleType)
-	* @param string $phpType (should always be scalar)
-	* @param array $enumeration array of values
-	* @see xmlschema
-	* @access public
-	*/
-	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
-		$restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
-
-		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
-		$this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
-	}
-
-	/**
-	* adds an element to the WSDL types
-	*
-	* @param array $attrs attributes that must include name and type
-	* @see xmlschema
-	* @access public
-	*/
-	function addElement($attrs) {
-		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
-		$this->schemas[$typens][0]->addElement($attrs);
-	}
-
-	/**
-	* register an operation with the server
-	* 
-	* @param string $name operation (method) name
-	* @param array $in assoc array of input values: key = param name, value = param type
-	* @param array $out assoc array of output values: key = param name, value = param type
-	* @param string $namespace optional The namespace for the operation
-	* @param string $soapaction optional The soapaction for the operation
-	* @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically
-	* @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now)
-	* @param string $documentation optional The description to include in the WSDL
-	* @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
-	* @access public 
-	*/
-	function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
-		if ($use == 'encoded' && $encodingStyle == '') {
-			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-		}
-
-		if ($style == 'document') {
-			$elements = array();
-			foreach ($in as $n => $t) {
-				$elements[$n] = array('name' => $n, 'type' => $t);
-			}
-			$this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
-			$this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
-			$in = array('parameters' => 'tns:' . $name);
-
-			$elements = array();
-			foreach ($out as $n => $t) {
-				$elements[$n] = array('name' => $n, 'type' => $t);
-			}
-			$this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
-			$this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType'));
-			$out = array('parameters' => 'tns:' . $name . 'Response');
-		}
-
-		// get binding
-		$this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
-		array(
-		'name' => $name,
-		'binding' => $this->serviceName . 'Binding',
-		'endpoint' => $this->endpoint,
-		'soapAction' => $soapaction,
-		'style' => $style,
-		'input' => array(
-			'use' => $use,
-			'namespace' => $namespace,
-			'encodingStyle' => $encodingStyle,
-			'message' => $name . 'Request',
-			'parts' => $in),
-		'output' => array(
-			'use' => $use,
-			'namespace' => $namespace,
-			'encodingStyle' => $encodingStyle,
-			'message' => $name . 'Response',
-			'parts' => $out),
-		'namespace' => $namespace,
-		'transport' => 'http://schemas.xmlsoap.org/soap/http',
-		'documentation' => $documentation); 
-		// add portTypes
-		// add messages
-		if($in)
-		{
-			foreach($in as $pName => $pType)
-			{
-				if(strpos($pType,':')) {
-					$pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
-				}
-				$this->messages[$name.'Request'][$pName] = $pType;
-			}
-		} else {
-            $this->messages[$name.'Request']= '0';
-        }
-		if($out)
-		{
-			foreach($out as $pName => $pType)
-			{
-				if(strpos($pType,':')) {
-					$pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
-				}
-				$this->messages[$name.'Response'][$pName] = $pType;
-			}
-		} else {
-            $this->messages[$name.'Response']= '0';
-        }
-		return true;
-	} 
-}
-?><?php
-
-
-
-/**
-*
-* soap_parser class parses SOAP XML messages into native PHP values
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class soap_parser extends nusoap_base {
-
-	var $xml = '';
-	var $xml_encoding = '';
-	var $method = '';
-	var $root_struct = '';
-	var $root_struct_name = '';
-	var $root_struct_namespace = '';
-	var $root_header = '';
-    var $document = '';			// incoming SOAP body (text)
-	// determines where in the message we are (envelope,header,body,method)
-	var $status = '';
-	var $position = 0;
-	var $depth = 0;
-	var $default_namespace = '';
-	var $namespaces = array();
-	var $message = array();
-    var $parent = '';
-	var $fault = false;
-	var $fault_code = '';
-	var $fault_str = '';
-	var $fault_detail = '';
-	var $depth_array = array();
-	var $debug_flag = true;
-	var $soapresponse = NULL;
-	var $responseHeaders = '';	// incoming SOAP headers (text)
-	var $body_position = 0;
-	// for multiref parsing:
-	// array of id => pos
-	var $ids = array();
-	// array of id => hrefs => pos
-	var $multirefs = array();
-	// toggle for auto-decoding element content
-	var $decode_utf8 = true;
-
-	/**
-	* constructor that actually does the parsing
-	*
-	* @param    string $xml SOAP message
-	* @param    string $encoding character encoding scheme of message
-	* @param    string $method method for which XML is parsed (unused?)
-	* @param    string $decode_utf8 whether to decode UTF-8 to ISO-8859-1
-	* @access   public
-	*/
-	function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
-		parent::nusoap_base();
-		$this->xml = $xml;
-		$this->xml_encoding = $encoding;
-		$this->method = $method;
-		$this->decode_utf8 = $decode_utf8;
-
-		// Check whether content has been read.
-		if(!empty($xml)){
-			// Check XML encoding
-			$pos_xml = strpos($xml, '<?xml');
-			if ($pos_xml !== FALSE) {
-				$xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
-				if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
-					$xml_encoding = $res[1];
-					if (strtoupper($xml_encoding) != $encoding) {
-						$err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
-						$this->debug($err);
-						if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
-							$this->setError($err);
-							return;
-						}
-						// when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
-					} else {
-						$this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
-					}
-				} else {
-					$this->debug('No encoding specified in XML declaration');
-				}
-			} else {
-				$this->debug('No XML declaration');
-			}
-			$this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding);
-			// Create an XML parser - why not xml_parser_create_ns?
-			$this->parser = xml_parser_create($this->xml_encoding);
-			// Set the options for parsing the XML data.
-			//xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
-			xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
-			xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
-			// Set the object for the parser.
-			xml_set_object($this->parser, $this);
-			// Set the element handlers for the parser.
-			xml_set_element_handler($this->parser, 'start_element','end_element');
-			xml_set_character_data_handler($this->parser,'character_data');
-
-			// Parse the XML file.
-			if(!xml_parse($this->parser,$xml,true)){
-			    // Display an error message.
-			    $err = sprintf('XML error parsing SOAP payload on line %d: %s',
-			    xml_get_current_line_number($this->parser),
-			    xml_error_string(xml_get_error_code($this->parser)));
-				$this->debug($err);
-				$this->debug("XML payload:\n" . $xml);
-				$this->setError($err);
-			} else {
-				$this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
-				// get final value
-				$this->soapresponse = $this->message[$this->root_struct]['result'];
-				// get header value: no, because this is documented as XML string
-//				if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
-//					$this->responseHeaders = $this->message[$this->root_header]['result'];
-//				}
-				// resolve hrefs/ids
-				if(sizeof($this->multirefs) > 0){
-					foreach($this->multirefs as $id => $hrefs){
-						$this->debug('resolving multirefs for id: '.$id);
-						$idVal = $this->buildVal($this->ids[$id]);
-						if (is_array($idVal) && isset($idVal['!id'])) {
-							unset($idVal['!id']);
-						}
-						foreach($hrefs as $refPos => $ref){
-							$this->debug('resolving href at pos '.$refPos);
-							$this->multirefs[$id][$refPos] = $idVal;
-						}
-					}
-				}
-			}
-			xml_parser_free($this->parser);
-		} else {
-			$this->debug('xml was empty, didn\'t parse!');
-			$this->setError('xml was empty, didn\'t parse!');
-		}
-	}
-
-	/**
-	* start-element handler
-	*
-	* @param    resource $parser XML parser object
-	* @param    string $name element name
-	* @param    array $attrs associative array of attributes
-	* @access   private
-	*/
-	function start_element($parser, $name, $attrs) {
-		// position in a total number of elements, starting from 0
-		// update class level pos
-		$pos = $this->position++;
-		// and set mine
-		$this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
-		// depth = how many levels removed from root?
-		// set mine as current global depth and increment global depth value
-		$this->message[$pos]['depth'] = $this->depth++;
-
-		// else add self as child to whoever the current parent is
-		if($pos != 0){
-			$this->message[$this->parent]['children'] .= '|'.$pos;
-		}
-		// set my parent
-		$this->message[$pos]['parent'] = $this->parent;
-		// set self as current parent
-		$this->parent = $pos;
-		// set self as current value for this depth
-		$this->depth_array[$this->depth] = $pos;
-		// get element prefix
-		if(strpos($name,':')){
-			// get ns prefix
-			$prefix = substr($name,0,strpos($name,':'));
-			// get unqualified name
-			$name = substr(strstr($name,':'),1);
-		}
-		// set status
-		if($name == 'Envelope'){
-			$this->status = 'envelope';
-		} elseif($name == 'Header'){
-			$this->root_header = $pos;
-			$this->status = 'header';
-		} elseif($name == 'Body'){
-			$this->status = 'body';
-			$this->body_position = $pos;
-		// set method
-		} elseif($this->status == 'body' && $pos == ($this->body_position+1)){
-			$this->status = 'method';
-			$this->root_struct_name = $name;
-			$this->root_struct = $pos;
-			$this->message[$pos]['type'] = 'struct';
-			$this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
-		}
-		// set my status
-		$this->message[$pos]['status'] = $this->status;
-		// set name
-		$this->message[$pos]['name'] = htmlspecialchars($name);
-		// set attrs
-		$this->message[$pos]['attrs'] = $attrs;
-
-		// loop through atts, logging ns and type declarations
-        $attstr = '';
-		foreach($attrs as $key => $value){
-        	$key_prefix = $this->getPrefix($key);
-			$key_localpart = $this->getLocalPart($key);
-			// if ns declarations, add to class level array of valid namespaces
-            if($key_prefix == 'xmlns'){
-				if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){
-					$this->XMLSchemaVersion = $value;
-					$this->namespaces['xsd'] = $this->XMLSchemaVersion;
-					$this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
-				}
-                $this->namespaces[$key_localpart] = $value;
-				// set method namespace
-				if($name == $this->root_struct_name){
-					$this->methodNamespace = $value;
-				}
-			// if it's a type declaration, set type
-            } elseif($key_localpart == 'type'){
-            	$value_prefix = $this->getPrefix($value);
-                $value_localpart = $this->getLocalPart($value);
-				$this->message[$pos]['type'] = $value_localpart;
-				$this->message[$pos]['typePrefix'] = $value_prefix;
-                if(isset($this->namespaces[$value_prefix])){
-                	$this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
-                } else if(isset($attrs['xmlns:'.$value_prefix])) {
-					$this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
-                }
-				// should do something here with the namespace of specified type?
-			} elseif($key_localpart == 'arrayType'){
-				$this->message[$pos]['type'] = 'array';
-				/* do arrayType ereg here
-				[1]    arrayTypeValue    ::=    atype asize
-				[2]    atype    ::=    QName rank*
-				[3]    rank    ::=    '[' (',')* ']'
-				[4]    asize    ::=    '[' length~ ']'
-				[5]    length    ::=    nextDimension* Digit+
-				[6]    nextDimension    ::=    Digit+ ','
-				*/
-				$expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]';
-				if(ereg($expr,$value,$regs)){
-					$this->message[$pos]['typePrefix'] = $regs[1];
-					$this->message[$pos]['arrayTypePrefix'] = $regs[1];
-	                if (isset($this->namespaces[$regs[1]])) {
-	                	$this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
-	                } else if (isset($attrs['xmlns:'.$regs[1]])) {
-						$this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
-	                }
-					$this->message[$pos]['arrayType'] = $regs[2];
-					$this->message[$pos]['arraySize'] = $regs[3];
-					$this->message[$pos]['arrayCols'] = $regs[4];
-				}
-			// specifies nil value (or not)
-			} elseif ($key_localpart == 'nil'){
-				$this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
-			// some other attribute
-			} elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
-				$this->message[$pos]['xattrs']['!' . $key] = $value;
-			}
-
-			if ($key == 'xmlns') {
-				$this->default_namespace = $value;
-			}
-			// log id
-			if($key == 'id'){
-				$this->ids[$value] = $pos;
-			}
-			// root
-			if($key_localpart == 'root' && $value == 1){
-				$this->status = 'method';
-				$this->root_struct_name = $name;
-				$this->root_struct = $pos;
-				$this->debug("found root struct $this->root_struct_name, pos $pos");
-			}
-            // for doclit
-            $attstr .= " $key=\"$value\"";
-		}
-        // get namespace - must be done after namespace atts are processed
-		if(isset($prefix)){
-			$this->message[$pos]['namespace'] = $this->namespaces[$prefix];
-			$this->default_namespace = $this->namespaces[$prefix];
-		} else {
-			$this->message[$pos]['namespace'] = $this->default_namespace;
-		}
-        if($this->status == 'header'){
-        	if ($this->root_header != $pos) {
-	        	$this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
-	        }
-        } elseif($this->root_struct_name != ''){
-        	$this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
-        }
-	}
-
-	/**
-	* end-element handler
-	*
-	* @param    resource $parser XML parser object
-	* @param    string $name element name
-	* @access   private
-	*/
-	function end_element($parser, $name) {
-		// position of current element is equal to the last value left in depth_array for my depth
-		$pos = $this->depth_array[$this->depth--];
-
-        // get element prefix
-		if(strpos($name,':')){
-			// get ns prefix
-			$prefix = substr($name,0,strpos($name,':'));
-			// get unqualified name
-			$name = substr(strstr($name,':'),1);
-		}
-		
-		// build to native type
-		if(isset($this->body_position) && $pos > $this->body_position){
-			// deal w/ multirefs
-			if(isset($this->message[$pos]['attrs']['href'])){
-				// get id
-				$id = substr($this->message[$pos]['attrs']['href'],1);
-				// add placeholder to href array
-				$this->multirefs[$id][$pos] = 'placeholder';
-				// add set a reference to it as the result value
-				$this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
-            // build complexType values
-			} elseif($this->message[$pos]['children'] != ''){
-				// if result has already been generated (struct/array)
-				if(!isset($this->message[$pos]['result'])){
-					$this->message[$pos]['result'] = $this->buildVal($pos);
-				}
-			// build complexType values of attributes and possibly simpleContent
-			} elseif (isset($this->message[$pos]['xattrs'])) {
-				if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
-					$this->message[$pos]['xattrs']['!'] = null;
-				} elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
-	            	if (isset($this->message[$pos]['type'])) {
-						$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
-					} else {
-						$parent = $this->message[$pos]['parent'];
-						if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
-							$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
-						} else {
-							$this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
-						}
-					}
-				}
-				$this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
-			// set value of simpleType (or nil complexType)
-			} else {
-            	//$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
-				if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
-					$this->message[$pos]['xattrs']['!'] = null;
-				} elseif (isset($this->message[$pos]['type'])) {
-					$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
-				} else {
-					$parent = $this->message[$pos]['parent'];
-					if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
-						$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
-					} else {
-						$this->message[$pos]['result'] = $this->message[$pos]['cdata'];
-					}
-				}
-
-				/* add value to parent's result, if parent is struct/array
-				$parent = $this->message[$pos]['parent'];
-				if($this->message[$parent]['type'] != 'map'){
-					if(strtolower($this->message[$parent]['type']) == 'array'){
-						$this->message[$parent]['result'][] = $this->message[$pos]['result'];
-					} else {
-						$this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
-					}
-				}
-				*/
-			}
-		}
-		
-        // for doclit
-        if($this->status == 'header'){
-        	if ($this->root_header != $pos) {
-	        	$this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
-	        }
-        } elseif($pos >= $this->root_struct){
-        	$this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
-        }
-		// switch status
-		if($pos == $this->root_struct){
-			$this->status = 'body';
-			$this->root_struct_namespace = $this->message[$pos]['namespace'];
-		} elseif($name == 'Body'){
-			$this->status = 'envelope';
-		 } elseif($name == 'Header'){
-			$this->status = 'envelope';
-		} elseif($name == 'Envelope'){
-			//
-		}
-		// set parent back to my parent
-		$this->parent = $this->message[$pos]['parent'];
-	}
-
-	/**
-	* element content handler
-	*
-	* @param    resource $parser XML parser object
-	* @param    string $data element content
-	* @access   private
-	*/
-	function character_data($parser, $data){
-		$pos = $this->depth_array[$this->depth];
-		if ($this->xml_encoding=='UTF-8'){
-			// TODO: add an option to disable this for folks who want
-			// raw UTF-8 that, e.g., might not map to iso-8859-1
-			// TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
-			if($this->decode_utf8){
-				$data = utf8_decode($data);
-			}
-		}
-        $this->message[$pos]['cdata'] .= $data;
-        // for doclit
-        if($this->status == 'header'){
-        	$this->responseHeaders .= $data;
-        } else {
-        	$this->document .= $data;
-        }
-	}
-
-	/**
-	* get the parsed message
-	*
-	* @return	mixed
-	* @access   public
-	*/
-	function get_response(){
-		return $this->soapresponse;
-	}
-
-	/**
-	* get the parsed headers
-	*
-	* @return	string XML or empty if no headers
-	* @access   public
-	*/
-	function getHeaders(){
-	    return $this->responseHeaders;
-	}
-
-	/**
-	* decodes simple types into PHP variables
-	*
-	* @param    string $value value to decode
-	* @param    string $type XML type to decode
-	* @param    string $typens XML type namespace to decode
-	* @return	mixed PHP value
-	* @access   private
-	*/
-	function decodeSimple($value, $type, $typens) {
-		// TODO: use the namespace!
-		if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
-			return (string) $value;
-		}
-		if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
-			return (int) $value;
-		}
-		if ($type == 'float' || $type == 'double' || $type == 'decimal') {
-			return (double) $value;
-		}
-		if ($type == 'boolean') {
-			if (strtolower($value) == 'false' || strtolower($value) == 'f') {
-				return false;
-			}
-			return (boolean) $value;
-		}
-		if ($type == 'base64' || $type == 'base64Binary') {
-			$this->debug('Decode base64 value');
-			return base64_decode($value);
-		}
-		// obscure numeric types
-		if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
-			|| $type == 'nonNegativeInteger' || $type == 'positiveInteger'
-			|| $type == 'unsignedInt'
-			|| $type == 'unsignedShort' || $type == 'unsignedByte') {
-			return (int) $value;
-		}
-		// bogus: parser treats array with no elements as a simple type
-		if ($type == 'array') {
-			return array();
-		}
-		// everything else
-		return (string) $value;
-	}
-
-	/**
-	* builds response structures for compound values (arrays/structs)
-	* and scalars
-	*
-	* @param    integer $pos position in node tree
-	* @return	mixed	PHP value
-	* @access   private
-	*/
-	function buildVal($pos){
-		if(!isset($this->message[$pos]['type'])){
-			$this->message[$pos]['type'] = '';
-		}
-		$this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
-		// if there are children...
-		if($this->message[$pos]['children'] != ''){
-			$this->debug('in buildVal, there are children');
-			$children = explode('|',$this->message[$pos]['children']);
-			array_shift($children); // knock off empty
-			// md array
-			if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
-            	$r=0; // rowcount
-            	$c=0; // colcount
-            	foreach($children as $child_pos){
-					$this->debug("in buildVal, got an MD array element: $r, $c");
-					$params[$r][] = $this->message[$child_pos]['result'];
-				    $c++;
-				    if($c == $this->message[$pos]['arrayCols']){
-				    	$c = 0;
-						$r++;
-				    }
-                }
-            // array
-			} elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
-                $this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
-                foreach($children as $child_pos){
-                	$params[] = &$this->message[$child_pos]['result'];
-                }
-            // apache Map type: java hashtable
-            } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
-                $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
-                foreach($children as $child_pos){
-                	$kv = explode("|",$this->message[$child_pos]['children']);
-                   	$params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
-                }
-            // generic compound type
-            //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
-		    } else {
-	    		// Apache Vector type: treat as an array
-                $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']);
-				if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
-					$notstruct = 1;
-				} else {
-					$notstruct = 0;
-	            }
-            	//
-            	foreach($children as $child_pos){
-            		if($notstruct){
-            			$params[] = &$this->message[$child_pos]['result'];
-            		} else {
-            			if (isset($params[$this->message[$child_pos]['name']])) {
-            				// de-serialize repeated element name into an array
-            				if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
-            					$params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
-            				}
-            				$params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
-            			} else {
-					    	$params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
-					    }
-                	}
-                }
-			}
-			if (isset($this->message[$pos]['xattrs'])) {
-                $this->debug('in buildVal, handling attributes');
-				foreach ($this->message[$pos]['xattrs'] as $n => $v) {
-					$params[$n] = $v;
-				}
-			}
-			// handle simpleContent
-			if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
-                $this->debug('in buildVal, handling simpleContent');
-            	if (isset($this->message[$pos]['type'])) {
-					$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
-				} else {
-					$parent = $this->message[$pos]['parent'];
-					if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
-						$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
-					} else {
-						$params['!'] = $this->message[$pos]['cdata'];
-					}
-				}
-			}
-			return is_array($params) ? $params : array();
-		} else {
-        	$this->debug('in buildVal, no children, building scalar');
-			$cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
-        	if (isset($this->message[$pos]['type'])) {
-				return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
-			}
-			$parent = $this->message[$pos]['parent'];
-			if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
-				return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
-			}
-           	return $this->message[$pos]['cdata'];
-		}
-	}
-}
-
-
-
-?><?php
-
-
-
-/**
-*
-* soapclient_nusoap higher level class for easy usage.
-*
-* usage:
-*
-* // instantiate client with server info
-* $soapclient = new soapclient_nusoap( string path [ ,boolean wsdl] );
-*
-* // call method, get results
-* echo $soapclient->call( string methodname [ ,array parameters] );
-*
-* // bye bye client
-* unset($soapclient);
-*
-* @author   Dietrich Ayala <dietrich@ganx4.com>
-* @version  $Id$
-* @access   public
-*/
-class soapclient_nusoap extends nusoap_base  {
-
-	var $username = '';
-	var $password = '';
-	var $authtype = '';
-	var $certRequest = array();
-	var $requestHeaders = false;	// SOAP headers in request (text)
-	var $responseHeaders = '';		// SOAP headers from response (incomplete namespace resolution) (text)
-	var $document = '';				// SOAP body response portion (incomplete namespace resolution) (text)
-	var $endpoint;
-	var $forceEndpoint = '';		// overrides WSDL endpoint
-    var $proxyhost = '';
-    var $proxyport = '';
-	var $proxyusername = '';
-	var $proxypassword = '';
-    var $xml_encoding = '';			// character set encoding of incoming (response) messages
-	var $http_encoding = false;
-	var $timeout = 0;				// HTTP connection timeout
-	var $response_timeout = 30;		// HTTP response timeout
-	var $endpointType = '';			// soap|wsdl, empty for WSDL initialization error
-	var $persistentConnection = false;
-	var $defaultRpcParams = false;	// This is no longer used
-	var $request = '';				// HTTP request
-	var $response = '';				// HTTP response
-	var $responseData = '';			// SOAP payload of response
-	var $cookies = array();			// Cookies from response or for request
-    var $decode_utf8 = true;		// toggles whether the parser decodes element content w/ utf8_decode()
-	var $operations = array();		// WSDL operations, empty for WSDL initialization error
-	
-	/*
-	 * fault related variables
-	 */
-	/**
-	 * @var      fault
-	 * @access   public
-	 */
-	var $fault;
-	/**
-	 * @var      faultcode
-	 * @access   public
-	 */
-	var $faultcode;
-	/**
-	 * @var      faultstring
-	 * @access   public
-	 */
-	var $faultstring;
-	/**
-	 * @var      faultdetail
-	 * @access   public
-	 */
-	var $faultdetail;
-
-	/**
-	* constructor
-	*
-	* @param    mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object)
-	* @param    bool $wsdl optional, set to true if using WSDL
-	* @param	int $portName optional portName in WSDL document
-	* @param    string $proxyhost
-	* @param    string $proxyport
-	* @param	string $proxyusername
-	* @param	string $proxypassword
-	* @param	integer $timeout set the connection timeout
-	* @param	integer $response_timeout set the response timeout
-	* @access   public
-	*/
-	function soapclient_nusoap($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
-		parent::nusoap_base();
-		$this->endpoint = $endpoint;
-		$this->proxyhost = $proxyhost;
-		$this->proxyport = $proxyport;
-		$this->proxyusername = $proxyusername;
-		$this->proxypassword = $proxypassword;
-		$this->timeout = $timeout;
-		$this->response_timeout = $response_timeout;
-
-		// make values
-		if($wsdl){
-			if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
-				$this->wsdl = $endpoint;
-				$this->endpoint = $this->wsdl->wsdl;
-				$this->wsdlFile = $this->endpoint;
-				$this->debug('existing wsdl instance created from ' . $this->endpoint);
-			} else {
-				$this->wsdlFile = $this->endpoint;
-				
-				// instantiate wsdl object and parse wsdl file
-				$this->debug('instantiating wsdl class with doc: '.$endpoint);
-				$this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout);
-			}
-			$this->appendDebug($this->wsdl->getDebug());
-			$this->wsdl->clearDebug();
-			// catch errors
-			if($errstr = $this->wsdl->getError()){
-				$this->debug('got wsdl error: '.$errstr);
-				$this->setError('wsdl error: '.$errstr);
-			} elseif($this->operations = $this->wsdl->getOperations()){
-				$this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile);
-				$this->endpointType = 'wsdl';
-			} else {
-				$this->debug( 'getOperations returned false');
-				$this->setError('no operations defined in the WSDL document!');
-			}
-		} else {
-			$this->debug("instantiate SOAP with endpoint at $endpoint");
-			$this->endpointType = 'soap';
-		}
-	}
-
-	/**
-	* calls method, returns PHP native type
-	*
-	* @param    string $method SOAP server URL or path
-	* @param    mixed $params An array, associative or simple, of the parameters
-	*			              for the method call, or a string that is the XML
-	*			              for the call.  For rpc style, this call will
-	*			              wrap the XML in a tag named after the method, as
-	*			              well as the SOAP Envelope and Body.  For document
-	*			              style, this will only wrap with the Envelope and Body.
-	*			              IMPORTANT: when using an array with document style,
-	*			              in which case there
-	*                         is really one parameter, the root of the fragment
-	*                         used in the call, which encloses what programmers
-	*                         normally think of parameters.  A parameter array
-	*                         *must* include the wrapper.
-	* @param	string $namespace optional method namespace (WSDL can override)
-	* @param	string $soapAction optional SOAPAction value (WSDL can override)
-	* @param	mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
-	* @param	boolean $rpcParams optional (no longer used)
-	* @param	string	$style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
-	* @param	string	$use optional (encoded|literal) the use when serializing parameters (WSDL can override)
-	* @return	mixed	response from SOAP call
-	* @access   public
-	*/
-	function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
-		$this->operation = $operation;
-		$this->fault = false;
-		$this->setError('');
-		$this->request = '';
-		$this->response = '';
-		$this->responseData = '';
-		$this->faultstring = '';
-		$this->faultcode = '';
-		$this->opData = array();
-		
-		$this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
-		$this->appendDebug('params=' . $this->varDump($params));
-		$this->appendDebug('headers=' . $this->varDump($headers));
-		if ($headers) {
-			$this->requestHeaders = $headers;
-		}
-		// serialize parameters
-		if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
-			// use WSDL for operation
-			$this->opData = $opData;
-			$this->debug("found operation");
-			$this->appendDebug('opData=' . $this->varDump($opData));
-			if (isset($opData['soapAction'])) {
-				$soapAction = $opData['soapAction'];
-			}
-			if (! $this->forceEndpoint) {
-				$this->endpoint = $opData['endpoint'];
-			} else {
-				$this->endpoint = $this->forceEndpoint;
-			}
-			$namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] :	$namespace;
-			$style = $opData['style'];
-			$use = $opData['input']['use'];
-			// add ns to ns array
-			if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
-				$nsPrefix = 'ns' . rand(1000, 9999);
-				$this->wsdl->namespaces[$nsPrefix] = $namespace;
-			}
-            $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
-			// serialize payload
-			if (is_string($params)) {
-				$this->debug("serializing param string for WSDL operation $operation");
-				$payload = $params;
-			} elseif (is_array($params)) {
-				$this->debug("serializing param array for WSDL operation $operation");
-				$payload = $this->wsdl->serializeRPCParameters($operation,'input',$params);
-			} else {
-				$this->debug('params must be array or string');
-				$this->setError('params must be array or string');
-				return false;
-			}
-            $usedNamespaces = $this->wsdl->usedNamespaces;
-			if (isset($opData['input']['encodingStyle'])) {
-				$encodingStyle = $opData['input']['encodingStyle'];
-			} else {
-				$encodingStyle = '';
-			}
-			$this->appendDebug($this->wsdl->getDebug());
-			$this->wsdl->clearDebug();
-			if ($errstr = $this->wsdl->getError()) {
-				$this->debug('got wsdl error: '.$errstr);
-				$this->setError('wsdl error: '.$errstr);
-				return false;
-			}
-		} elseif($this->endpointType == 'wsdl') {
-			// operation not in WSDL
-			$this->appendDebug($this->wsdl->getDebug());
-			$this->wsdl->clearDebug();
-			$this->setError( 'operation '.$operation.' not present.');
-			$this->debug("operation '$operation' not present.");
-			return false;
-		} else {
-			// no WSDL
-			//$this->namespaces['ns1'] = $namespace;
-			$nsPrefix = 'ns' . rand(1000, 9999);
-			// serialize 
-			$payload = '';
-			if (is_string($params)) {
-				$this->debug("serializing param string for operation $operation");
-				$payload = $params;
-			} elseif (is_array($params)) {
-				$this->debug("serializing param array for operation $operation");
-				foreach($params as $k => $v){
-					$payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
-				}
-			} else {
-				$this->debug('params must be array or string');
-				$this->setError('params must be array or string');
-				return false;
-			}
-			$usedNamespaces = array();
-			if ($use == 'encoded') {
-				$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
-			} else {
-				$encodingStyle = '';
-			}
-		}
-		// wrap RPC calls with method element
-		if ($style == 'rpc') {
-			if ($use == 'literal') {
-				$this->debug("wrapping RPC request with literal method element");
-				if ($namespace) {
-					$payload = "<$operation xmlns=\"$namespace\">" . $payload . "</$operation>";
-				} else {
-					$payload = "<$operation>" . $payload . "</$operation>";
-				}
-			} else {
-				$this->debug("wrapping RPC request with encoded method element");
-				if ($namespace) {
-					$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
-								$payload .
-								"</$nsPrefix:$operation>";
-				} else {
-					$payload = "<$operation>" .
-								$payload .
-								"</$operation>";
-				}
-			}
-		}
-		// serialize envelope
-		$soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
-		$this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
-		$this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
-		// send
-		$return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
-		if($errstr = $this->getError()){
-			$this->debug('Error: '.$errstr);
-			return false;
-		} else {
-			$this->return = $return;
-			$this->debug('sent message successfully and got a(n) '.gettype($return));
-           	$this->appendDebug('return=' . $this->varDump($return));
-			
-			// fault?
-			if(is_array($return) && isset($return['faultcode'])){
-				$this->debug('got fault');
-				$this->setError($return['faultcode'].': '.$return['faultstring']);
-				$this->fault = true;
-				foreach($return as $k => $v){
-					$this->$k = $v;
-					$this->debug("$k = $v<br>");
-				}
-				return $return;
-			} elseif ($style == 'document') {
-				// NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
-				// we are only going to return the first part here...sorry about that
-				return $return;
-			} else {
-				// array of return values
-				if(is_array($return)){
-					// multiple 'out' parameters, which we return wrapped up
-					// in the array
-					if(sizeof($return) > 1){
-						return $return;
-					}
-					// single 'out' parameter (normally the return value)
-					$return = array_shift($return);
-					$this->debug('return shifted value: ');
-					$this->appendDebug($this->varDump($return));
-           			return $return;
-				// nothing returned (ie, echoVoid)
-				} else {
-					return "";
-				}
-			}
-		}
-	}
-
-	/**
-	* get available data pertaining to an operation
-	*
-	* @param    string $operation operation name
-	* @return	array array of data pertaining to the operation
-	* @access   public
-	*/
-	function getOperationData($operation){
-		if(isset($this->operations[$operation])){
-			return $this->operations[$operation];
-		}
-		$this->debug("No data for operation: $operation");
-	}
-
-    /**
-    * send the SOAP message
-    *
-    * Note: if the operation has multiple return values
-    * the return value of this method will be an array
-    * of those values.
-    *
-	* @param    string $msg a SOAPx4 soapmsg object
-	* @param    string $soapaction SOAPAction value
-	* @param    integer $timeout set connection timeout in seconds
-	* @param	integer $response_timeout set response timeout in seconds
-	* @return	mixed native PHP types.
-	* @access   private
-	*/
-	function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
-		$this->checkCookies();
-		// detect transport
-		switch(true){
-			// http(s)
-			case ereg('^http',$this->endpoint):
-				$this->debug('transporting via HTTP');
-				if($this->persistentConnection == true && is_object($this->persistentConnection)){
-					$http =& $this->persistentConnection;
-				} else {
-					$http = new soap_transport_http($this->endpoint);
-					if ($this->persistentConnection) {
-						$http->usePersistentConnection();
-					}
-				}
-				$http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
-				$http->setSOAPAction($soapaction);
-				if($this->proxyhost && $this->proxyport){
-					$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
-				}
-                if($this->authtype != '') {
-					$http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
-				}
-				if($this->http_encoding != ''){
-					$http->setEncoding($this->http_encoding);
-				}
-				$this->debug('sending message, length='.strlen($msg));
-				if(ereg('^http:',$this->endpoint)){
-				//if(strpos($this->endpoint,'http:')){
-					$this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
-				} elseif(ereg('^https',$this->endpoint)){
-				//} elseif(strpos($this->endpoint,'https:')){
-					//if(phpversion() == '4.3.0-dev'){
-						//$response = $http->send($msg,$timeout,$response_timeout);
-                   		//$this->request = $http->outgoing_payload;
-						//$this->response = $http->incoming_payload;
-					//} else
-					$this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
-				} else {
-					$this->setError('no http/s in endpoint url');
-				}
-				$this->request = $http->outgoing_payload;
-				$this->response = $http->incoming_payload;
-				$this->appendDebug($http->getDebug());
-				$this->UpdateCookies($http->incoming_cookies);
-
-				// save transport object if using persistent connections
-				if ($this->persistentConnection) {
-					$http->clearDebug();
-					if (!is_object($this->persistentConnection)) {
-						$this->persistentConnection = $http;
-					}
-				}
-				
-				if($err = $http->getError()){
-					$this->setError('HTTP Error: '.$err);
-					return false;
-				} elseif($this->getError()){
-					return false;
-				} else {
-					$this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
-					return $this->parseResponse($http->incoming_headers, $this->responseData);
-				}
-			break;
-			default:
-				$this->setError('no transport found, or selected transport is not yet supported!');
-			return false;
-			break;
-		}
-	}
-
-	/**
-	* processes SOAP message returned from server
-	*
-	* @param	array	$headers	The HTTP headers
-	* @param	string	$data		unprocessed response data from server
-	* @return	mixed	value of the message, decoded into a PHP type
-	* @access   private
-	*/
-    function parseResponse($headers, $data) {
-		$this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
-		if (!strstr($headers['content-type'], 'text/xml')) {
-			$this->setError('Response not of type text/xml');
-			return false;
-		}
-		if (strpos($headers['content-type'], '=')) {
-			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
-			$this->debug('Got response encoding: ' . $enc);
-			if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
-				$this->xml_encoding = strtoupper($enc);
-			} else {
-				$this->xml_encoding = 'US-ASCII';
-			}
-		} else {
-			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
-			$this->xml_encoding = 'ISO-8859-1';
-		}
-		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
-		$parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
-		// add parser debug data to our debug
-		$this->appendDebug($parser->getDebug());
-		// if parse errors
-		if($errstr = $parser->getError()){
-			$this->setError( $errstr);
-			// destroy the parser object
-			unset($parser);
-			return false;
-		} else {
-			// get SOAP headers
-			$this->responseHeaders = $parser->getHeaders();
-			// get decoded message
-			$return = $parser->get_response();
-            // add document for doclit support
-            $this->document = $parser->document;
-			// destroy the parser object
-			unset($parser);
-			// return decode message
-			return $return;
-		}
-	 }
-
-	/**
-	* sets the SOAP endpoint, which can override WSDL
-	*
-	* @param	$endpoint string The endpoint URL to use, or empty string or false to prevent override
-	* @access   public
-	*/
-	function setEndpoint($endpoint) {
-		$this->forceEndpoint = $endpoint;
-	}
-
-	/**
-	* set the SOAP headers
-	*
-	* @param	$headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers
-	* @access   public
-	*/
-	function setHeaders($headers){
-		$this->requestHeaders = $headers;
-	}
-
-	/**
-	* get the SOAP response headers (namespace resolution incomplete)
-	*
-	* @return	string
-	* @access   public
-	*/
-	function getHeaders(){
-		return $this->responseHeaders;
-	}
-
-	/**
-	* set proxy info here
-	*
-	* @param    string $proxyhost
-	* @param    string $proxyport
-	* @param	string $proxyusername
-	* @param	string $proxypassword
-	* @access   public
-	*/
-	function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
-		$this->proxyhost = $proxyhost;
-		$this->proxyport = $proxyport;
-		$this->proxyusername = $proxyusername;
-		$this->proxypassword = $proxypassword;
-	}
-
-	/**
-	* if authenticating, set user credentials here
-	*
-	* @param    string $username
-	* @param    string $password
-	* @param	string $authtype (basic|digest|certificate)
-	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
-	* @access   public
-	*/
-	function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
-		$this->username = $username;
-		$this->password = $password;
-		$this->authtype = $authtype;
-		$this->certRequest = $certRequest;
-	}
-	
-	/**
-	* use HTTP encoding
-	*
-	* @param    string $enc
-	* @access   public
-	*/
-	function setHTTPEncoding($enc='gzip, deflate'){
-		$this->http_encoding = $enc;
-	}
-	
-	/**
-	* use HTTP persistent connections if possible
-	*
-	* @access   public
-	*/
-	function useHTTPPersistentConnection(){
-		$this->persistentConnection = true;
-	}
-	
-	/**
-	* gets the default RPC parameter setting.
-	* If true, default is that call params are like RPC even for document style.
-	* Each call() can override this value.
-	*
-	* This is no longer used.
-	*
-	* @return boolean
-	* @access public
-	* @deprecated
-	*/
-	function getDefaultRpcParams() {
-		return $this->defaultRpcParams;
-	}
-
-	/**
-	* sets the default RPC parameter setting.
-	* If true, default is that call params are like RPC even for document style
-	* Each call() can override this value.
-	*
-	* This is no longer used.
-	*
-	* @param    boolean $rpcParams
-	* @access public
-	* @deprecated
-	*/
-	function setDefaultRpcParams($rpcParams) {
-		$this->defaultRpcParams = $rpcParams;
-	}
-	
-	/**
-	* dynamically creates an instance of a proxy class,
-	* allowing user to directly call methods from wsdl
-	*
-	* @return   object soap_proxy object
-	* @access   public
-	*/
-	function getProxy(){
-		$r = rand();
-		$evalStr = $this->_getProxyClassCode($r);
-		//$this->debug("proxy class: $evalStr";
-		// eval the class
-		eval($evalStr);
-		// instantiate proxy object
-		eval("\$proxy = new soap_proxy_$r('');");
-		// transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
-		$proxy->endpointType = 'wsdl';
-		$proxy->wsdlFile = $this->wsdlFile;
-		$proxy->wsdl = $this->wsdl;
-		$proxy->operations = $this->operations;
-		$proxy->defaultRpcParams = $this->defaultRpcParams;
-		// transfer other state
-		$proxy->username = $this->username;
-		$proxy->password = $this->password;
-		$proxy->authtype = $this->authtype;
-		$proxy->proxyhost = $this->proxyhost;
-		$proxy->proxyport = $this->proxyport;
-		$proxy->proxyusername = $this->proxyusername;
-		$proxy->proxypassword = $this->proxypassword;
-		$proxy->timeout = $this->timeout;
-		$proxy->response_timeout = $this->response_timeout;
-		$proxy->http_encoding = $this->http_encoding;
-		$proxy->persistentConnection = $this->persistentConnection;
-		$proxy->requestHeaders = $this->requestHeaders;
-		$proxy->soap_defencoding = $this->soap_defencoding;
-		$proxy->endpoint = $this->endpoint;
-		$proxy->forceEndpoint = $this->forceEndpoint;
-		return $proxy;
-	}
-
-	/**
-	* dynamically creates proxy class code
-	*
-	* @return   string PHP/NuSOAP code for the proxy class
-	* @access   private
-	*/
-	function _getProxyClassCode($r) {
-		if ($this->endpointType != 'wsdl') {
-			$evalStr = 'A proxy can only be created for a WSDL client';
-			$this->setError($evalStr);
-			return $evalStr;
-		}
-		$evalStr = '';
-		foreach ($this->operations as $operation => $opData) {
-			if ($operation != '') {
-				// create param string and param comment string
-				if (sizeof($opData['input']['parts']) > 0) {
-					$paramStr = '';
-					$paramArrayStr = '';
-					$paramCommentStr = '';
-					foreach ($opData['input']['parts'] as $name => $type) {
-						$paramStr .= "\$$name, ";
-						$paramArrayStr .= "'$name' => \$$name, ";
-						$paramCommentStr .= "$type \$$name, ";
-					}
-					$paramStr = substr($paramStr, 0, strlen($paramStr)-2);
-					$paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
-					$paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
-				} else {
-					$paramStr = '';
-					$paramCommentStr = 'void';
-				}
-				$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
-				$evalStr .= "// $paramCommentStr
-	function " . str_replace('.', '__', $operation) . "($paramStr) {
-		\$params = array($paramArrayStr);
-		return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
-	}
-	";
-				unset($paramStr);
-				unset($paramCommentStr);
-			}
-		}
-		$evalStr = 'class soap_proxy_'.$r.' extends soapclient_nusoap {
-	'.$evalStr.'
-}';
-		return $evalStr;
-	}
-
-	/**
-	* dynamically creates proxy class code
-	*
-	* @return   string PHP/NuSOAP code for the proxy class
-	* @access   public
-	*/
-	function getProxyClassCode() {
-		$r = rand();
-		return $this->_getProxyClassCode($r);
-	}
-
-	/**
-	* gets the HTTP body for the current request.
-	*
-	* @param string $soapmsg The SOAP payload
-	* @return string The HTTP body, which includes the SOAP payload
-	* @access private
-	*/
-	function getHTTPBody($soapmsg) {
-		return $soapmsg;
-	}
-	
-	/**
-	* gets the HTTP content type for the current request.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type for the current request.
-	* @access private
-	*/
-	function getHTTPContentType() {
-		return 'text/xml';
-	}
-	
-	/**
-	* gets the HTTP content type charset for the current request.
-	* returns false for non-text content types.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type charset for the current request.
-	* @access private
-	*/
-	function getHTTPContentTypeCharset() {
-		return $this->soap_defencoding;
-	}
-
-	/*
-	* whether or not parser should decode utf8 element content
-    *
-    * @return   always returns true
-    * @access   public
-    */
-    function decodeUTF8($bool){
-		$this->decode_utf8 = $bool;
-		return true;
-    }
-
-	/**
-	 * adds a new Cookie into $this->cookies array
-	 *
-	 * @param	string $name Cookie Name
-	 * @param	string $value Cookie Value
-	 * @return	if cookie-set was successful returns true, else false
-	 * @access	public
-	 */
-	function setCookie($name, $value) {
-		if (strlen($name) == 0) {
-			return false;
-		}
-		$this->cookies[] = array('name' => $name, 'value' => $value);
-		return true;
-	}
-
-	/**
-	 * gets all Cookies
-	 *
-	 * @return   array with all internal cookies
-	 * @access   public
-	 */
-	function getCookies() {
-		return $this->cookies;
-	}
-
-	/**
-	 * checks all Cookies and delete those which are expired
-	 *
-	 * @return   always return true
-	 * @access   private
-	 */
-	function checkCookies() {
-		if (sizeof($this->cookies) == 0) {
-			return true;
-		}
-		$this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
-		$curr_cookies = $this->cookies;
-		$this->cookies = array();
-		foreach ($curr_cookies as $cookie) {
-			if (! is_array($cookie)) {
-				$this->debug('Remove cookie that is not an array');
-				continue;
-			}
-			if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
-				if (strtotime($cookie['expires']) > time()) {
-					$this->cookies[] = $cookie;
-				} else {
-					$this->debug('Remove expired cookie ' . $cookie['name']);
-				}
-			} else {
-				$this->cookies[] = $cookie;
-			}
-		}
-		$this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
-		return true;
-	}
-
-	/**
-	 * updates the current cookies with a new set
-	 *
-	 * @param	array $cookies new cookies with which to update current ones
-	 * @return	always return true
-	 * @access	private
-	 */
-	function UpdateCookies($cookies) {
-		if (sizeof($this->cookies) == 0) {
-			// no existing cookies: take whatever is new
-			if (sizeof($cookies) > 0) {
-				$this->debug('Setting new cookie(s)');
-				$this->cookies = $cookies;
-			}
-			return true;
-		}
-		if (sizeof($cookies) == 0) {
-			// no new cookies: keep what we've got
-			return true;
-		}
-		// merge
-		foreach ($cookies as $newCookie) {
-			if (!is_array($newCookie)) {
-				continue;
-			}
-			if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
-				continue;
-			}
-			$newName = $newCookie['name'];
-
-			$found = false;
-			for ($i = 0; $i < count($this->cookies); $i++) {
-				$cookie = $this->cookies[$i];
-				if (!is_array($cookie)) {
-					continue;
-				}
-				if (!isset($cookie['name'])) {
-					continue;
-				}
-				if ($newName != $cookie['name']) {
-					continue;
-				}
-				$newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
-				$domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
-				if ($newDomain != $domain) {
-					continue;
-				}
-				$newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
-				$path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
-				if ($newPath != $path) {
-					continue;
-				}
-				$this->cookies[$i] = $newCookie;
-				$found = true;
-				$this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
-				break;
-			}
-			if (! $found) {
-				$this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
-				$this->cookies[] = $newCookie;
-			}
-		}
-		return true;
-	}
-}
-?>
+<?php
+
+/*
+$Id$
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+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
+
+If you have any questions or comments, please email:
+
+Dietrich Ayala
+dietrich@ganx4.com
+http://dietrich.ganx4.com/nusoap
+
+NuSphere Corporation
+http://www.nusphere.com
+
+*/
+
+/* load classes
+
+// necessary classes
+require_once('class.soapclient.php');
+require_once('class.soap_val.php');
+require_once('class.soap_parser.php');
+require_once('class.soap_fault.php');
+
+// transport classes
+require_once('class.soap_transport_http.php');
+
+// optional add-on classes
+require_once('class.xmlschema.php');
+require_once('class.wsdl.php');
+
+// server class
+require_once('class.soap_server.php');*/
+
+// class variable emulation
+// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
+$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
+
+/**
+*
+* nusoap_base
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class nusoap_base {
+	/**
+	 * Identification for HTTP headers.
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $title = 'NuSOAP';
+	/**
+	 * Version for HTTP headers.
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $version = '0.7.2';
+	/**
+	 * CVS revision for HTTP headers.
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $revision = '$Revision$';
+    /**
+     * Current error string (manipulated by getError/setError)
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $error_str = '';
+    /**
+     * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
+	 *
+	 * @var string
+	 * @access private
+	 */
+    var $debug_str = '';
+    /**
+	 * toggles automatic encoding of special characters as entities
+	 * (should always be true, I think)
+	 *
+	 * @var boolean
+	 * @access private
+	 */
+	var $charencoding = true;
+	/**
+	 * the debug level for this instance
+	 *
+	 * @var	integer
+	 * @access private
+	 */
+	var $debugLevel;
+
+    /**
+	* set schema version
+	*
+	* @var      string
+	* @access   public
+	*/
+	var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
+	
+    /**
+	* charset encoding for outgoing messages
+	*
+	* @var      string
+	* @access   public
+	*/
+    var $soap_defencoding = 'ISO-8859-1';
+	//var $soap_defencoding = 'UTF-8';
+
+	/**
+	* namespaces in an array of prefix => uri
+	*
+	* this is "seeded" by a set of constants, but it may be altered by code
+	*
+	* @var      array
+	* @access   public
+	*/
+	var $namespaces = array(
+		'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
+		'xsd' => 'http://www.w3.org/2001/XMLSchema',
+		'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
+		'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
+		);
+
+	/**
+	* namespaces used in the current context, e.g. during serialization
+	*
+	* @var      array
+	* @access   private
+	*/
+	var $usedNamespaces = array();
+
+	/**
+	* XML Schema types in an array of uri => (array of xml type => php type)
+	* is this legacy yet?
+	* no, this is used by the xmlschema class to verify type => namespace mappings.
+	* @var      array
+	* @access   public
+	*/
+	var $typemap = array(
+	'http://www.w3.org/2001/XMLSchema' => array(
+		'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
+		'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
+		'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
+		// abstract "any" types
+		'anyType'=>'string','anySimpleType'=>'string',
+		// derived datatypes
+		'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
+		'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
+		'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
+		'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
+	'http://www.w3.org/2000/10/XMLSchema' => array(
+		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
+		'float'=>'double','dateTime'=>'string',
+		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
+	'http://www.w3.org/1999/XMLSchema' => array(
+		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
+		'float'=>'double','dateTime'=>'string',
+		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
+	'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
+	'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
+    'http://xml.apache.org/xml-soap' => array('Map')
+	);
+
+	/**
+	* XML entities to convert
+	*
+	* @var      array
+	* @access   public
+	* @deprecated
+	* @see	expandEntities
+	*/
+	var $xmlEntities = array('quot' => '"','amp' => '&',
+		'lt' => '<','gt' => '>','apos' => "'");
+
+	/**
+	* constructor
+	*
+	* @access	public
+	*/
+	function nusoap_base() {
+		$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
+	}
+
+	/**
+	* gets the global debug level, which applies to future instances
+	*
+	* @return	integer	Debug level 0-9, where 0 turns off
+	* @access	public
+	*/
+	function getGlobalDebugLevel() {
+		return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
+	}
+
+	/**
+	* sets the global debug level, which applies to future instances
+	*
+	* @param	int	$level	Debug level 0-9, where 0 turns off
+	* @access	public
+	*/
+	function setGlobalDebugLevel($level) {
+		$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
+	}
+
+	/**
+	* gets the debug level for this instance
+	*
+	* @return	int	Debug level 0-9, where 0 turns off
+	* @access	public
+	*/
+	function getDebugLevel() {
+		return $this->debugLevel;
+	}
+
+	/**
+	* sets the debug level for this instance
+	*
+	* @param	int	$level	Debug level 0-9, where 0 turns off
+	* @access	public
+	*/
+	function setDebugLevel($level) {
+		$this->debugLevel = $level;
+	}
+
+	/**
+	* adds debug data to the instance debug string with formatting
+	*
+	* @param    string $string debug data
+	* @access   private
+	*/
+	function debug($string){
+		if ($this->debugLevel > 0) {
+			$this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
+		}
+	}
+
+	/**
+	* adds debug data to the instance debug string without formatting
+	*
+	* @param    string $string debug data
+	* @access   public
+	*/
+	function appendDebug($string){
+		if ($this->debugLevel > 0) {
+			// it would be nice to use a memory stream here to use
+			// memory more efficiently
+			$this->debug_str .= $string;
+		}
+	}
+
+	/**
+	* clears the current debug data for this instance
+	*
+	* @access   public
+	*/
+	function clearDebug() {
+		// it would be nice to use a memory stream here to use
+		// memory more efficiently
+		$this->debug_str = '';
+	}
+
+	/**
+	* gets the current debug data for this instance
+	*
+	* @return   debug data
+	* @access   public
+	*/
+	function &getDebug() {
+		// it would be nice to use a memory stream here to use
+		// memory more efficiently
+		return $this->debug_str;
+	}
+
+	/**
+	* gets the current debug data for this instance as an XML comment
+	* this may change the contents of the debug data
+	*
+	* @return   debug data as an XML comment
+	* @access   public
+	*/
+	function &getDebugAsXMLComment() {
+		// it would be nice to use a memory stream here to use
+		// memory more efficiently
+		while (strpos($this->debug_str, '--')) {
+			$this->debug_str = str_replace('--', '- -', $this->debug_str);
+		}
+    	return "<!--\n" . $this->debug_str . "\n-->";
+	}
+
+	/**
+	* expands entities, e.g. changes '<' to '&lt;'.
+	*
+	* @param	string	$val	The string in which to expand entities.
+	* @access	private
+	*/
+	function expandEntities($val) {
+		if ($this->charencoding) {
+	    	$val = str_replace('&', '&amp;', $val);
+	    	$val = str_replace("'", '&apos;', $val);
+	    	$val = str_replace('"', '&quot;', $val);
+	    	$val = str_replace('<', '&lt;', $val);
+	    	$val = str_replace('>', '&gt;', $val);
+	    }
+	    return $val;
+	}
+
+	/**
+	* returns error string if present
+	*
+	* @return   mixed error string or false
+	* @access   public
+	*/
+	function getError(){
+		if($this->error_str != ''){
+			return $this->error_str;
+		}
+		return false;
+	}
+
+	/**
+	* sets error string
+	*
+	* @return   boolean $string error string
+	* @access   private
+	*/
+	function setError($str){
+		$this->error_str = $str;
+	}
+
+	/**
+	* detect if array is a simple array or a struct (associative array)
+	*
+	* @param	mixed	$val	The PHP array
+	* @return	string	(arraySimple|arrayStruct)
+	* @access	private
+	*/
+	function isArraySimpleOrStruct($val) {
+        $keyList = array_keys($val);
+		foreach ($keyList as $keyListValue) {
+			if (!is_int($keyListValue)) {
+				return 'arrayStruct';
+			}
+		}
+		return 'arraySimple';
+	}
+
+	/**
+	* serializes PHP values in accordance w/ section 5. Type information is
+	* not serialized if $use == 'literal'.
+	*
+	* @param	mixed	$val	The value to serialize
+	* @param	string	$name	The name (local part) of the XML element
+	* @param	string	$type	The XML schema type (local part) for the element
+	* @param	string	$name_ns	The namespace for the name of the XML element
+	* @param	string	$type_ns	The namespace for the type of the element
+	* @param	array	$attributes	The attributes to serialize as name=>value pairs
+	* @param	string	$use	The WSDL "use" (encoded|literal)
+	* @return	string	The serialized element, possibly with child elements
+    * @access	public
+	*/
+	function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){
+		$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use");
+		$this->appendDebug('value=' . $this->varDump($val));
+		$this->appendDebug('attributes=' . $this->varDump($attributes));
+		
+    	if(is_object($val) && get_class($val) == 'soapval'){
+        	return $val->serialize($use);
+        }
+		// force valid name if necessary
+		if (is_numeric($name)) {
+			$name = '__numeric_' . $name;
+		} elseif (! $name) {
+			$name = 'noname';
+		}
+		// if name has ns, add ns prefix to name
+		$xmlns = '';
+        if($name_ns){
+			$prefix = 'nu'.rand(1000,9999);
+			$name = $prefix.':'.$name;
+			$xmlns .= " xmlns:$prefix=\"$name_ns\"";
+		}
+		// if type is prefixed, create type prefix
+		if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
+			// need to fix this. shouldn't default to xsd if no ns specified
+		    // w/o checking against typemap
+			$type_prefix = 'xsd';
+		} elseif($type_ns){
+			$type_prefix = 'ns'.rand(1000,9999);
+			$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
+		}
+		// serialize attributes if present
+		$atts = '';
+		if($attributes){
+			foreach($attributes as $k => $v){
+				$atts .= " $k=\"".$this->expandEntities($v).'"';
+			}
+		}
+		// serialize null value
+		if (is_null($val)) {
+			if ($use == 'literal') {
+				// TODO: depends on minOccurs
+	        	return "<$name$xmlns $atts/>";
+        	} else {
+				if (isset($type) && isset($type_prefix)) {
+					$type_str = " xsi:type=\"$type_prefix:$type\"";
+				} else {
+					$type_str = '';
+				}
+	        	return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>";
+        	}
+		}
+        // serialize if an xsd built-in primitive type
+        if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
+        	if (is_bool($val)) {
+        		if ($type == 'boolean') {
+	        		$val = $val ? 'true' : 'false';
+	        	} elseif (! $val) {
+	        		$val = 0;
+	        	}
+			} else if (is_string($val)) {
+				$val = $this->expandEntities($val);
+			}
+			if ($use == 'literal') {
+	        	return "<$name$xmlns $atts>$val</$name>";
+        	} else {
+	        	return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>";
+        	}
+        }
+		// detect type and serialize
+		$xml = '';
+		switch(true) {
+			case (is_bool($val) || $type == 'boolean'):
+        		if ($type == 'boolean') {
+	        		$val = $val ? 'true' : 'false';
+	        	} elseif (! $val) {
+	        		$val = 0;
+	        	}
+				if ($use == 'literal') {
+					$xml .= "<$name$xmlns $atts>$val</$name>";
+				} else {
+					$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
+				}
+				break;
+			case (is_int($val) || is_long($val) || $type == 'int'):
+				if ($use == 'literal') {
+					$xml .= "<$name$xmlns $atts>$val</$name>";
+				} else {
+					$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
+				}
+				break;
+			case (is_float($val)|| is_double($val) || $type == 'float'):
+				if ($use == 'literal') {
+					$xml .= "<$name$xmlns $atts>$val</$name>";
+				} else {
+					$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
+				}
+				break;
+			case (is_string($val) || $type == 'string'):
+				$val = $this->expandEntities($val);
+				if ($use == 'literal') {
+					$xml .= "<$name$xmlns $atts>$val</$name>";
+				} else {
+					$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
+				}
+				break;
+			case is_object($val):
+				if (! $name) {
+					$name = get_class($val);
+					$this->debug("In serialize_val, used class name $name as element name");
+				} else {
+					$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
+				}
+				foreach(get_object_vars($val) as $k => $v){
+					$pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
+				}
+				$xml .= '<'.$name.'>'.$pXml.'</'.$name.'>';
+				break;
+			break;
+			case (is_array($val) || $type):
+				// detect if struct or array
+				$valueType = $this->isArraySimpleOrStruct($val);
+                if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
+					$i = 0;
+					if(is_array($val) && count($val)> 0){
+						foreach($val as $v){
+	                    	if(is_object($v) && get_class($v) ==  'soapval'){
+								$tt_ns = $v->type_ns;
+								$tt = $v->type;
+							} elseif (is_array($v)) {
+								$tt = $this->isArraySimpleOrStruct($v);
+							} else {
+								$tt = gettype($v);
+	                        }
+							$array_types[$tt] = 1;
+							// TODO: for literal, the name should be $name
+							$xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
+							++$i;
+						}
+						if(count($array_types) > 1){
+							$array_typename = 'xsd:anyType';
+						} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
+							if ($tt == 'integer') {
+								$tt = 'int';
+							}
+							$array_typename = 'xsd:'.$tt;
+						} elseif(isset($tt) && $tt == 'arraySimple'){
+							$array_typename = 'SOAP-ENC:Array';
+						} elseif(isset($tt) && $tt == 'arrayStruct'){
+							$array_typename = 'unnamed_struct_use_soapval';
+						} else {
+							// if type is prefixed, create type prefix
+							if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
+								 $array_typename = 'xsd:' . $tt;
+							} elseif ($tt_ns) {
+								$tt_prefix = 'ns' . rand(1000, 9999);
+								$array_typename = "$tt_prefix:$tt";
+								$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
+							} else {
+								$array_typename = $tt;
+							}
+						}
+						$array_type = $i;
+						if ($use == 'literal') {
+							$type_str = '';
+						} else if (isset($type) && isset($type_prefix)) {
+							$type_str = " xsi:type=\"$type_prefix:$type\"";
+						} else {
+							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
+						}
+					// empty array
+					} else {
+						if ($use == 'literal') {
+							$type_str = '';
+						} else if (isset($type) && isset($type_prefix)) {
+							$type_str = " xsi:type=\"$type_prefix:$type\"";
+						} else {
+							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
+						}
+					}
+					// TODO: for array in literal, there is no wrapper here
+					$xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
+				} else {
+					// got a struct
+					if(isset($type) && isset($type_prefix)){
+						$type_str = " xsi:type=\"$type_prefix:$type\"";
+					} else {
+						$type_str = '';
+					}
+					if ($use == 'literal') {
+						$xml .= "<$name$xmlns $atts>";
+					} else {
+						$xml .= "<$name$xmlns$type_str$atts>";
+					}
+					foreach($val as $k => $v){
+						// Apache Map
+						if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
+							$xml .= '<item>';
+							$xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
+							$xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
+							$xml .= '</item>';
+						} else {
+							$xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
+						}
+					}
+					$xml .= "</$name>";
+				}
+				break;
+			default:
+				$xml .= 'not detected, got '.gettype($val).' for '.$val;
+				break;
+		}
+		return $xml;
+	}
+
+    /**
+    * serializes a message
+    *
+    * @param string $body the XML of the SOAP body
+    * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
+    * @param array $namespaces optional the namespaces used in generating the body and headers
+    * @param string $style optional (rpc|document)
+    * @param string $use optional (encoded|literal)
+    * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
+    * @return string the message
+    * @access public
+    */
+    function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
+    // TODO: add an option to automatically run utf8_encode on $body and $headers
+    // if $this->soap_defencoding is UTF-8.  Not doing this automatically allows
+    // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
+
+	$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
+	$this->debug("headers:");
+	$this->appendDebug($this->varDump($headers));
+	$this->debug("namespaces:");
+	$this->appendDebug($this->varDump($namespaces));
+
+	// serialize namespaces
+    $ns_string = '';
+	foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
+		$ns_string .= " xmlns:$k=\"$v\"";
+	}
+	if($encodingStyle) {
+		$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
+	}
+
+	// serialize headers
+	if($headers){
+		if (is_array($headers)) {
+			$xml = '';
+			foreach ($headers as $header) {
+				$xml .= $this->serialize_val($header, false, false, false, false, false, $use);
+			}
+			$headers = $xml;
+			$this->debug("In serializeEnvelope, serialzied array of headers to $headers");
+		}
+		$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
+	}
+	// serialize envelope
+	return
+	'<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
+	'<SOAP-ENV:Envelope'.$ns_string.">".
+	$headers.
+	"<SOAP-ENV:Body>".
+		$body.
+	"</SOAP-ENV:Body>".
+	"</SOAP-ENV:Envelope>";
+    }
+
+	/**
+	 * formats a string to be inserted into an HTML stream
+	 *
+	 * @param string $str The string to format
+	 * @return string The formatted string
+	 * @access public
+	 * @deprecated
+	 */
+    function formatDump($str){
+		$str = htmlspecialchars($str);
+		return nl2br($str);
+    }
+
+	/**
+	* contracts (changes namespace to prefix) a qualified name
+	*
+	* @param    string $qname qname
+	* @return	string contracted qname
+	* @access   private
+	*/
+	function contractQname($qname){
+		// get element namespace
+		//$this->xdebug("Contract $qname");
+		if (strrpos($qname, ':')) {
+			// get unqualified name
+			$name = substr($qname, strrpos($qname, ':') + 1);
+			// get ns
+			$ns = substr($qname, 0, strrpos($qname, ':'));
+			$p = $this->getPrefixFromNamespace($ns);
+			if ($p) {
+				return $p . ':' . $name;
+			}
+			return $qname;
+		} else {
+			return $qname;
+		}
+	}
+
+	/**
+	* expands (changes prefix to namespace) a qualified name
+	*
+	* @param    string $string qname
+	* @return	string expanded qname
+	* @access   private
+	*/
+	function expandQname($qname){
+		// get element prefix
+		if(strpos($qname,':') && !ereg('^http://',$qname)){
+			// get unqualified name
+			$name = substr(strstr($qname,':'),1);
+			// get ns prefix
+			$prefix = substr($qname,0,strpos($qname,':'));
+			if(isset($this->namespaces[$prefix])){
+				return $this->namespaces[$prefix].':'.$name;
+			} else {
+				return $qname;
+			}
+		} else {
+			return $qname;
+		}
+	}
+
+    /**
+    * returns the local part of a prefixed string
+    * returns the original string, if not prefixed
+    *
+    * @param string $str The prefixed string
+    * @return string The local part
+    * @access public
+    */
+	function getLocalPart($str){
+		if($sstr = strrchr($str,':')){
+			// get unqualified name
+			return substr( $sstr, 1 );
+		} else {
+			return $str;
+		}
+	}
+
+	/**
+    * returns the prefix part of a prefixed string
+    * returns false, if not prefixed
+    *
+    * @param string $str The prefixed string
+    * @return mixed The prefix or false if there is no prefix
+    * @access public
+    */
+	function getPrefix($str){
+		if($pos = strrpos($str,':')){
+			// get prefix
+			return substr($str,0,$pos);
+		}
+		return false;
+	}
+
+	/**
+    * pass it a prefix, it returns a namespace
+    *
+    * @param string $prefix The prefix
+    * @return mixed The namespace, false if no namespace has the specified prefix
+    * @access public
+    */
+	function getNamespaceFromPrefix($prefix){
+		if (isset($this->namespaces[$prefix])) {
+			return $this->namespaces[$prefix];
+		}
+		//$this->setError("No namespace registered for prefix '$prefix'");
+		return false;
+	}
+
+	/**
+    * returns the prefix for a given namespace (or prefix)
+    * or false if no prefixes registered for the given namespace
+    *
+    * @param string $ns The namespace
+    * @return mixed The prefix, false if the namespace has no prefixes
+    * @access public
+    */
+	function getPrefixFromNamespace($ns) {
+		foreach ($this->namespaces as $p => $n) {
+			if ($ns == $n || $ns == $p) {
+			    $this->usedNamespaces[$p] = $n;
+				return $p;
+			}
+		}
+		return false;
+	}
+
+	/**
+    * returns the time in ODBC canonical form with microseconds
+    *
+    * @return string The time in ODBC canonical form with microseconds
+    * @access public
+    */
+	function getmicrotime() {
+		if (function_exists('gettimeofday')) {
+			$tod = gettimeofday();
+			$sec = $tod['sec'];
+			$usec = $tod['usec'];
+		} else {
+			$sec = time();
+			$usec = 0;
+		}
+		return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
+	}
+
+	/**
+	 * Returns a string with the output of var_dump
+	 *
+	 * @param mixed $data The variable to var_dump
+	 * @return string The output of var_dump
+	 * @access public
+	 */
+    function varDump($data) {
+		ob_start();
+		var_dump($data);
+		$ret_val = ob_get_contents();
+		ob_end_clean();
+		return $ret_val;
+	}
+}
+
+// XML Schema Datatype Helper Functions
+
+//xsd:dateTime helpers
+
+/**
+* convert unix timestamp to ISO 8601 compliant date string
+*
+* @param    string $timestamp Unix time stamp
+* @access   public
+*/
+function timestamp_to_iso8601($timestamp,$utc=true){
+	$datestr = date('Y-m-d\TH:i:sO',$timestamp);
+	if($utc){
+		$eregStr =
+		'([0-9]{4})-'.	// centuries & years CCYY-
+		'([0-9]{2})-'.	// months MM-
+		'([0-9]{2})'.	// days DD
+		'T'.			// separator T
+		'([0-9]{2}):'.	// hours hh:
+		'([0-9]{2}):'.	// minutes mm:
+		'([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
+		'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
+
+		if(ereg($eregStr,$datestr,$regs)){
+			return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
+		}
+		return false;
+	} else {
+		return $datestr;
+	}
+}
+
+/**
+* convert ISO 8601 compliant date string to unix timestamp
+*
+* @param    string $datestr ISO 8601 compliant date string
+* @access   public
+*/
+function iso8601_to_timestamp($datestr){
+	$eregStr =
+	'([0-9]{4})-'.	// centuries & years CCYY-
+	'([0-9]{2})-'.	// months MM-
+	'([0-9]{2})'.	// days DD
+	'T'.			// separator T
+	'([0-9]{2}):'.	// hours hh:
+	'([0-9]{2}):'.	// minutes mm:
+	'([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
+	'(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
+	if(ereg($eregStr,$datestr,$regs)){
+		// not utc
+		if($regs[8] != 'Z'){
+			$op = substr($regs[8],0,1);
+			$h = substr($regs[8],1,2);
+			$m = substr($regs[8],strlen($regs[8])-2,2);
+			if($op == '-'){
+				$regs[4] = $regs[4] + $h;
+				$regs[5] = $regs[5] + $m;
+			} elseif($op == '+'){
+				$regs[4] = $regs[4] - $h;
+				$regs[5] = $regs[5] - $m;
+			}
+		}
+		return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
+	} else {
+		return false;
+	}
+}
+
+/**
+* sleeps some number of microseconds
+*
+* @param    string $usec the number of microseconds to sleep
+* @access   public
+* @deprecated
+*/
+function usleepWindows($usec)
+{
+	$start = gettimeofday();
+	
+	do
+	{
+		$stop = gettimeofday();
+		$timePassed = 1000000 * ($stop['sec'] - $start['sec'])
+		+ $stop['usec'] - $start['usec'];
+	}
+	while ($timePassed < $usec);
+}
+
+?><?php
+
+
+
+/**
+* Contains information for a SOAP fault.
+* Mainly used for returning faults from deployed functions
+* in a server instance.
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access public
+*/
+class soap_fault extends nusoap_base {
+	/**
+	 * The fault code (client|server)
+	 * @var string
+	 * @access private
+	 */
+	var $faultcode;
+	/**
+	 * The fault actor
+	 * @var string
+	 * @access private
+	 */
+	var $faultactor;
+	/**
+	 * The fault string, a description of the fault
+	 * @var string
+	 * @access private
+	 */
+	var $faultstring;
+	/**
+	 * The fault detail, typically a string or array of string
+	 * @var mixed
+	 * @access private
+	 */
+	var $faultdetail;
+
+	/**
+	* constructor
+    *
+    * @param string $faultcode (client | server)
+    * @param string $faultactor only used when msg routed between multiple actors
+    * @param string $faultstring human readable error message
+    * @param mixed $faultdetail detail, typically a string or array of string
+	*/
+	function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
+		parent::nusoap_base();
+		$this->faultcode = $faultcode;
+		$this->faultactor = $faultactor;
+		$this->faultstring = $faultstring;
+		$this->faultdetail = $faultdetail;
+	}
+
+	/**
+	* serialize a fault
+	*
+	* @return	string	The serialization of the fault instance.
+	* @access   public
+	*/
+	function serialize(){
+		$ns_string = '';
+		foreach($this->namespaces as $k => $v){
+			$ns_string .= "\n  xmlns:$k=\"$v\"";
+		}
+		$return_msg =
+			'<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
+			'<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
+				'<SOAP-ENV:Body>'.
+				'<SOAP-ENV:Fault>'.
+					$this->serialize_val($this->faultcode, 'faultcode').
+					$this->serialize_val($this->faultactor, 'faultactor').
+					$this->serialize_val($this->faultstring, 'faultstring').
+					$this->serialize_val($this->faultdetail, 'detail').
+				'</SOAP-ENV:Fault>'.
+				'</SOAP-ENV:Body>'.
+			'</SOAP-ENV:Envelope>';
+		return $return_msg;
+	}
+}
+
+
+
+?><?php
+
+
+
+/**
+* parses an XML Schema, allows access to it's data, other utility methods
+* no validation... yet.
+* very experimental and limited. As is discussed on XML-DEV, I'm one of the people
+* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
+* tutorials I refer to :)
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class XMLSchema extends nusoap_base  {
+	
+	// files
+	var $schema = '';
+	var $xml = '';
+	// namespaces
+	var $enclosingNamespaces;
+	// schema info
+	var $schemaInfo = array();
+	var $schemaTargetNamespace = '';
+	// types, elements, attributes defined by the schema
+	var $attributes = array();
+	var $complexTypes = array();
+	var $complexTypeStack = array();
+	var $currentComplexType = null;
+	var $elements = array();
+	var $elementStack = array();
+	var $currentElement = null;
+	var $simpleTypes = array();
+	var $simpleTypeStack = array();
+	var $currentSimpleType = null;
+	// imports
+	var $imports = array();
+	// parser vars
+	var $parser;
+	var $position = 0;
+	var $depth = 0;
+	var $depth_array = array();
+	var $message = array();
+	var $defaultNamespace = array();
+    
+	/**
+	* constructor
+	*
+	* @param    string $schema schema document URI
+	* @param    string $xml xml document URI
+	* @param	string $namespaces namespaces defined in enclosing XML
+	* @access   public
+	*/
+	function XMLSchema($schema='',$xml='',$namespaces=array()){
+		parent::nusoap_base();
+		$this->debug('xmlschema class instantiated, inside constructor');
+		// files
+		$this->schema = $schema;
+		$this->xml = $xml;
+
+		// namespaces
+		$this->enclosingNamespaces = $namespaces;
+		$this->namespaces = array_merge($this->namespaces, $namespaces);
+
+		// parse schema file
+		if($schema != ''){
+			$this->debug('initial schema file: '.$schema);
+			$this->parseFile($schema, 'schema');
+		}
+
+		// parse xml file
+		if($xml != ''){
+			$this->debug('initial xml file: '.$xml);
+			$this->parseFile($xml, 'xml');
+		}
+
+	}
+
+    /**
+    * parse an XML file
+    *
+    * @param string $xml, path/URL to XML file
+    * @param string $type, (schema | xml)
+	* @return boolean
+    * @access public
+    */
+	function parseFile($xml,$type){
+		// parse xml file
+		if($xml != ""){
+			$xmlStr = @join("",@file($xml));
+			if($xmlStr == ""){
+				$msg = 'Error reading XML from '.$xml;
+				$this->setError($msg);
+				$this->debug($msg);
+			return false;
+			} else {
+				$this->debug("parsing $xml");
+				$this->parseString($xmlStr,$type);
+				$this->debug("done parsing $xml");
+			return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	* parse an XML string
+	*
+	* @param    string $xml path or URL
+    * @param string $type, (schema|xml)
+	* @access   private
+	*/
+	function parseString($xml,$type){
+		// parse xml string
+		if($xml != ""){
+
+	    	// Create an XML parser.
+	    	$this->parser = xml_parser_create();
+	    	// Set the options for parsing the XML data.
+	    	xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+
+	    	// Set the object for the parser.
+	    	xml_set_object($this->parser, $this);
+
+	    	// Set the element handlers for the parser.
+			if($type == "schema"){
+		    	xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
+		    	xml_set_character_data_handler($this->parser,'schemaCharacterData');
+			} elseif($type == "xml"){
+				xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
+		    	xml_set_character_data_handler($this->parser,'xmlCharacterData');
+			}
+
+		    // Parse the XML file.
+		    if(!xml_parse($this->parser,$xml,true)){
+			// Display an error message.
+				$errstr = sprintf('XML error parsing XML schema on line %d: %s',
+				xml_get_current_line_number($this->parser),
+				xml_error_string(xml_get_error_code($this->parser))
+				);
+				$this->debug($errstr);
+				$this->debug("XML payload:\n" . $xml);
+				$this->setError($errstr);
+	    	}
+            
+			xml_parser_free($this->parser);
+		} else{
+			$this->debug('no xml passed to parseString()!!');
+			$this->setError('no xml passed to parseString()!!');
+		}
+	}
+
+	/**
+	* start-element handler
+	*
+	* @param    string $parser XML parser object
+	* @param    string $name element name
+	* @param    string $attrs associative array of attributes
+	* @access   private
+	*/
+	function schemaStartElement($parser, $name, $attrs) {
+		
+		// position in the total number of elements, starting from 0
+		$pos = $this->position++;
+		$depth = $this->depth++;
+		// set self as current value for this depth
+		$this->depth_array[$depth] = $pos;
+		$this->message[$pos] = array('cdata' => ''); 
+		if ($depth > 0) {
+			$this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
+		} else {
+			$this->defaultNamespace[$pos] = false;
+		}
+
+		// get element prefix
+		if($prefix = $this->getPrefix($name)){
+			// get unqualified name
+			$name = $this->getLocalPart($name);
+		} else {
+        	$prefix = '';
+        }
+		
+        // loop thru attributes, expanding, and registering namespace declarations
+        if(count($attrs) > 0){
+        	foreach($attrs as $k => $v){
+                // if ns declarations, add to class level array of valid namespaces
+				if(ereg("^xmlns",$k)){
+                	//$this->xdebug("$k: $v");
+                	//$this->xdebug('ns_prefix: '.$this->getPrefix($k));
+                	if($ns_prefix = substr(strrchr($k,':'),1)){
+                		//$this->xdebug("Add namespace[$ns_prefix] = $v");
+						$this->namespaces[$ns_prefix] = $v;
+					} else {
+						$this->defaultNamespace[$pos] = $v;
+						if (! $this->getPrefixFromNamespace($v)) {
+							$this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
+						}
+					}
+					if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
+						$this->XMLSchemaVersion = $v;
+						$this->namespaces['xsi'] = $v.'-instance';
+					}
+				}
+        	}
+        	foreach($attrs as $k => $v){
+                // expand each attribute
+                $k = strpos($k,':') ? $this->expandQname($k) : $k;
+                $v = strpos($v,':') ? $this->expandQname($v) : $v;
+        		$eAttrs[$k] = $v;
+        	}
+        	$attrs = $eAttrs;
+        } else {
+        	$attrs = array();
+        }
+		// find status, register data
+		switch($name){
+			case 'all':			// (optional) compositor content for a complexType
+			case 'choice':
+			case 'group':
+			case 'sequence':
+				//$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
+				$this->complexTypes[$this->currentComplexType]['compositor'] = $name;
+				//if($name == 'all' || $name == 'sequence'){
+				//	$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+				//}
+			break;
+			case 'attribute':	// complexType attribute
+            	//$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
+            	$this->xdebug("parsing attribute:");
+            	$this->appendDebug($this->varDump($attrs));
+				if (!isset($attrs['form'])) {
+					$attrs['form'] = $this->schemaInfo['attributeFormDefault'];
+				}
+            	if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
+					$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+					if (!strpos($v, ':')) {
+						// no namespace in arrayType attribute value...
+						if ($this->defaultNamespace[$pos]) {
+							// ...so use the default
+							$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+						}
+					}
+            	}
+                if(isset($attrs['name'])){
+					$this->attributes[$attrs['name']] = $attrs;
+					$aname = $attrs['name'];
+				} elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
+					if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
+	                	$aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+	                } else {
+	                	$aname = '';
+	                }
+				} elseif(isset($attrs['ref'])){
+					$aname = $attrs['ref'];
+                    $this->attributes[$attrs['ref']] = $attrs;
+				}
+                
+				if($this->currentComplexType){	// This should *always* be
+					$this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
+				}
+				// arrayType attribute
+				if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
+					$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+                	$prefix = $this->getPrefix($aname);
+					if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
+						$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+					} else {
+						$v = '';
+					}
+                    if(strpos($v,'[,]')){
+                        $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
+                    }
+                    $v = substr($v,0,strpos($v,'[')); // clip the []
+                    if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
+                        $v = $this->XMLSchemaVersion.':'.$v;
+                    }
+                    $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
+				}
+			break;
+			case 'complexContent':	// (optional) content for a complexType
+			break;
+			case 'complexType':
+				array_push($this->complexTypeStack, $this->currentComplexType);
+				if(isset($attrs['name'])){
+					$this->xdebug('processing named complexType '.$attrs['name']);
+					//$this->currentElement = false;
+					$this->currentComplexType = $attrs['name'];
+					$this->complexTypes[$this->currentComplexType] = $attrs;
+					$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
+					// This is for constructs like
+					//           <complexType name="ListOfString" base="soap:Array">
+					//                <sequence>
+					//                    <element name="string" type="xsd:string"
+					//                        minOccurs="0" maxOccurs="unbounded" />
+					//                </sequence>
+					//            </complexType>
+					if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
+						$this->xdebug('complexType is unusual array');
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+					} else {
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+					}
+				}else{
+					$this->xdebug('processing unnamed complexType for element '.$this->currentElement);
+					$this->currentComplexType = $this->currentElement . '_ContainedType';
+					//$this->currentElement = false;
+					$this->complexTypes[$this->currentComplexType] = $attrs;
+					$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
+					// This is for constructs like
+					//           <complexType name="ListOfString" base="soap:Array">
+					//                <sequence>
+					//                    <element name="string" type="xsd:string"
+					//                        minOccurs="0" maxOccurs="unbounded" />
+					//                </sequence>
+					//            </complexType>
+					if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
+						$this->xdebug('complexType is unusual array');
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+					} else {
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+					}
+				}
+			break;
+			case 'element':
+				array_push($this->elementStack, $this->currentElement);
+				// elements defined as part of a complex type should
+				// not really be added to $this->elements, but for some
+				// reason, they are
+				if (!isset($attrs['form'])) {
+					$attrs['form'] = $this->schemaInfo['elementFormDefault'];
+				}
+				if(isset($attrs['type'])){
+					$this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
+					if (! $this->getPrefix($attrs['type'])) {
+						if ($this->defaultNamespace[$pos]) {
+							$attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
+							$this->xdebug('used default namespace to make type ' . $attrs['type']);
+						}
+					}
+					// This is for constructs like
+					//           <complexType name="ListOfString" base="soap:Array">
+					//                <sequence>
+					//                    <element name="string" type="xsd:string"
+					//                        minOccurs="0" maxOccurs="unbounded" />
+					//                </sequence>
+					//            </complexType>
+					if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
+						$this->xdebug('arrayType for unusual array is ' . $attrs['type']);
+						$this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
+					}
+					$this->currentElement = $attrs['name'];
+					$this->elements[ $attrs['name'] ] = $attrs;
+					$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
+					$ename = $attrs['name'];
+				} elseif(isset($attrs['ref'])){
+					$this->xdebug("processing element as ref to ".$attrs['ref']);
+					$this->currentElement = "ref to ".$attrs['ref'];
+					$ename = $this->getLocalPart($attrs['ref']);
+				} else {
+					$this->xdebug("processing untyped element ".$attrs['name']);
+					$this->currentElement = $attrs['name'];
+					$this->elements[ $attrs['name'] ] = $attrs;
+					$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
+					$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
+					$this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
+					$ename = $attrs['name'];
+				}
+				if(isset($ename) && $this->currentComplexType){
+					$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
+				}
+			break;
+			case 'enumeration':	//	restriction value list member
+				$this->xdebug('enumeration ' . $attrs['value']);
+				if ($this->currentSimpleType) {
+					$this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
+				} elseif ($this->currentComplexType) {
+					$this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
+				}
+			break;
+			case 'extension':	// simpleContent or complexContent type extension
+				$this->xdebug('extension ' . $attrs['base']);
+				if ($this->currentComplexType) {
+					$this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
+				}
+			break;
+			case 'import':
+			    if (isset($attrs['schemaLocation'])) {
+					//$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
+                    $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
+				} else {
+					//$this->xdebug('import namespace ' . $attrs['namespace']);
+                    $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
+					if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
+						$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
+					}
+				}
+			break;
+			case 'list':	// simpleType value list
+			break;
+			case 'restriction':	// simpleType, simpleContent or complexContent value restriction
+				$this->xdebug('restriction ' . $attrs['base']);
+				if($this->currentSimpleType){
+					$this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
+				} elseif($this->currentComplexType){
+					$this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
+					if(strstr($attrs['base'],':') == ':Array'){
+						$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+					}
+				}
+			break;
+			case 'schema':
+				$this->schemaInfo = $attrs;
+				$this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
+				if (isset($attrs['targetNamespace'])) {
+					$this->schemaTargetNamespace = $attrs['targetNamespace'];
+				}
+				if (!isset($attrs['elementFormDefault'])) {
+					$this->schemaInfo['elementFormDefault'] = 'unqualified';
+				}
+				if (!isset($attrs['attributeFormDefault'])) {
+					$this->schemaInfo['attributeFormDefault'] = 'unqualified';
+				}
+			break;
+			case 'simpleContent':	// (optional) content for a complexType
+			break;
+			case 'simpleType':
+				array_push($this->simpleTypeStack, $this->currentSimpleType);
+				if(isset($attrs['name'])){
+					$this->xdebug("processing simpleType for name " . $attrs['name']);
+					$this->currentSimpleType = $attrs['name'];
+					$this->simpleTypes[ $attrs['name'] ] = $attrs;
+					$this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
+					$this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
+				} else {
+					$this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
+					$this->currentSimpleType = $this->currentElement . '_ContainedType';
+					//$this->currentElement = false;
+					$this->simpleTypes[$this->currentSimpleType] = $attrs;
+					$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
+				}
+			break;
+			case 'union':	// simpleType type list
+			break;
+			default:
+				//$this->xdebug("do not have anything to do for element $name");
+		}
+	}
+
+	/**
+	* end-element handler
+	*
+	* @param    string $parser XML parser object
+	* @param    string $name element name
+	* @access   private
+	*/
+	function schemaEndElement($parser, $name) {
+		// bring depth down a notch
+		$this->depth--;
+		// position of current element is equal to the last value left in depth_array for my depth
+		if(isset($this->depth_array[$this->depth])){
+        	$pos = $this->depth_array[$this->depth];
+        }
+		// get element prefix
+		if ($prefix = $this->getPrefix($name)){
+			// get unqualified name
+			$name = $this->getLocalPart($name);
+		} else {
+        	$prefix = '';
+        }
+		// move on...
+		if($name == 'complexType'){
+			$this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
+			$this->currentComplexType = array_pop($this->complexTypeStack);
+			//$this->currentElement = false;
+		}
+		if($name == 'element'){
+			$this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
+			$this->currentElement = array_pop($this->elementStack);
+		}
+		if($name == 'simpleType'){
+			$this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
+			$this->currentSimpleType = array_pop($this->simpleTypeStack);
+		}
+	}
+
+	/**
+	* element content handler
+	*
+	* @param    string $parser XML parser object
+	* @param    string $data element content
+	* @access   private
+	*/
+	function schemaCharacterData($parser, $data){
+		$pos = $this->depth_array[$this->depth - 1];
+		$this->message[$pos]['cdata'] .= $data;
+	}
+
+	/**
+	* serialize the schema
+	*
+	* @access   public
+	*/
+	function serializeSchema(){
+
+		$schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
+		$xml = '';
+		// imports
+		if (sizeof($this->imports) > 0) {
+			foreach($this->imports as $ns => $list) {
+				foreach ($list as $ii) {
+					if ($ii['location'] != '') {
+						$xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
+					} else {
+						$xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
+					}
+				}
+			} 
+		} 
+		// complex types
+		foreach($this->complexTypes as $typeName => $attrs){
+			$contentStr = '';
+			// serialize child elements
+			if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
+				foreach($attrs['elements'] as $element => $eParts){
+					if(isset($eParts['ref'])){
+						$contentStr .= "   <$schemaPrefix:element ref=\"$element\"/>\n";
+					} else {
+						$contentStr .= "   <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
+						foreach ($eParts as $aName => $aValue) {
+							// handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
+							if ($aName != 'name' && $aName != 'type') {
+								$contentStr .= " $aName=\"$aValue\"";
+							}
+						}
+						$contentStr .= "/>\n";
+					}
+				}
+				// compositor wraps elements
+				if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
+					$contentStr = "  <$schemaPrefix:$attrs[compositor]>\n".$contentStr."  </$schemaPrefix:$attrs[compositor]>\n";
+				}
+			}
+			// attributes
+			if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
+				foreach($attrs['attrs'] as $attr => $aParts){
+					$contentStr .= "    <$schemaPrefix:attribute";
+					foreach ($aParts as $a => $v) {
+						if ($a == 'ref' || $a == 'type') {
+							$contentStr .= " $a=\"".$this->contractQName($v).'"';
+						} elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
+							$this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
+							$contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
+						} else {
+							$contentStr .= " $a=\"$v\"";
+						}
+					}
+					$contentStr .= "/>\n";
+				}
+			}
+			// if restriction
+			if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
+				$contentStr = "   <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr."   </$schemaPrefix:restriction>\n";
+				// complex or simple content
+				if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
+					$contentStr = "  <$schemaPrefix:complexContent>\n".$contentStr."  </$schemaPrefix:complexContent>\n";
+				}
+			}
+			// finalize complex type
+			if($contentStr != ''){
+				$contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
+			} else {
+				$contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
+			}
+			$xml .= $contentStr;
+		}
+		// simple types
+		if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
+			foreach($this->simpleTypes as $typeName => $eParts){
+				$xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n  <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
+				if (isset($eParts['enumeration'])) {
+					foreach ($eParts['enumeration'] as $e) {
+						$xml .= "  <$schemaPrefix:enumeration value=\"$e\"/>\n";
+					}
+				}
+				$xml .= " </$schemaPrefix:simpleType>";
+			}
+		}
+		// elements
+		if(isset($this->elements) && count($this->elements) > 0){
+			foreach($this->elements as $element => $eParts){
+				$xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
+			}
+		}
+		// attributes
+		if(isset($this->attributes) && count($this->attributes) > 0){
+			foreach($this->attributes as $attr => $aParts){
+				$xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
+			}
+		}
+		// finish 'er up
+		$el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
+		foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
+			$el .= " xmlns:$nsp=\"$ns\"\n";
+		}
+		$xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
+		return $xml;
+	}
+
+	/**
+	* adds debug data to the clas level debug string
+	*
+	* @param    string $string debug data
+	* @access   private
+	*/
+	function xdebug($string){
+		$this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
+	}
+
+    /**
+    * get the PHP type of a user defined type in the schema
+    * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
+    * returns false if no type exists, or not w/ the given namespace
+    * else returns a string that is either a native php type, or 'struct'
+    *
+    * @param string $type, name of defined type
+    * @param string $ns, namespace of type
+    * @return mixed
+    * @access public
+    * @deprecated
+    */
+	function getPHPType($type,$ns){
+		if(isset($this->typemap[$ns][$type])){
+			//print "found type '$type' and ns $ns in typemap<br>";
+			return $this->typemap[$ns][$type];
+		} elseif(isset($this->complexTypes[$type])){
+			//print "getting type '$type' and ns $ns from complexTypes array<br>";
+			return $this->complexTypes[$type]['phpType'];
+		}
+		return false;
+	}
+
+	/**
+    * returns an associative array of information about a given type
+    * returns false if no type exists by the given name
+    *
+	*	For a complexType typeDef = array(
+	*	'restrictionBase' => '',
+	*	'phpType' => '',
+	*	'compositor' => '(sequence|all)',
+	*	'elements' => array(), // refs to elements array
+	*	'attrs' => array() // refs to attributes array
+	*	... and so on (see addComplexType)
+	*	)
+	*
+	*   For simpleType or element, the array has different keys.
+    *
+    * @param string
+    * @return mixed
+    * @access public
+    * @see addComplexType
+    * @see addSimpleType
+    * @see addElement
+    */
+	function getTypeDef($type){
+		//$this->debug("in getTypeDef for type $type");
+		if(isset($this->complexTypes[$type])){
+			$this->xdebug("in getTypeDef, found complexType $type");
+			return $this->complexTypes[$type];
+		} elseif(isset($this->simpleTypes[$type])){
+			$this->xdebug("in getTypeDef, found simpleType $type");
+			if (!isset($this->simpleTypes[$type]['phpType'])) {
+				// get info for type to tack onto the simple type
+				// TODO: can this ever really apply (i.e. what is a simpleType really?)
+				$uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
+				$ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
+				$etype = $this->getTypeDef($uqType);
+				if ($etype) {
+					$this->xdebug("in getTypeDef, found type for simpleType $type:");
+					$this->xdebug($this->varDump($etype));
+					if (isset($etype['phpType'])) {
+						$this->simpleTypes[$type]['phpType'] = $etype['phpType'];
+					}
+					if (isset($etype['elements'])) {
+						$this->simpleTypes[$type]['elements'] = $etype['elements'];
+					}
+				}
+			}
+			return $this->simpleTypes[$type];
+		} elseif(isset($this->elements[$type])){
+			$this->xdebug("in getTypeDef, found element $type");
+			if (!isset($this->elements[$type]['phpType'])) {
+				// get info for type to tack onto the element
+				$uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
+				$ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
+				$etype = $this->getTypeDef($uqType);
+				if ($etype) {
+					$this->xdebug("in getTypeDef, found type for element $type:");
+					$this->xdebug($this->varDump($etype));
+					if (isset($etype['phpType'])) {
+						$this->elements[$type]['phpType'] = $etype['phpType'];
+					}
+					if (isset($etype['elements'])) {
+						$this->elements[$type]['elements'] = $etype['elements'];
+					}
+				} elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
+					$this->xdebug("in getTypeDef, element $type is an XSD type");
+					$this->elements[$type]['phpType'] = 'scalar';
+				}
+			}
+			return $this->elements[$type];
+		} elseif(isset($this->attributes[$type])){
+			$this->xdebug("in getTypeDef, found attribute $type");
+			return $this->attributes[$type];
+		} elseif (ereg('_ContainedType$', $type)) {
+			$this->xdebug("in getTypeDef, have an untyped element $type");
+			$typeDef['typeClass'] = 'simpleType';
+			$typeDef['phpType'] = 'scalar';
+			$typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
+			return $typeDef;
+		}
+		$this->xdebug("in getTypeDef, did not find $type");
+		return false;
+	}
+
+	/**
+    * returns a sample serialization of a given type, or false if no type by the given name
+    *
+    * @param string $type, name of type
+    * @return mixed
+    * @access public
+    * @deprecated
+    */
+    function serializeTypeDef($type){
+    	//print "in sTD() for type $type<br>";
+	if($typeDef = $this->getTypeDef($type)){
+		$str .= '<'.$type;
+	    if(is_array($typeDef['attrs'])){
+		foreach($attrs as $attName => $data){
+		    $str .= " $attName=\"{type = ".$data['type']."}\"";
+		}
+	    }
+	    $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
+	    if(count($typeDef['elements']) > 0){
+		$str .= ">";
+		foreach($typeDef['elements'] as $element => $eData){
+		    $str .= $this->serializeTypeDef($element);
+		}
+		$str .= "</$type>";
+	    } elseif($typeDef['typeClass'] == 'element') {
+		$str .= "></$type>";
+	    } else {
+		$str .= "/>";
+	    }
+			return $str;
+	}
+    	return false;
+    }
+
+    /**
+    * returns HTML form elements that allow a user
+    * to enter values for creating an instance of the given type.
+    *
+    * @param string $name, name for type instance
+    * @param string $type, name of type
+    * @return string
+    * @access public
+    * @deprecated
+	*/
+	function typeToForm($name,$type){
+		// get typedef
+		if($typeDef = $this->getTypeDef($type)){
+			// if struct
+			if($typeDef['phpType'] == 'struct'){
+				$buffer .= '<table>';
+				foreach($typeDef['elements'] as $child => $childDef){
+					$buffer .= "
+					<tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
+					<td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
+				}
+				$buffer .= '</table>';
+			// if array
+			} elseif($typeDef['phpType'] == 'array'){
+				$buffer .= '<table>';
+				for($i=0;$i < 3; $i++){
+					$buffer .= "
+					<tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
+					<td><input type='text' name='parameters[".$name."][]'></td></tr>";
+				}
+				$buffer .= '</table>';
+			// if scalar
+			} else {
+				$buffer .= "<input type='text' name='parameters[$name]'>";
+			}
+		} else {
+			$buffer .= "<input type='text' name='parameters[$name]'>";
+		}
+		return $buffer;
+	}
+	
+	/**
+	* adds a complex type to the schema
+	* 
+	* example: array
+	* 
+	* addType(
+	* 	'ArrayOfstring',
+	* 	'complexType',
+	* 	'array',
+	* 	'',
+	* 	'SOAP-ENC:Array',
+	* 	array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
+	* 	'xsd:string'
+	* );
+	* 
+	* example: PHP associative array ( SOAP Struct )
+	* 
+	* addType(
+	* 	'SOAPStruct',
+	* 	'complexType',
+	* 	'struct',
+	* 	'all',
+	* 	array('myVar'=> array('name'=>'myVar','type'=>'string')
+	* );
+	* 
+	* @param name
+	* @param typeClass (complexType|simpleType|attribute)
+	* @param phpType: currently supported are array and struct (php assoc array)
+	* @param compositor (all|sequence|choice)
+	* @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+	* @param elements = array ( name = array(name=>'',type=>'') )
+	* @param attrs = array(
+	* 	array(
+	*		'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
+	*		"http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
+	* 	)
+	* )
+	* @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
+	* @access public
+	* @see getTypeDef
+	*/
+	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
+		$this->complexTypes[$name] = array(
+	    'name'		=> $name,
+	    'typeClass'	=> $typeClass,
+	    'phpType'	=> $phpType,
+		'compositor'=> $compositor,
+	    'restrictionBase' => $restrictionBase,
+		'elements'	=> $elements,
+	    'attrs'		=> $attrs,
+	    'arrayType'	=> $arrayType
+		);
+		
+		$this->xdebug("addComplexType $name:");
+		$this->appendDebug($this->varDump($this->complexTypes[$name]));
+	}
+	
+	/**
+	* adds a simple type to the schema
+	*
+	* @param string $name
+	* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+	* @param string $typeClass (should always be simpleType)
+	* @param string $phpType (should always be scalar)
+	* @param array $enumeration array of values
+	* @access public
+	* @see xmlschema
+	* @see getTypeDef
+	*/
+	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
+		$this->simpleTypes[$name] = array(
+	    'name'			=> $name,
+	    'typeClass'		=> $typeClass,
+	    'phpType'		=> $phpType,
+	    'type'			=> $restrictionBase,
+	    'enumeration'	=> $enumeration
+		);
+		
+		$this->xdebug("addSimpleType $name:");
+		$this->appendDebug($this->varDump($this->simpleTypes[$name]));
+	}
+
+	/**
+	* adds an element to the schema
+	*
+	* @param array $attrs attributes that must include name and type
+	* @see xmlschema
+	* @access public
+	*/
+	function addElement($attrs) {
+		if (! $this->getPrefix($attrs['type'])) {
+			$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
+		}
+		$this->elements[ $attrs['name'] ] = $attrs;
+		$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
+		
+		$this->xdebug("addElement " . $attrs['name']);
+		$this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
+	}
+}
+
+
+
+?><?php
+
+
+
+/**
+* For creating serializable abstractions of native PHP types.  This class
+* allows element name/namespace, XSD type, and XML attributes to be
+* associated with a value.  This is extremely useful when WSDL is not
+* used, but is also useful when WSDL is used with polymorphic types, including
+* xsd:anyType and user-defined types.
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class soapval extends nusoap_base {
+	/**
+	 * The XML element name
+	 *
+	 * @var string
+	 * @access private
+	 */
+	var $name;
+	/**
+	 * The XML type name (string or false)
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $type;
+	/**
+	 * The PHP value
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $value;
+	/**
+	 * The XML element namespace (string or false)
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $element_ns;
+	/**
+	 * The XML type namespace (string or false)
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $type_ns;
+	/**
+	 * The XML element attributes (array or false)
+	 *
+	 * @var mixed
+	 * @access private
+	 */
+	var $attributes;
+
+	/**
+	* constructor
+	*
+	* @param    string $name optional name
+	* @param    mixed $type optional type name
+	* @param	mixed $value optional value
+	* @param	mixed $element_ns optional namespace of value
+	* @param	mixed $type_ns optional namespace of type
+	* @param	mixed $attributes associative array of attributes to add to element serialization
+	* @access   public
+	*/
+  	function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
+		parent::nusoap_base();
+		$this->name = $name;
+		$this->type = $type;
+		$this->value = $value;
+		$this->element_ns = $element_ns;
+		$this->type_ns = $type_ns;
+		$this->attributes = $attributes;
+    }
+
+	/**
+	* return serialized value
+	*
+	* @param	string $use The WSDL use value (encoded|literal)
+	* @return	string XML data
+	* @access   public
+	*/
+	function serialize($use='encoded') {
+		return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use);
+    }
+
+	/**
+	* decodes a soapval object into a PHP native type
+	*
+	* @return	mixed
+	* @access   public
+	*/
+	function decode(){
+		return $this->value;
+	}
+}
+
+
+
+?><?php
+
+
+
+/**
+* transport class for sending/receiving data via HTTP and HTTPS
+* NOTE: PHP must be compiled with the CURL extension for HTTPS support
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access public
+*/
+class soap_transport_http extends nusoap_base {
+
+	var $url = '';
+	var $uri = '';
+	var $digest_uri = '';
+	var $scheme = '';
+	var $host = '';
+	var $port = '';
+	var $path = '';
+	var $request_method = 'POST';
+	var $protocol_version = '1.0';
+	var $encoding = '';
+	var $outgoing_headers = array();
+	var $incoming_headers = array();
+	var $incoming_cookies = array();
+	var $outgoing_payload = '';
+	var $incoming_payload = '';
+	var $useSOAPAction = true;
+	var $persistentConnection = false;
+	var $ch = false;	// cURL handle
+	var $username = '';
+	var $password = '';
+	var $authtype = '';
+	var $digestRequest = array();
+	var $certRequest = array();	// keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional)
+								// cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
+								// sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
+								// sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem'
+								// passphrase: SSL key password/passphrase
+								// verifypeer: default is 1
+								// verifyhost: default is 1
+
+	/**
+	* constructor
+	*/
+	function soap_transport_http($url){
+		parent::nusoap_base();
+		$this->setURL($url);
+		ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
+		$this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')';
+		$this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']);
+	}
+
+	function setURL($url) {
+		$this->url = $url;
+
+		$u = parse_url($url);
+		foreach($u as $k => $v){
+			$this->debug("$k = $v");
+			$this->$k = $v;
+		}
+		
+		// add any GET params to path
+		if(isset($u['query']) && $u['query'] != ''){
+            $this->path .= '?' . $u['query'];
+		}
+		
+		// set default port
+		if(!isset($u['port'])){
+			if($u['scheme'] == 'https'){
+				$this->port = 443;
+			} else {
+				$this->port = 80;
+			}
+		}
+		
+		$this->uri = $this->path;
+		$this->digest_uri = $this->uri;
+		
+		// build headers
+		if (!isset($u['port'])) {
+			$this->outgoing_headers['Host'] = $this->host;
+		} else {
+			$this->outgoing_headers['Host'] = $this->host.':'.$this->port;
+		}
+		$this->debug('set Host: ' . $this->outgoing_headers['Host']);
+
+		if (isset($u['user']) && $u['user'] != '') {
+			$this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
+		}
+	}
+	
+	function connect($connection_timeout=0,$response_timeout=30){
+	  	// For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like
+	  	// "regular" socket.
+	  	// TODO: disabled for now because OpenSSL must be *compiled* in (not just
+	  	//       loaded), and until PHP5 stream_get_wrappers is not available.
+//	  	if ($this->scheme == 'https') {
+//		  	if (version_compare(phpversion(), '4.3.0') >= 0) {
+//		  		if (extension_loaded('openssl')) {
+//		  			$this->scheme = 'ssl';
+//		  			$this->debug('Using SSL over OpenSSL');
+//		  		}
+//		  	}
+//		}
+		$this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
+	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+		// use persistent connection
+		if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
+			if (!feof($this->fp)) {
+				$this->debug('Re-use persistent connection');
+				return true;
+			}
+			fclose($this->fp);
+			$this->debug('Closed persistent connection at EOF');
+		}
+
+		// munge host if using OpenSSL
+		if ($this->scheme == 'ssl') {
+			$host = 'ssl://' . $this->host;
+		} else {
+			$host = $this->host;
+		}
+		$this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
+
+		// open socket
+		if($connection_timeout > 0){
+			$this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
+		} else {
+			$this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
+		}
+		
+		// test pointer
+		if(!$this->fp) {
+			$msg = 'Couldn\'t open socket connection to server ' . $this->url;
+			if ($this->errno) {
+				$msg .= ', Error ('.$this->errno.'): '.$this->error_str;
+			} else {
+				$msg .= ' prior to connect().  This is often a problem looking up the host name.';
+			}
+			$this->debug($msg);
+			$this->setError($msg);
+			return false;
+		}
+		
+		// set response timeout
+		$this->debug('set response timeout to ' . $response_timeout);
+		socket_set_timeout( $this->fp, $response_timeout);
+
+		$this->debug('socket connected');
+		return true;
+	  } else if ($this->scheme == 'https') {
+		if (!extension_loaded('curl')) {
+			$this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
+			return false;
+		}
+		$this->debug('connect using https');
+		// init CURL
+		$this->ch = curl_init();
+		// set url
+		$hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host";
+		// add path
+		$hostURL .= $this->path;
+		curl_setopt($this->ch, CURLOPT_URL, $hostURL);
+		// follow location headers (re-directs)
+		curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1);
+		// ask for headers in the response output
+		curl_setopt($this->ch, CURLOPT_HEADER, 1);
+		// ask for the response output as the return value
+		curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
+		// encode
+		// We manage this ourselves through headers and encoding
+//		if(function_exists('gzuncompress')){
+//			curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate');
+//		}
+		// persistent connection
+		if ($this->persistentConnection) {
+			// The way we send data, we cannot use persistent connections, since
+			// there will be some "junk" at the end of our request.
+			//curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true);
+			$this->persistentConnection = false;
+			$this->outgoing_headers['Connection'] = 'close';
+			$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
+		}
+		// set timeout
+		if ($connection_timeout != 0) {
+			curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout);
+		}
+		// TODO: cURL has added a connection timeout separate from the response timeout
+		//if ($connection_timeout != 0) {
+		//	curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
+		//}
+		//if ($response_timeout != 0) {
+		//	curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout);
+		//}
+
+		// recent versions of cURL turn on peer/host checking by default,
+		// while PHP binaries are not compiled with a default location for the
+		// CA cert bundle, so disable peer/host checking.
+//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');		
+		curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
+		curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
+
+		// support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
+		if ($this->authtype == 'certificate') {
+			if (isset($this->certRequest['cainfofile'])) {
+				curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']);
+			}
+			if (isset($this->certRequest['verifypeer'])) {
+				curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
+			} else {
+				curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1);
+			}
+			if (isset($this->certRequest['verifyhost'])) {
+				curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
+			} else {
+				curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1);
+			}
+			if (isset($this->certRequest['sslcertfile'])) {
+				curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
+			}
+			if (isset($this->certRequest['sslkeyfile'])) {
+				curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
+			}
+			if (isset($this->certRequest['passphrase'])) {
+				curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']);
+			}
+		}
+		$this->debug('cURL connection set up');
+		return true;
+	  } else {
+		$this->setError('Unknown scheme ' . $this->scheme);
+		$this->debug('Unknown scheme ' . $this->scheme);
+		return false;
+	  }
+	}
+	
+	/**
+	* send the SOAP message via HTTP
+	*
+	* @param    string $data message data
+	* @param    integer $timeout set connection timeout in seconds
+	* @param	integer $response_timeout set response timeout in seconds
+	* @param	array $cookies cookies to send
+	* @return	string data
+	* @access   public
+	*/
+	function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) {
+		
+		$this->debug('entered send() with data of length: '.strlen($data));
+
+		$this->tryagain = true;
+		$tries = 0;
+		while ($this->tryagain) {
+			$this->tryagain = false;
+			if ($tries++ < 2) {
+				// make connnection
+				if (!$this->connect($timeout, $response_timeout)){
+					return false;
+				}
+				
+				// send request
+				if (!$this->sendRequest($data, $cookies)){
+					return false;
+				}
+				
+				// get response
+				$respdata = $this->getResponse();
+			} else {
+				$this->setError('Too many tries to get an OK response');
+			}
+		}		
+		$this->debug('end of send()');
+		return $respdata;
+	}
+
+
+	/**
+	* send the SOAP message via HTTPS 1.0 using CURL
+	*
+	* @param    string $msg message data
+	* @param    integer $timeout set connection timeout in seconds
+	* @param	integer $response_timeout set response timeout in seconds
+	* @param	array $cookies cookies to send
+	* @return	string data
+	* @access   public
+	*/
+	function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
+		return $this->send($data, $timeout, $response_timeout, $cookies);
+	}
+	
+	/**
+	* if authenticating, set user credentials here
+	*
+	* @param    string $username
+	* @param    string $password
+	* @param	string $authtype (basic, digest, certificate)
+	* @param	array $digestRequest (keys must be nonce, nc, realm, qop)
+	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
+	* @access   public
+	*/
+	function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) {
+		$this->debug("Set credentials for authtype $authtype");
+		// cf. RFC 2617
+		if ($authtype == 'basic') {
+			$this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password);
+		} elseif ($authtype == 'digest') {
+			if (isset($digestRequest['nonce'])) {
+				$digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
+				
+				// calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html)
+	
+				// A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+				$A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
+	
+				// H(A1) = MD5(A1)
+				$HA1 = md5($A1);
+	
+				// A2 = Method ":" digest-uri-value
+				$A2 = 'POST:' . $this->digest_uri;
+	
+				// H(A2)
+				$HA2 =  md5($A2);
+	
+				// KD(secret, data) = H(concat(secret, ":", data))
+				// if qop == auth:
+				// request-digest  = <"> < KD ( H(A1),     unq(nonce-value)
+				//                              ":" nc-value
+				//                              ":" unq(cnonce-value)
+				//                              ":" unq(qop-value)
+				//                              ":" H(A2)
+				//                            ) <">
+				// if qop is missing,
+				// request-digest  = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">
+	
+				$unhashedDigest = '';
+				$nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
+				$cnonce = $nonce;
+				if ($digestRequest['qop'] != '') {
+					$unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
+				} else {
+					$unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
+				}
+	
+				$hashedDigest = md5($unhashedDigest);
+	
+				$this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"';
+			}
+		} elseif ($authtype == 'certificate') {
+			$this->certRequest = $certRequest;
+		}
+		$this->username = $username;
+		$this->password = $password;
+		$this->authtype = $authtype;
+		$this->digestRequest = $digestRequest;
+		
+		if (isset($this->outgoing_headers['Authorization'])) {
+			$this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...');
+		} else {
+			$this->debug('Authorization header not set');
+		}
+	}
+	
+	/**
+	* set the soapaction value
+	*
+	* @param    string $soapaction
+	* @access   public
+	*/
+	function setSOAPAction($soapaction) {
+		$this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"';
+		$this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']);
+	}
+	
+	/**
+	* use http encoding
+	*
+	* @param    string $enc encoding style. supported values: gzip, deflate, or both
+	* @access   public
+	*/
+	function setEncoding($enc='gzip, deflate') {
+		if (function_exists('gzdeflate')) {
+			$this->protocol_version = '1.1';
+			$this->outgoing_headers['Accept-Encoding'] = $enc;
+			$this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']);
+			if (!isset($this->outgoing_headers['Connection'])) {
+				$this->outgoing_headers['Connection'] = 'close';
+				$this->persistentConnection = false;
+				$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
+			}
+			set_magic_quotes_runtime(0);
+			// deprecated
+			$this->encoding = $enc;
+		}
+	}
+	
+	/**
+	* set proxy info here
+	*
+	* @param    string $proxyhost
+	* @param    string $proxyport
+	* @param	string $proxyusername
+	* @param	string $proxypassword
+	* @access   public
+	*/
+	function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
+		$this->uri = $this->url;
+		$this->host = $proxyhost;
+		$this->port = $proxyport;
+		if ($proxyusername != '' && $proxypassword != '') {
+			$this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword);
+			$this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']);
+		}
+	}
+	
+	/**
+	* decode a string that is encoded w/ "chunked' transfer encoding
+ 	* as defined in RFC2068 19.4.6
+	*
+	* @param    string $buffer
+	* @param    string $lb
+	* @returns	string
+	* @access   public
+	* @deprecated
+	*/
+	function decodeChunked($buffer, $lb){
+		// length := 0
+		$length = 0;
+		$new = '';
+		
+		// read chunk-size, chunk-extension (if any) and CRLF
+		// get the position of the linebreak
+		$chunkend = strpos($buffer, $lb);
+		if ($chunkend == FALSE) {
+			$this->debug('no linebreak found in decodeChunked');
+			return $new;
+		}
+		$temp = substr($buffer,0,$chunkend);
+		$chunk_size = hexdec( trim($temp) );
+		$chunkstart = $chunkend + strlen($lb);
+		// while (chunk-size > 0) {
+		while ($chunk_size > 0) {
+			$this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
+			$chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
+		  	
+			// Just in case we got a broken connection
+		  	if ($chunkend == FALSE) {
+		  	    $chunk = substr($buffer,$chunkstart);
+				// append chunk-data to entity-body
+		    	$new .= $chunk;
+		  	    $length += strlen($chunk);
+		  	    break;
+			}
+			
+		  	// read chunk-data and CRLF
+		  	$chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
+		  	// append chunk-data to entity-body
+		  	$new .= $chunk;
+		  	// length := length + chunk-size
+		  	$length += strlen($chunk);
+		  	// read chunk-size and CRLF
+		  	$chunkstart = $chunkend + strlen($lb);
+			
+		  	$chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
+			if ($chunkend == FALSE) {
+				break; //Just in case we got a broken connection
+			}
+			$temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
+			$chunk_size = hexdec( trim($temp) );
+			$chunkstart = $chunkend;
+		}
+		return $new;
+	}
+	
+	/*
+	 *	Writes payload, including HTTP headers, to $this->outgoing_payload.
+	 */
+	function buildPayload($data, $cookie_str = '') {
+		// add content-length header
+		$this->outgoing_headers['Content-Length'] = strlen($data);
+		$this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']);
+
+		// start building outgoing payload:
+		$req = "$this->request_method $this->uri HTTP/$this->protocol_version";
+		$this->debug("HTTP request: $req");
+		$this->outgoing_payload = "$req\r\n";
+
+		// loop thru headers, serializing
+		foreach($this->outgoing_headers as $k => $v){
+			$hdr = $k.': '.$v;
+			$this->debug("HTTP header: $hdr");
+			$this->outgoing_payload .= "$hdr\r\n";
+		}
+
+		// add any cookies
+		if ($cookie_str != '') {
+			$hdr = 'Cookie: '.$cookie_str;
+			$this->debug("HTTP header: $hdr");
+			$this->outgoing_payload .= "$hdr\r\n";
+		}
+
+		// header/body separator
+		$this->outgoing_payload .= "\r\n";
+		
+		// add data
+		$this->outgoing_payload .= $data;
+	}
+
+	function sendRequest($data, $cookies = NULL) {
+		// build cookie string
+		$cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
+
+		// build payload
+		$this->buildPayload($data, $cookie_str);
+
+	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+		// send payload
+		if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
+			$this->setError('couldn\'t write message data to socket');
+			$this->debug('couldn\'t write message data to socket');
+			return false;
+		}
+		$this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
+		return true;
+	  } else if ($this->scheme == 'https') {
+		// set payload
+		// TODO: cURL does say this should only be the verb, and in fact it
+		// turns out that the URI and HTTP version are appended to this, which
+		// some servers refuse to work with
+		//curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
+		foreach($this->outgoing_headers as $k => $v){
+			$curl_headers[] = "$k: $v";
+		}
+		if ($cookie_str != '') {
+			$curl_headers[] = 'Cookie: ' . $cookie_str;
+		}
+		curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers);
+		if ($this->request_method == "POST") {
+	  		curl_setopt($this->ch, CURLOPT_POST, 1);
+	  		curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
+	  	} else {
+	  	}
+		$this->debug('set cURL payload');
+		return true;
+	  }
+	}
+
+	function getResponse(){
+		$this->incoming_payload = '';
+	    
+	  if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+	    // loop until headers have been retrieved
+	    $data = '';
+	    while (!isset($lb)){
+
+			// We might EOF during header read.
+			if(feof($this->fp)) {
+				$this->incoming_payload = $data;
+				$this->debug('found no headers before EOF after length ' . strlen($data));
+				$this->debug("received before EOF:\n" . $data);
+				$this->setError('server failed to send headers');
+				return false;
+			}
+
+			$tmp = fgets($this->fp, 256);
+			$tmplen = strlen($tmp);
+			$this->debug("read line of $tmplen bytes: " . trim($tmp));
+
+			if ($tmplen == 0) {
+				$this->incoming_payload = $data;
+				$this->debug('socket read of headers timed out after length ' . strlen($data));
+				$this->debug("read before timeout: " . $data);
+				$this->setError('socket read of headers timed out');
+				return false;
+			}
+
+			$data .= $tmp;
+			$pos = strpos($data,"\r\n\r\n");
+			if($pos > 1){
+				$lb = "\r\n";
+			} else {
+				$pos = strpos($data,"\n\n");
+				if($pos > 1){
+					$lb = "\n";
+				}
+			}
+			// remove 100 header
+			if(isset($lb) && ereg('^HTTP/1.1 100',$data)){
+				unset($lb);
+				$data = '';
+			}//
+		}
+		// store header data
+		$this->incoming_payload .= $data;
+		$this->debug('found end of headers after length ' . strlen($data));
+		// process headers
+		$header_data = trim(substr($data,0,$pos));
+		$header_array = explode($lb,$header_data);
+		$this->incoming_headers = array();
+		$this->incoming_cookies = array();
+		foreach($header_array as $header_line){
+			$arr = explode(':',$header_line, 2);
+			if(count($arr) > 1){
+				$header_name = strtolower(trim($arr[0]));
+				$this->incoming_headers[$header_name] = trim($arr[1]);
+				if ($header_name == 'set-cookie') {
+					// TODO: allow multiple cookies from parseCookie
+					$cookie = $this->parseCookie(trim($arr[1]));
+					if ($cookie) {
+						$this->incoming_cookies[] = $cookie;
+						$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
+					} else {
+						$this->debug('did not find cookie in ' . trim($arr[1]));
+					}
+    			}
+			} else if (isset($header_name)) {
+				// append continuation line to previous header
+				$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
+			}
+		}
+		
+		// loop until msg has been received
+		if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
+			$content_length =  2147483647;	// ignore any content-length header
+			$chunked = true;
+			$this->debug("want to read chunked content");
+		} elseif (isset($this->incoming_headers['content-length'])) {
+			$content_length = $this->incoming_headers['content-length'];
+			$chunked = false;
+			$this->debug("want to read content of length $content_length");
+		} else {
+			$content_length =  2147483647;
+			$chunked = false;
+			$this->debug("want to read content to EOF");
+		}
+		$data = '';
+		do {
+			if ($chunked) {
+				$tmp = fgets($this->fp, 256);
+				$tmplen = strlen($tmp);
+				$this->debug("read chunk line of $tmplen bytes");
+				if ($tmplen == 0) {
+					$this->incoming_payload = $data;
+					$this->debug('socket read of chunk length timed out after length ' . strlen($data));
+					$this->debug("read before timeout:\n" . $data);
+					$this->setError('socket read of chunk length timed out');
+					return false;
+				}
+				$content_length = hexdec(trim($tmp));
+				$this->debug("chunk length $content_length");
+			}
+			$strlen = 0;
+		    while (($strlen < $content_length) && (!feof($this->fp))) {
+		    	$readlen = min(8192, $content_length - $strlen);
+				$tmp = fread($this->fp, $readlen);
+				$tmplen = strlen($tmp);
+				$this->debug("read buffer of $tmplen bytes");
+				if (($tmplen == 0) && (!feof($this->fp))) {
+					$this->incoming_payload = $data;
+					$this->debug('socket read of body timed out after length ' . strlen($data));
+					$this->debug("read before timeout:\n" . $data);
+					$this->setError('socket read of body timed out');
+					return false;
+				}
+				$strlen += $tmplen;
+				$data .= $tmp;
+			}
+			if ($chunked && ($content_length > 0)) {
+				$tmp = fgets($this->fp, 256);
+				$tmplen = strlen($tmp);
+				$this->debug("read chunk terminator of $tmplen bytes");
+				if ($tmplen == 0) {
+					$this->incoming_payload = $data;
+					$this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
+					$this->debug("read before timeout:\n" . $data);
+					$this->setError('socket read of chunk terminator timed out');
+					return false;
+				}
+			}
+		} while ($chunked && ($content_length > 0) && (!feof($this->fp)));
+		if (feof($this->fp)) {
+			$this->debug('read to EOF');
+		}
+		$this->debug('read body of length ' . strlen($data));
+		$this->incoming_payload .= $data;
+		$this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server');
+		
+		// close filepointer
+		if(
+			(isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || 
+			(! $this->persistentConnection) || feof($this->fp)){
+			fclose($this->fp);
+			$this->fp = false;
+			$this->debug('closed socket');
+		}
+		
+		// connection was closed unexpectedly
+		if($this->incoming_payload == ''){
+			$this->setError('no response from server');
+			return false;
+		}
+		
+		// decode transfer-encoding
+//		if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){
+//			if(!$data = $this->decodeChunked($data, $lb)){
+//				$this->setError('Decoding of chunked data failed');
+//				return false;
+//			}
+			//print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>";
+			// set decoded payload
+//			$this->incoming_payload = $header_data.$lb.$lb.$data;
+//		}
+	
+	  } else if ($this->scheme == 'https') {
+		// send and receive
+		$this->debug('send and receive with cURL');
+		$this->incoming_payload = curl_exec($this->ch);
+		$data = $this->incoming_payload;
+
+        $cErr = curl_error($this->ch);
+		if ($cErr != '') {
+        	$err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>';
+        	// TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE
+			foreach(curl_getinfo($this->ch) as $k => $v){
+				$err .= "$k: $v<br>";
+			}
+			$this->debug($err);
+			$this->setError($err);
+			curl_close($this->ch);
+	    	return false;
+		} else {
+			//echo '<pre>';
+			//var_dump(curl_getinfo($this->ch));
+			//echo '</pre>';
+		}
+		// close curl
+		$this->debug('No cURL error, closing cURL');
+		curl_close($this->ch);
+		
+		// remove 100 header(s)
+		while (ereg('^HTTP/1.1 100',$data)) {
+			if ($pos = strpos($data,"\r\n\r\n")) {
+				$data = ltrim(substr($data,$pos));
+			} elseif($pos = strpos($data,"\n\n") ) {
+				$data = ltrim(substr($data,$pos));
+			}
+		}
+		
+		// separate content from HTTP headers
+		if ($pos = strpos($data,"\r\n\r\n")) {
+			$lb = "\r\n";
+		} elseif( $pos = strpos($data,"\n\n")) {
+			$lb = "\n";
+		} else {
+			$this->debug('no proper separation of headers and document');
+			$this->setError('no proper separation of headers and document');
+			return false;
+		}
+		$header_data = trim(substr($data,0,$pos));
+		$header_array = explode($lb,$header_data);
+		$data = ltrim(substr($data,$pos));
+		$this->debug('found proper separation of headers and document');
+		$this->debug('cleaned data, stringlen: '.strlen($data));
+		// clean headers
+		foreach ($header_array as $header_line) {
+			$arr = explode(':',$header_line,2);
+			if(count($arr) > 1){
+				$header_name = strtolower(trim($arr[0]));
+				$this->incoming_headers[$header_name] = trim($arr[1]);
+				if ($header_name == 'set-cookie') {
+					// TODO: allow multiple cookies from parseCookie
+					$cookie = $this->parseCookie(trim($arr[1]));
+					if ($cookie) {
+						$this->incoming_cookies[] = $cookie;
+						$this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
+					} else {
+						$this->debug('did not find cookie in ' . trim($arr[1]));
+					}
+    			}
+			} else if (isset($header_name)) {
+				// append continuation line to previous header
+				$this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
+			}
+		}
+	  }
+
+		$arr = explode(' ', $header_array[0], 3);
+		$http_version = $arr[0];
+		$http_status = intval($arr[1]);
+		$http_reason = count($arr) > 2 ? $arr[2] : '';
+
+ 		// see if we need to resend the request with http digest authentication
+ 		if (isset($this->incoming_headers['location']) && $http_status == 301) {
+ 			$this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']);
+ 			$this->setURL($this->incoming_headers['location']);
+			$this->tryagain = true;
+			return false;
+		}
+
+ 		// see if we need to resend the request with http digest authentication
+ 		if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
+ 			$this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
+ 			if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
+ 				$this->debug('Server wants digest authentication');
+ 				// remove "Digest " from our elements
+ 				$digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
+ 				
+ 				// parse elements into array
+ 				$digestElements = explode(',', $digestString);
+ 				foreach ($digestElements as $val) {
+ 					$tempElement = explode('=', trim($val), 2);
+ 					$digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
+ 				}
+
+				// should have (at least) qop, realm, nonce
+ 				if (isset($digestRequest['nonce'])) {
+ 					$this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
+ 					$this->tryagain = true;
+ 					return false;
+ 				}
+ 			}
+			$this->debug('HTTP authentication failed');
+			$this->setError('HTTP authentication failed');
+			return false;
+ 		}
+		
+		if (
+			($http_status >= 300 && $http_status <= 307) ||
+			($http_status >= 400 && $http_status <= 417) ||
+			($http_status >= 501 && $http_status <= 505)
+		   ) {
+			$this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient_nusoap->response has contents of the response)");
+			return false;
+		}
+
+		// decode content-encoding
+		if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){
+			if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){
+    			// if decoding works, use it. else assume data wasn't gzencoded
+    			if(function_exists('gzinflate')){
+					//$timer->setMarker('starting decoding of gzip/deflated content');
+					// IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress)
+					// this means there are no Zlib headers, although there should be
+					$this->debug('The gzinflate function exists');
+					$datalen = strlen($data);
+					if ($this->incoming_headers['content-encoding'] == 'deflate') {
+						if ($degzdata = @gzinflate($data)) {
+	    					$data = $degzdata;
+	    					$this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
+	    					if (strlen($data) < $datalen) {
+	    						// test for the case that the payload has been compressed twice
+		    					$this->debug('The inflated payload is smaller than the gzipped one; try again');
+								if ($degzdata = @gzinflate($data)) {
+			    					$data = $degzdata;
+			    					$this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
+								}
+	    					}
+	    				} else {
+	    					$this->debug('Error using gzinflate to inflate the payload');
+	    					$this->setError('Error using gzinflate to inflate the payload');
+	    				}
+					} elseif ($this->incoming_headers['content-encoding'] == 'gzip') {
+						if ($degzdata = @gzinflate(substr($data, 10))) {	// do our best
+							$data = $degzdata;
+	    					$this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
+	    					if (strlen($data) < $datalen) {
+	    						// test for the case that the payload has been compressed twice
+		    					$this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
+								if ($degzdata = @gzinflate(substr($data, 10))) {
+			    					$data = $degzdata;
+			    					$this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
+								}
+	    					}
+	    				} else {
+	    					$this->debug('Error using gzinflate to un-gzip the payload');
+							$this->setError('Error using gzinflate to un-gzip the payload');
+	    				}
+					}
+					//$timer->setMarker('finished decoding of gzip/deflated content');
+					//print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>";
+					// set decoded payload
+					$this->incoming_payload = $header_data.$lb.$lb.$data;
+    			} else {
+					$this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
+					$this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
+				}
+			} else {
+				$this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
+				$this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
+			}
+		} else {
+			$this->debug('No Content-Encoding header');
+		}
+		
+		if(strlen($data) == 0){
+			$this->debug('no data after headers!');
+			$this->setError('no data present after HTTP headers');
+			return false;
+		}
+		
+		return $data;
+	}
+
+	function setContentType($type, $charset = false) {
+		$this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : '');
+		$this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']);
+	}
+
+	function usePersistentConnection(){
+		if (isset($this->outgoing_headers['Accept-Encoding'])) {
+			return false;
+		}
+		$this->protocol_version = '1.1';
+		$this->persistentConnection = true;
+		$this->outgoing_headers['Connection'] = 'Keep-Alive';
+		$this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
+		return true;
+	}
+
+	/**
+	 * parse an incoming Cookie into it's parts
+	 *
+	 * @param	string $cookie_str content of cookie
+	 * @return	array with data of that cookie
+	 * @access	private
+	 */
+	/*
+	 * TODO: allow a Set-Cookie string to be parsed into multiple cookies
+	 */
+	function parseCookie($cookie_str) {
+		$cookie_str = str_replace('; ', ';', $cookie_str) . ';';
+		$data = split(';', $cookie_str);
+		$value_str = $data[0];
+
+		$cookie_param = 'domain=';
+		$start = strpos($cookie_str, $cookie_param);
+		if ($start > 0) {
+			$domain = substr($cookie_str, $start + strlen($cookie_param));
+			$domain = substr($domain, 0, strpos($domain, ';'));
+		} else {
+			$domain = '';
+		}
+
+		$cookie_param = 'expires=';
+		$start = strpos($cookie_str, $cookie_param);
+		if ($start > 0) {
+			$expires = substr($cookie_str, $start + strlen($cookie_param));
+			$expires = substr($expires, 0, strpos($expires, ';'));
+		} else {
+			$expires = '';
+		}
+
+		$cookie_param = 'path=';
+		$start = strpos($cookie_str, $cookie_param);
+		if ( $start > 0 ) {
+			$path = substr($cookie_str, $start + strlen($cookie_param));
+			$path = substr($path, 0, strpos($path, ';'));
+		} else {
+			$path = '/';
+		}
+						
+		$cookie_param = ';secure;';
+		if (strpos($cookie_str, $cookie_param) !== FALSE) {
+			$secure = true;
+		} else {
+			$secure = false;
+		}
+
+		$sep_pos = strpos($value_str, '=');
+
+		if ($sep_pos) {
+			$name = substr($value_str, 0, $sep_pos);
+			$value = substr($value_str, $sep_pos + 1);
+			$cookie= array(	'name' => $name,
+			                'value' => $value,
+							'domain' => $domain,
+							'path' => $path,
+							'expires' => $expires,
+							'secure' => $secure
+							);		
+			return $cookie;
+		}
+		return false;
+	}
+  
+	/**
+	 * sort out cookies for the current request
+	 *
+	 * @param	array $cookies array with all cookies
+	 * @param	boolean $secure is the send-content secure or not?
+	 * @return	string for Cookie-HTTP-Header
+	 * @access	private
+	 */
+	function getCookiesForRequest($cookies, $secure=false) {
+		$cookie_str = '';
+		if ((! is_null($cookies)) && (is_array($cookies))) {
+			foreach ($cookies as $cookie) {
+				if (! is_array($cookie)) {
+					continue;
+				}
+	    		$this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']);
+				if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
+					if (strtotime($cookie['expires']) <= time()) {
+						$this->debug('cookie has expired');
+						continue;
+					}
+				}
+				if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) {
+					$domain = preg_quote($cookie['domain']);
+					if (! preg_match("'.*$domain$'i", $this->host)) {
+						$this->debug('cookie has different domain');
+						continue;
+					}
+				}
+				if ((isset($cookie['path'])) && (! empty($cookie['path']))) {
+					$path = preg_quote($cookie['path']);
+					if (! preg_match("'^$path.*'i", $this->path)) {
+						$this->debug('cookie is for a different path');
+						continue;
+					}
+				}
+				if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
+					$this->debug('cookie is secure, transport is not');
+					continue;
+				}
+				$cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
+	    		$this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
+			}
+		}
+		return $cookie_str;
+  }
+}
+
+?><?php
+
+
+
+/**
+*
+* soap_server allows the user to create a SOAP server
+* that is capable of receiving messages and returning responses
+*
+* NOTE: WSDL functionality is experimental
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class soap_server extends nusoap_base {
+	/**
+	 * HTTP headers of request
+	 * @var array
+	 * @access private
+	 */
+	var $headers = array();
+	/**
+	 * HTTP request
+	 * @var string
+	 * @access private
+	 */
+	var $request = '';
+	/**
+	 * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text)
+	 * @var string
+	 * @access public
+	 */
+	var $requestHeaders = '';
+	/**
+	 * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text)
+	 * @var string
+	 * @access public
+	 */
+	var $document = '';
+	/**
+	 * SOAP payload for request (text)
+	 * @var string
+	 * @access public
+	 */
+	var $requestSOAP = '';
+	/**
+	 * requested method namespace URI
+	 * @var string
+	 * @access private
+	 */
+	var $methodURI = '';
+	/**
+	 * name of method requested
+	 * @var string
+	 * @access private
+	 */
+	var $methodname = '';
+	/**
+	 * method parameters from request
+	 * @var array
+	 * @access private
+	 */
+	var $methodparams = array();
+	/**
+	 * SOAP Action from request
+	 * @var string
+	 * @access private
+	 */
+	var $SOAPAction = '';
+	/**
+	 * character set encoding of incoming (request) messages
+	 * @var string
+	 * @access public
+	 */
+	var $xml_encoding = '';
+	/**
+	 * toggles whether the parser decodes element content w/ utf8_decode()
+	 * @var boolean
+	 * @access public
+	 */
+    var $decode_utf8 = true;
+
+	/**
+	 * HTTP headers of response
+	 * @var array
+	 * @access public
+	 */
+	var $outgoing_headers = array();
+	/**
+	 * HTTP response
+	 * @var string
+	 * @access private
+	 */
+	var $response = '';
+	/**
+	 * SOAP headers for response (text)
+	 * @var string
+	 * @access public
+	 */
+	var $responseHeaders = '';
+	/**
+	 * SOAP payload for response (text)
+	 * @var string
+	 * @access private
+	 */
+	var $responseSOAP = '';
+	/**
+	 * method return value to place in response
+	 * @var mixed
+	 * @access private
+	 */
+	var $methodreturn = false;
+	/**
+	 * whether $methodreturn is a string of literal XML
+	 * @var boolean
+	 * @access public
+	 */
+	var $methodreturnisliteralxml = false;
+	/**
+	 * SOAP fault for response (or false)
+	 * @var mixed
+	 * @access private
+	 */
+	var $fault = false;
+	/**
+	 * text indication of result (for debugging)
+	 * @var string
+	 * @access private
+	 */
+	var $result = 'successful';
+
+	/**
+	 * assoc array of operations => opData; operations are added by the register()
+	 * method or by parsing an external WSDL definition
+	 * @var array
+	 * @access private
+	 */
+	var $operations = array();
+	/**
+	 * wsdl instance (if one)
+	 * @var mixed
+	 * @access private
+	 */
+	var $wsdl = false;
+	/**
+	 * URL for WSDL (if one)
+	 * @var mixed
+	 * @access private
+	 */
+	var $externalWSDLURL = false;
+	/**
+	 * whether to append debug to response as XML comment
+	 * @var boolean
+	 * @access public
+	 */
+	var $debug_flag = false;
+
+
+	/**
+	* constructor
+    * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to.
+	*
+    * @param mixed $wsdl file path or URL (string), or wsdl instance (object)
+	* @access   public
+	*/
+	function soap_server($wsdl=false){
+		parent::nusoap_base();
+		// turn on debugging?
+		global $debug;
+		global $HTTP_SERVER_VARS;
+
+		if (isset($_SERVER)) {
+			$this->debug("_SERVER is defined:");
+			$this->appendDebug($this->varDump($_SERVER));
+		} elseif (isset($HTTP_SERVER_VARS)) {
+			$this->debug("HTTP_SERVER_VARS is defined:");
+			$this->appendDebug($this->varDump($HTTP_SERVER_VARS));
+		} else {
+			$this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
+		}
+
+		if (isset($debug)) {
+			$this->debug("In soap_server, set debug_flag=$debug based on global flag");
+			$this->debug_flag = $debug;
+		} elseif (isset($_SERVER['QUERY_STRING'])) {
+			$qs = explode('&', $_SERVER['QUERY_STRING']);
+			foreach ($qs as $v) {
+				if (substr($v, 0, 6) == 'debug=') {
+					$this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
+					$this->debug_flag = substr($v, 6);
+				}
+			}
+		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
+			$qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
+			foreach ($qs as $v) {
+				if (substr($v, 0, 6) == 'debug=') {
+					$this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
+					$this->debug_flag = substr($v, 6);
+				}
+			}
+		}
+
+		// wsdl
+		if($wsdl){
+			$this->debug("In soap_server, WSDL is specified");
+			if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
+				$this->wsdl = $wsdl;
+				$this->externalWSDLURL = $this->wsdl->wsdl;
+				$this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
+			} else {
+				$this->debug('Create wsdl from ' . $wsdl);
+				$this->wsdl = new wsdl($wsdl);
+				$this->externalWSDLURL = $wsdl;
+			}
+			$this->appendDebug($this->wsdl->getDebug());
+			$this->wsdl->clearDebug();
+			if($err = $this->wsdl->getError()){
+				die('WSDL ERROR: '.$err);
+			}
+		}
+	}
+
+	/**
+	* processes request and returns response
+	*
+	* @param    string $data usually is the value of $HTTP_RAW_POST_DATA
+	* @access   public
+	*/
+	function service($data){
+		global $HTTP_SERVER_VARS;
+
+		if (isset($_SERVER['QUERY_STRING'])) {
+			$qs = $_SERVER['QUERY_STRING'];
+		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
+			$qs = $HTTP_SERVER_VARS['QUERY_STRING'];
+		} else {
+			$qs = '';
+		}
+		$this->debug("In service, query string=$qs");
+
+		if (ereg('wsdl', $qs) ){
+			$this->debug("In service, this is a request for WSDL");
+			if($this->externalWSDLURL){
+              if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL
+				header('Location: '.$this->externalWSDLURL);
+              } else { // assume file
+                header("Content-Type: text/xml\r\n");
+                $fp = fopen($this->externalWSDLURL, 'r');
+                fpassthru($fp);
+              }
+			} elseif ($this->wsdl) {
+				header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
+				print $this->wsdl->serialize($this->debug_flag);
+				if ($this->debug_flag) {
+					$this->debug('wsdl:');
+					$this->appendDebug($this->varDump($this->wsdl));
+					print $this->getDebugAsXMLComment();
+				}
+			} else {
+				header("Content-Type: text/html; charset=ISO-8859-1\r\n");
+				print "This service does not provide WSDL";
+			}
+		} elseif ($data == '' && $this->wsdl) {
+			$this->debug("In service, there is no data, so return Web description");
+			print $this->wsdl->webDescription();
+		} else {
+			$this->debug("In service, invoke the request");
+			$this->parse_request($data);
+			if (! $this->fault) {
+				$this->invoke_method();
+			}
+			if (! $this->fault) {
+				$this->serialize_return();
+			}
+			$this->send_response();
+		}
+	}
+
+	/**
+	* parses HTTP request headers.
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* headers
+	* request
+	* xml_encoding
+	* SOAPAction
+	*
+	* @access   private
+	*/
+	function parse_http_headers() {
+		global $HTTP_SERVER_VARS;
+
+		$this->request = '';
+		$this->SOAPAction = '';
+		if(function_exists('getallheaders')){
+			$this->debug("In parse_http_headers, use getallheaders");
+			$headers = getallheaders();
+			foreach($headers as $k=>$v){
+				$k = strtolower($k);
+				$this->headers[$k] = $v;
+				$this->request .= "$k: $v\r\n";
+				$this->debug("$k: $v");
+			}
+			// get SOAPAction header
+			if(isset($this->headers['soapaction'])){
+				$this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
+			}
+			// get the character encoding of the incoming request
+			if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
+				$enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
+				if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
+					$this->xml_encoding = strtoupper($enc);
+				} else {
+					$this->xml_encoding = 'US-ASCII';
+				}
+			} else {
+				// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+				$this->xml_encoding = 'ISO-8859-1';
+			}
+		} elseif(isset($_SERVER) && is_array($_SERVER)){
+			$this->debug("In parse_http_headers, use _SERVER");
+			foreach ($_SERVER as $k => $v) {
+				if (substr($k, 0, 5) == 'HTTP_') {
+					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
+				} else {
+					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
+				}
+				if ($k == 'soapaction') {
+					// get SOAPAction header
+					$k = 'SOAPAction';
+					$v = str_replace('"', '', $v);
+					$v = str_replace('\\', '', $v);
+					$this->SOAPAction = $v;
+				} else if ($k == 'content-type') {
+					// get the character encoding of the incoming request
+					if (strpos($v, '=')) {
+						$enc = substr(strstr($v, '='), 1);
+						$enc = str_replace('"', '', $enc);
+						$enc = str_replace('\\', '', $enc);
+						if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
+							$this->xml_encoding = strtoupper($enc);
+						} else {
+							$this->xml_encoding = 'US-ASCII';
+						}
+					} else {
+						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+						$this->xml_encoding = 'ISO-8859-1';
+					}
+				}
+				$this->headers[$k] = $v;
+				$this->request .= "$k: $v\r\n";
+				$this->debug("$k: $v");
+			}
+		} elseif (is_array($HTTP_SERVER_VARS)) {
+			$this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
+			foreach ($HTTP_SERVER_VARS as $k => $v) {
+				if (substr($k, 0, 5) == 'HTTP_') {
+					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
+				} else {
+					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
+				}
+				if ($k == 'soapaction') {
+					// get SOAPAction header
+					$k = 'SOAPAction';
+					$v = str_replace('"', '', $v);
+					$v = str_replace('\\', '', $v);
+					$this->SOAPAction = $v;
+				} else if ($k == 'content-type') {
+					// get the character encoding of the incoming request
+					if (strpos($v, '=')) {
+						$enc = substr(strstr($v, '='), 1);
+						$enc = str_replace('"', '', $enc);
+						$enc = str_replace('\\', '', $enc);
+						if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
+							$this->xml_encoding = strtoupper($enc);
+						} else {
+							$this->xml_encoding = 'US-ASCII';
+						}
+					} else {
+						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+						$this->xml_encoding = 'ISO-8859-1';
+					}
+				}
+				$this->headers[$k] = $v;
+				$this->request .= "$k: $v\r\n";
+				$this->debug("$k: $v");
+			}
+		} else {
+			$this->debug("In parse_http_headers, HTTP headers not accessible");
+			$this->setError("HTTP headers not accessible");
+		}
+	}
+
+	/**
+	* parses a request
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* headers
+	* request
+	* xml_encoding
+	* SOAPAction
+	* request
+	* requestSOAP
+	* methodURI
+	* methodname
+	* methodparams
+	* requestHeaders
+	* document
+	*
+	* This sets the fault field on error
+	*
+	* @param    string $data XML string
+	* @access   private
+	*/
+	function parse_request($data='') {
+		$this->debug('entering parse_request()');
+		$this->parse_http_headers();
+		$this->debug('got character encoding: '.$this->xml_encoding);
+		// uncompress if necessary
+		if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
+			$this->debug('got content encoding: ' . $this->headers['content-encoding']);
+			if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
+		    	// if decoding works, use it. else assume data wasn't gzencoded
+				if (function_exists('gzuncompress')) {
+					if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
+						$data = $degzdata;
+					} elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
+						$data = $degzdata;
+					} else {
+						$this->fault('Client', 'Errors occurred when trying to decode the data');
+						return;
+					}
+				} else {
+					$this->fault('Client', 'This Server does not support compressed data');
+					return;
+				}
+			}
+		}
+		$this->request .= "\r\n".$data;
+		$data = $this->parseRequest($this->headers, $data);
+		$this->requestSOAP = $data;
+		$this->debug('leaving parse_request');
+	}
+
+	/**
+	* invokes a PHP function for the requested SOAP method
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* methodreturn
+	*
+	* Note that the PHP function that is called may also set the following
+	* fields to affect the response sent to the client
+	*
+	* responseHeaders
+	* outgoing_headers
+	*
+	* This sets the fault field on error
+	*
+	* @access   private
+	*/
+	function invoke_method() {
+		$this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
+
+		if ($this->wsdl) {
+			if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
+				$this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
+				$this->appendDebug('opData=' . $this->varDump($this->opData));
+			} elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
+				// Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
+				$this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
+				$this->appendDebug('opData=' . $this->varDump($this->opData));
+				$this->methodname = $this->opData['name'];
+			} else {
+				$this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
+				$this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
+				return;
+			}
+		} else {
+			$this->debug('in invoke_method, no WSDL to validate method');
+		}
+
+		// if a . is present in $this->methodname, we see if there is a class in scope,
+		// which could be referred to. We will also distinguish between two deliminators,
+		// to allow methods to be called a the class or an instance
+		$class = '';
+		$method = '';
+		if (strpos($this->methodname, '..') > 0) {
+			$delim = '..';
+		} else if (strpos($this->methodname, '.') > 0) {
+			$delim = '.';
+		} else {
+			$delim = '';
+		}
+
+		if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
+			class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
+			// get the class and method name
+			$class = substr($this->methodname, 0, strpos($this->methodname, $delim));
+			$method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
+			$this->debug("in invoke_method, class=$class method=$method delim=$delim");
+		}
+
+		// does method exist?
+		if ($class == '') {
+			if (!function_exists($this->methodname)) {
+				$this->debug("in invoke_method, function '$this->methodname' not found!");
+				$this->result = 'fault: method not found';
+				$this->fault('Client',"method '$this->methodname' not defined in service");
+				return;
+			}
+		} else {
+			$method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
+			if (!in_array($method_to_compare, get_class_methods($class))) {
+				$this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
+				$this->result = 'fault: method not found';
+				$this->fault('Client',"method '$this->methodname' not defined in service");
+				return;
+			}
+		}
+
+		// evaluate message, getting back parameters
+		// verify that request parameters match the method's signature
+		if(! $this->verify_method($this->methodname,$this->methodparams)){
+			// debug
+			$this->debug('ERROR: request not verified against method signature');
+			$this->result = 'fault: request failed validation against method signature';
+			// return fault
+			$this->fault('Client',"Operation '$this->methodname' not defined in service.");
+			return;
+		}
+
+		// if there are parameters to pass
+		$this->debug('in invoke_method, params:');
+		$this->appendDebug($this->varDump($this->methodparams));
+		$this->debug("in invoke_method, calling '$this->methodname'");
+		if (!function_exists('call_user_func_array')) {
+			if ($class == '') {
+				$this->debug('in invoke_method, calling function using eval()');
+				$funcCall = "\$this->methodreturn = $this->methodname(";
+			} else {
+				if ($delim == '..') {
+					$this->debug('in invoke_method, calling class method using eval()');
+					$funcCall = "\$this->methodreturn = ".$class."::".$method."(";
+				} else {
+					$this->debug('in invoke_method, calling instance method using eval()');
+					// generate unique instance name
+					$instname = "\$inst_".time();
+					$funcCall = $instname." = new ".$class."(); ";
+					$funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
+				}
+			}
+			if ($this->methodparams) {
+				foreach ($this->methodparams as $param) {
+					if (is_array($param)) {
+						$this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
+						return;
+					}
+					$funcCall .= "\"$param\",";
+				}
+				$funcCall = substr($funcCall, 0, -1);
+			}
+			$funcCall .= ');';
+			$this->debug('in invoke_method, function call: '.$funcCall);
+			@eval($funcCall);
+		} else {
+			if ($class == '') {
+				$this->debug('in invoke_method, calling function using call_user_func_array()');
+				$call_arg = "$this->methodname";	// straight assignment changes $this->methodname to lower case after call_user_func_array()
+			} elseif ($delim == '..') {
+				$this->debug('in invoke_method, calling class method using call_user_func_array()');
+				$call_arg = array ($class, $method);
+			} else {
+				$this->debug('in invoke_method, calling instance method using call_user_func_array()');
+				$instance = new $class ();
+				$call_arg = array(&$instance, $method);
+			}
+			$this->methodreturn = call_user_func_array($call_arg, $this->methodparams);
+		}
+        $this->debug('in invoke_method, methodreturn:');
+        $this->appendDebug($this->varDump($this->methodreturn));
+		$this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn));
+	}
+
+	/**
+	* serializes the return value from a PHP function into a full SOAP Envelope
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* responseSOAP
+	*
+	* This sets the fault field on error
+	*
+	* @access   private
+	*/
+	function serialize_return() {
+		$this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
+		// if fault
+		if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) {
+			$this->debug('got a fault object from method');
+			$this->fault = $this->methodreturn;
+			return;
+		} elseif ($this->methodreturnisliteralxml) {
+			$return_val = $this->methodreturn;
+		// returned value(s)
+		} else {
+			$this->debug('got a(n) '.gettype($this->methodreturn).' from method');
+			$this->debug('serializing return value');
+			if($this->wsdl){
+				// weak attempt at supporting multiple output params
+				if(sizeof($this->opData['output']['parts']) > 1){
+			    	$opParams = $this->methodreturn;
+			    } else {
+			    	// TODO: is this really necessary?
+			    	$opParams = array($this->methodreturn);
+			    }
+			    $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
+			    $this->appendDebug($this->wsdl->getDebug());
+			    $this->wsdl->clearDebug();
+				if($errstr = $this->wsdl->getError()){
+					$this->debug('got wsdl error: '.$errstr);
+					$this->fault('Server', 'unable to serialize result');
+					return;
+				}
+			} else {
+				if (isset($this->methodreturn)) {
+					$return_val = $this->serialize_val($this->methodreturn, 'return');
+				} else {
+					$return_val = '';
+					$this->debug('in absence of WSDL, assume void return for backward compatibility');
+				}
+			}
+		}
+		$this->debug('return value:');
+		$this->appendDebug($this->varDump($return_val));
+
+		$this->debug('serializing response');
+		if ($this->wsdl) {
+			$this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
+			if ($this->opData['style'] == 'rpc') {
+				$this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
+				if ($this->opData['output']['use'] == 'literal') {
+					$payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>";
+				} else {
+					$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
+				}
+			} else {
+				$this->debug('style is not rpc for serialization: assume document');
+				$payload = $return_val;
+			}
+		} else {
+			$this->debug('do not have WSDL for serialization: assume rpc/encoded');
+			$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
+		}
+		$this->result = 'successful';
+		if($this->wsdl){
+			//if($this->debug_flag){
+            	$this->appendDebug($this->wsdl->getDebug());
+            //	}
+			if (isset($opData['output']['encodingStyle'])) {
+				$encodingStyle = $opData['output']['encodingStyle'];
+			} else {
+				$encodingStyle = '';
+			}
+			// Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
+			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle);
+		} else {
+			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
+		}
+		$this->debug("Leaving serialize_return");
+	}
+
+	/**
+	* sends an HTTP response
+	*
+	* The following fields are set by this function (when successful)
+	*
+	* outgoing_headers
+	* response
+	*
+	* @access   private
+	*/
+	function send_response() {
+		$this->debug('Enter send_response');
+		if ($this->fault) {
+			$payload = $this->fault->serialize();
+			$this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
+			$this->outgoing_headers[] = "Status: 500 Internal Server Error";
+		} else {
+			$payload = $this->responseSOAP;
+			// Some combinations of PHP+Web server allow the Status
+			// to come through as a header.  Since OK is the default
+			// just do nothing.
+			// $this->outgoing_headers[] = "HTTP/1.0 200 OK";
+			// $this->outgoing_headers[] = "Status: 200 OK";
+		}
+        // add debug data if in debug mode
+		if(isset($this->debug_flag) && $this->debug_flag){
+        	$payload .= $this->getDebugAsXMLComment();
+        }
+		$this->outgoing_headers[] = "Server: $this->title Server v$this->version";
+		ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
+		$this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
+		// Let the Web server decide about this
+		//$this->outgoing_headers[] = "Connection: Close\r\n";
+		$payload = $this->getHTTPBody($payload);
+		$type = $this->getHTTPContentType();
+		$charset = $this->getHTTPContentTypeCharset();
+		$this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
+		//begin code to compress payload - by John
+		// NOTE: there is no way to know whether the Web server will also compress
+		// this data.
+		if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {	
+			if (strstr($this->headers['accept-encoding'], 'gzip')) {
+				if (function_exists('gzencode')) {
+					if (isset($this->debug_flag) && $this->debug_flag) {
+						$payload .= "<!-- Content being gzipped -->";
+					}
+					$this->outgoing_headers[] = "Content-Encoding: gzip";
+					$payload = gzencode($payload);
+				} else {
+					if (isset($this->debug_flag) && $this->debug_flag) {
+						$payload .= "<!-- Content will not be gzipped: no gzencode -->";
+					}
+				}
+			} elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
+				// Note: MSIE requires gzdeflate output (no Zlib header and checksum),
+				// instead of gzcompress output,
+				// which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
+				if (function_exists('gzdeflate')) {
+					if (isset($this->debug_flag) && $this->debug_flag) {
+						$payload .= "<!-- Content being deflated -->";
+					}
+					$this->outgoing_headers[] = "Content-Encoding: deflate";
+					$payload = gzdeflate($payload);
+				} else {
+					if (isset($this->debug_flag) && $this->debug_flag) {
+						$payload .= "<!-- Content will not be deflated: no gzcompress -->";
+					}
+				}
+			}
+		}
+		//end code
+		$this->outgoing_headers[] = "Content-Length: ".strlen($payload);
+		reset($this->outgoing_headers);
+		foreach($this->outgoing_headers as $hdr){
+			header($hdr, false);
+		}
+		print $payload;
+		$this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
+	}
+
+	/**
+	* takes the value that was created by parsing the request
+	* and compares to the method's signature, if available.
+	*
+	* @param	string	$operation	The operation to be invoked
+	* @param	array	$request	The array of parameter values
+	* @return	boolean	Whether the operation was found
+	* @access   private
+	*/
+	function verify_method($operation,$request){
+		if(isset($this->wsdl) && is_object($this->wsdl)){
+			if($this->wsdl->getOperationData($operation)){
+				return true;
+			}
+	    } elseif(isset($this->operations[$operation])){
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	* processes SOAP message received from client
+	*
+	* @param	array	$headers	The HTTP headers
+	* @param	string	$data		unprocessed request data from client
+	* @return	mixed	value of the message, decoded into a PHP type
+	* @access   private
+	*/
+    function parseRequest($headers, $data) {
+		$this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
+		if (!strstr($headers['content-type'], 'text/xml')) {
+			$this->setError('Request not of type text/xml');
+			return false;
+		}
+		if (strpos($headers['content-type'], '=')) {
+			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
+			$this->debug('Got response encoding: ' . $enc);
+			if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
+				$this->xml_encoding = strtoupper($enc);
+			} else {
+				$this->xml_encoding = 'US-ASCII';
+			}
+		} else {
+			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+			$this->xml_encoding = 'ISO-8859-1';
+		}
+		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
+		// parse response, get soap parser obj
+		$parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
+		// parser debug
+		$this->debug("parser debug: \n".$parser->getDebug());
+		// if fault occurred during message parsing
+		if($err = $parser->getError()){
+			$this->result = 'fault: error in msg parsing: '.$err;
+			$this->fault('Client',"error in msg parsing:\n".$err);
+		// else successfully parsed request into soapval object
+		} else {
+			// get/set methodname
+			$this->methodURI = $parser->root_struct_namespace;
+			$this->methodname = $parser->root_struct_name;
+			$this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
+			$this->debug('calling parser->get_response()');
+			$this->methodparams = $parser->get_response();
+			// get SOAP headers
+			$this->requestHeaders = $parser->getHeaders();
+            // add document for doclit support
+            $this->document = $parser->document;
+		}
+	 }
+
+	/**
+	* gets the HTTP body for the current response.
+	*
+	* @param string $soapmsg The SOAP payload
+	* @return string The HTTP body, which includes the SOAP payload
+	* @access private
+	*/
+	function getHTTPBody($soapmsg) {
+		return $soapmsg;
+	}
+	
+	/**
+	* gets the HTTP content type for the current response.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type for the current response.
+	* @access private
+	*/
+	function getHTTPContentType() {
+		return 'text/xml';
+	}
+	
+	/**
+	* gets the HTTP content type charset for the current response.
+	* returns false for non-text content types.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type charset for the current response.
+	* @access private
+	*/
+	function getHTTPContentTypeCharset() {
+		return $this->soap_defencoding;
+	}
+
+	/**
+	* add a method to the dispatch map (this has been replaced by the register method)
+	*
+	* @param    string $methodname
+	* @param    string $in array of input values
+	* @param    string $out array of output values
+	* @access   public
+	* @deprecated
+	*/
+	function add_to_map($methodname,$in,$out){
+			$this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
+	}
+
+	/**
+	* register a service function with the server
+	*
+	* @param    string $name the name of the PHP function, class.method or class..method
+	* @param    array $in assoc array of input values: key = param name, value = param type
+	* @param    array $out assoc array of output values: key = param name, value = param type
+	* @param	mixed $namespace the element namespace for the method or false
+	* @param	mixed $soapaction the soapaction for the method or false
+	* @param	mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically
+	* @param	mixed $use optional (encoded|literal) or false
+	* @param	string $documentation optional Description to include in WSDL
+	* @param	string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
+	* @access   public
+	*/
+	function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
+		global $HTTP_SERVER_VARS;
+
+		if($this->externalWSDLURL){
+			die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
+		}
+		if (! $name) {
+			die('You must specify a name when you register an operation');
+		}
+		if (!is_array($in)) {
+			die('You must provide an array for operation inputs');
+		}
+		if (!is_array($out)) {
+			die('You must provide an array for operation outputs');
+		}
+		if(false == $namespace) {
+		}
+		if(false == $soapaction) {
+			if (isset($_SERVER)) {
+				$SERVER_NAME = $_SERVER['SERVER_NAME'];
+				$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
+			} elseif (isset($HTTP_SERVER_VARS)) {
+				$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
+				$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
+			} else {
+				$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
+			}
+			$soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name";
+		}
+		if(false == $style) {
+			$style = "rpc";
+		}
+		if(false == $use) {
+			$use = "encoded";
+		}
+		if ($use == 'encoded' && $encodingStyle = '') {
+			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+		}
+
+		$this->operations[$name] = array(
+	    'name' => $name,
+	    'in' => $in,
+	    'out' => $out,
+	    'namespace' => $namespace,
+	    'soapaction' => $soapaction,
+	    'style' => $style);
+        if($this->wsdl){
+        	$this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
+	    }
+		return true;
+	}
+
+	/**
+	* Specify a fault to be returned to the client.
+	* This also acts as a flag to the server that a fault has occured.
+	*
+	* @param	string $faultcode
+	* @param	string $faultstring
+	* @param	string $faultactor
+	* @param	string $faultdetail
+	* @access   public
+	*/
+	function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
+		if ($faultdetail == '' && $this->debug_flag) {
+			$faultdetail = $this->getDebug();
+		}
+		$this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
+		$this->fault->soap_defencoding = $this->soap_defencoding;
+	}
+
+    /**
+    * Sets up wsdl object.
+    * Acts as a flag to enable internal WSDL generation
+    *
+    * @param string $serviceName, name of the service
+    * @param mixed $namespace optional 'tns' service namespace or false
+    * @param mixed $endpoint optional URL of service endpoint or false
+    * @param string $style optional (rpc|document) WSDL style (also specified by operation)
+    * @param string $transport optional SOAP transport
+    * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false
+    */
+    function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
+    {
+    	global $HTTP_SERVER_VARS;
+
+		if (isset($_SERVER)) {
+			$SERVER_NAME = $_SERVER['SERVER_NAME'];
+			$SERVER_PORT = $_SERVER['SERVER_PORT'];
+			$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
+			$HTTPS = $_SERVER['HTTPS'];
+		} elseif (isset($HTTP_SERVER_VARS)) {
+			$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
+			$SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
+			$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
+			$HTTPS = $HTTP_SERVER_VARS['HTTPS'];
+		} else {
+			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
+		}
+		if ($SERVER_PORT == 80) {
+			$SERVER_PORT = '';
+		} else {
+			$SERVER_PORT = ':' . $SERVER_PORT;
+		}
+        if(false == $namespace) {
+            $namespace = "http://$SERVER_NAME/soap/$serviceName";
+        }
+        
+        if(false == $endpoint) {
+        	if ($HTTPS == '1' || $HTTPS == 'on') {
+        		$SCHEME = 'https';
+        	} else {
+        		$SCHEME = 'http';
+        	}
+            $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
+        }
+        
+        if(false == $schemaTargetNamespace) {
+            $schemaTargetNamespace = $namespace;
+        }
+        
+		$this->wsdl = new wsdl;
+		$this->wsdl->serviceName = $serviceName;
+        $this->wsdl->endpoint = $endpoint;
+		$this->wsdl->namespaces['tns'] = $namespace;
+		$this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
+		$this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
+		if ($schemaTargetNamespace != $namespace) {
+			$this->wsdl->namespaces['types'] = $schemaTargetNamespace;
+		}
+        $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces);
+        $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
+        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
+        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
+        $this->wsdl->bindings[$serviceName.'Binding'] = array(
+        	'name'=>$serviceName.'Binding',
+            'style'=>$style,
+            'transport'=>$transport,
+            'portType'=>$serviceName.'PortType');
+        $this->wsdl->ports[$serviceName.'Port'] = array(
+        	'binding'=>$serviceName.'Binding',
+            'location'=>$endpoint,
+            'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
+    }
+}
+
+
+
+?><?php
+
+
+
+/**
+* parses a WSDL file, allows access to it's data, other utility methods
+* 
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access public 
+*/
+class wsdl extends nusoap_base {
+	// URL or filename of the root of this WSDL
+    var $wsdl; 
+    // define internal arrays of bindings, ports, operations, messages, etc.
+    var $schemas = array();
+    var $currentSchema;
+    var $message = array();
+    var $complexTypes = array();
+    var $messages = array();
+    var $currentMessage;
+    var $currentOperation;
+    var $portTypes = array();
+    var $currentPortType;
+    var $bindings = array();
+    var $currentBinding;
+    var $ports = array();
+    var $currentPort;
+    var $opData = array();
+    var $status = '';
+    var $documentation = false;
+    var $endpoint = ''; 
+    // array of wsdl docs to import
+    var $import = array(); 
+    // parser vars
+    var $parser;
+    var $position = 0;
+    var $depth = 0;
+    var $depth_array = array();
+	// for getting wsdl
+	var $proxyhost = '';
+    var $proxyport = '';
+	var $proxyusername = '';
+	var $proxypassword = '';
+	var $timeout = 0;
+	var $response_timeout = 30;
+
+    /**
+     * constructor
+     * 
+     * @param string $wsdl WSDL document URL
+	 * @param string $proxyhost
+	 * @param string $proxyport
+	 * @param string $proxyusername
+	 * @param string $proxypassword
+	 * @param integer $timeout set the connection timeout
+	 * @param integer $response_timeout set the response timeout
+     * @access public 
+     */
+    function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){
+		parent::nusoap_base();
+        $this->wsdl = $wsdl;
+        $this->proxyhost = $proxyhost;
+        $this->proxyport = $proxyport;
+		$this->proxyusername = $proxyusername;
+		$this->proxypassword = $proxypassword;
+		$this->timeout = $timeout;
+		$this->response_timeout = $response_timeout;
+        
+        // parse wsdl file
+        if ($wsdl != "") {
+            $this->debug('initial wsdl URL: ' . $wsdl);
+            $this->parseWSDL($wsdl);
+        }
+        // imports
+        // TODO: handle imports more properly, grabbing them in-line and nesting them
+        	$imported_urls = array();
+        	$imported = 1;
+        	while ($imported > 0) {
+        		$imported = 0;
+        		// Schema imports
+        		foreach ($this->schemas as $ns => $list) {
+        			foreach ($list as $xs) {
+						$wsdlparts = parse_url($this->wsdl);	// this is bogusly simple!
+			            foreach ($xs->imports as $ns2 => $list2) {
+			                for ($ii = 0; $ii < count($list2); $ii++) {
+			                	if (! $list2[$ii]['loaded']) {
+			                		$this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
+			                		$url = $list2[$ii]['location'];
+									if ($url != '') {
+										$urlparts = parse_url($url);
+										if (!isset($urlparts['host'])) {
+											$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
+													substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
+										}
+										if (! in_array($url, $imported_urls)) {
+						                	$this->parseWSDL($url);
+					                		$imported++;
+					                		$imported_urls[] = $url;
+					                	}
+									} else {
+										$this->debug("Unexpected scenario: empty URL for unloaded import");
+									}
+								}
+							}
+			            } 
+        			}
+        		}
+        		// WSDL imports
+				$wsdlparts = parse_url($this->wsdl);	// this is bogusly simple!
+	            foreach ($this->import as $ns => $list) {
+	                for ($ii = 0; $ii < count($list); $ii++) {
+	                	if (! $list[$ii]['loaded']) {
+	                		$this->import[$ns][$ii]['loaded'] = true;
+	                		$url = $list[$ii]['location'];
+							if ($url != '') {
+								$urlparts = parse_url($url);
+								if (!isset($urlparts['host'])) {
+									$url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
+											substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
+								}
+								if (! in_array($url, $imported_urls)) {
+				                	$this->parseWSDL($url);
+			                		$imported++;
+			                		$imported_urls[] = $url;
+			                	}
+							} else {
+								$this->debug("Unexpected scenario: empty URL for unloaded import");
+							}
+						}
+					}
+	            } 
+			}
+        // add new data to operation data
+        foreach($this->bindings as $binding => $bindingData) {
+            if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
+                foreach($bindingData['operations'] as $operation => $data) {
+                    $this->debug('post-parse data gathering for ' . $operation);
+                    $this->bindings[$binding]['operations'][$operation]['input'] = 
+						isset($this->bindings[$binding]['operations'][$operation]['input']) ? 
+						array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
+						$this->portTypes[ $bindingData['portType'] ][$operation]['input'];
+                    $this->bindings[$binding]['operations'][$operation]['output'] = 
+						isset($this->bindings[$binding]['operations'][$operation]['output']) ?
+						array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
+						$this->portTypes[ $bindingData['portType'] ][$operation]['output'];
+                    if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
+						$this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
+					}
+					if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
+                   		$this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
+                    }
+					if (isset($bindingData['style'])) {
+                        $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
+                    }
+                    $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
+                    $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
+                    $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
+                } 
+            } 
+        }
+    }
+
+    /**
+     * parses the wsdl document
+     * 
+     * @param string $wsdl path or URL
+     * @access private 
+     */
+    function parseWSDL($wsdl = '')
+    {
+        if ($wsdl == '') {
+            $this->debug('no wsdl passed to parseWSDL()!!');
+            $this->setError('no wsdl passed to parseWSDL()!!');
+            return false;
+        }
+        
+        // parse $wsdl for url format
+        $wsdl_props = parse_url($wsdl);
+
+        if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
+            $this->debug('getting WSDL http(s) URL ' . $wsdl);
+        	// get wsdl
+	        $tr = new soap_transport_http($wsdl);
+			$tr->request_method = 'GET';
+			$tr->useSOAPAction = false;
+			if($this->proxyhost && $this->proxyport){
+				$tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
+			}
+			$tr->setEncoding('gzip, deflate');
+			$wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
+			//$this->debug("WSDL request\n" . $tr->outgoing_payload);
+			//$this->debug("WSDL response\n" . $tr->incoming_payload);
+			$this->appendDebug($tr->getDebug());
+			// catch errors
+			if($err = $tr->getError() ){
+				$errstr = 'HTTP ERROR: '.$err;
+				$this->debug($errstr);
+	            $this->setError($errstr);
+				unset($tr);
+	            return false;
+			}
+			unset($tr);
+			$this->debug("got WSDL URL");
+        } else {
+            // $wsdl is not http(s), so treat it as a file URL or plain file path
+        	if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
+        		$path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
+        	} else {
+        		$path = $wsdl;
+        	}
+            $this->debug('getting WSDL file ' . $path);
+            if ($fp = @fopen($path, 'r')) {
+                $wsdl_string = '';
+                while ($data = fread($fp, 32768)) {
+                    $wsdl_string .= $data;
+                } 
+                fclose($fp);
+            } else {
+            	$errstr = "Bad path to WSDL file $path";
+            	$this->debug($errstr);
+                $this->setError($errstr);
+                return false;
+            } 
+        }
+        $this->debug('Parse WSDL');
+        // end new code added
+        // Create an XML parser.
+        $this->parser = xml_parser_create(); 
+        // Set the options for parsing the XML data.
+        // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 
+        // Set the object for the parser.
+        xml_set_object($this->parser, $this); 
+        // Set the element handlers for the parser.
+        xml_set_element_handler($this->parser, 'start_element', 'end_element');
+        xml_set_character_data_handler($this->parser, 'character_data');
+        // Parse the XML file.
+        if (!xml_parse($this->parser, $wsdl_string, true)) {
+            // Display an error message.
+            $errstr = sprintf(
+				'XML error parsing WSDL from %s on line %d: %s',
+				$wsdl,
+                xml_get_current_line_number($this->parser),
+                xml_error_string(xml_get_error_code($this->parser))
+                );
+            $this->debug($errstr);
+			$this->debug("XML payload:\n" . $wsdl_string);
+            $this->setError($errstr);
+            return false;
+        } 
+		// free the parser
+        xml_parser_free($this->parser);
+        $this->debug('Parsing WSDL done');
+		// catch wsdl parse errors
+		if($this->getError()){
+			return false;
+		}
+        return true;
+    } 
+
+    /**
+     * start-element handler
+     * 
+     * @param string $parser XML parser object
+     * @param string $name element name
+     * @param string $attrs associative array of attributes
+     * @access private 
+     */
+    function start_element($parser, $name, $attrs)
+    {
+        if ($this->status == 'schema') {
+            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
+            $this->appendDebug($this->currentSchema->getDebug());
+            $this->currentSchema->clearDebug();
+        } elseif (ereg('schema$', $name)) {
+        	$this->debug('Parsing WSDL schema');
+            // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
+            $this->status = 'schema';
+            $this->currentSchema = new xmlschema('', '', $this->namespaces);
+            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
+            $this->appendDebug($this->currentSchema->getDebug());
+            $this->currentSchema->clearDebug();
+        } else {
+            // position in the total number of elements, starting from 0
+            $pos = $this->position++;
+            $depth = $this->depth++; 
+            // set self as current value for this depth
+            $this->depth_array[$depth] = $pos;
+            $this->message[$pos] = array('cdata' => ''); 
+            // process attributes
+            if (count($attrs) > 0) {
+				// register namespace declarations
+                foreach($attrs as $k => $v) {
+                    if (ereg("^xmlns", $k)) {
+                        if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
+                            $this->namespaces[$ns_prefix] = $v;
+                        } else {
+                            $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
+                        } 
+                        if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
+                            $this->XMLSchemaVersion = $v;
+                            $this->namespaces['xsi'] = $v . '-instance';
+                        } 
+                    }
+                }
+                // expand each attribute prefix to its namespace
+                foreach($attrs as $k => $v) {
+                    $k = strpos($k, ':') ? $this->expandQname($k) : $k;
+                    if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
+                        $v = strpos($v, ':') ? $this->expandQname($v) : $v;
+                    } 
+                    $eAttrs[$k] = $v;
+                } 
+                $attrs = $eAttrs;
+            } else {
+                $attrs = array();
+            } 
+            // get element prefix, namespace and name
+            if (ereg(':', $name)) {
+                // get ns prefix
+                $prefix = substr($name, 0, strpos($name, ':')); 
+                // get ns
+                $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; 
+                // get unqualified name
+                $name = substr(strstr($name, ':'), 1);
+            } 
+			// process attributes, expanding any prefixes to namespaces
+            // find status, register data
+            switch ($this->status) {
+                case 'message':
+                    if ($name == 'part') {
+			            if (isset($attrs['type'])) {
+		                    $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
+		                    $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
+            			} 
+			            if (isset($attrs['element'])) {
+		                    $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
+			                $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'];
+			            } 
+        			} 
+        			break;
+			    case 'portType':
+			        switch ($name) {
+			            case 'operation':
+			                $this->currentPortOperation = $attrs['name'];
+			                $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
+			                if (isset($attrs['parameterOrder'])) {
+			                	$this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
+			        		} 
+			        		break;
+					    case 'documentation':
+					        $this->documentation = true;
+					        break; 
+					    // merge input/output data
+					    default:
+					        $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
+					        $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
+					        break;
+					} 
+			    	break;
+				case 'binding':
+				    switch ($name) {
+				        case 'binding': 
+				            // get ns prefix
+				            if (isset($attrs['style'])) {
+				            $this->bindings[$this->currentBinding]['prefix'] = $prefix;
+					    	} 
+					    	$this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
+					    	break;
+						case 'header':
+						    $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
+						    break;
+						case 'operation':
+						    if (isset($attrs['soapAction'])) {
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
+						    } 
+						    if (isset($attrs['style'])) {
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
+						    } 
+						    if (isset($attrs['name'])) {
+						        $this->currentOperation = $attrs['name'];
+						        $this->debug("current binding operation: $this->currentOperation");
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
+						    } 
+						    break;
+						case 'input':
+						    $this->opStatus = 'input';
+						    break;
+						case 'output':
+						    $this->opStatus = 'output';
+						    break;
+						case 'body':
+						    if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
+						    } else {
+						        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
+						    } 
+						    break;
+					} 
+					break;
+				case 'service':
+					switch ($name) {
+					    case 'port':
+					        $this->currentPort = $attrs['name'];
+					        $this->debug('current port: ' . $this->currentPort);
+					        $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
+					
+					        break;
+					    case 'address':
+					        $this->ports[$this->currentPort]['location'] = $attrs['location'];
+					        $this->ports[$this->currentPort]['bindingType'] = $namespace;
+					        $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
+					        $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
+					        break;
+					} 
+					break;
+			} 
+		// set status
+		switch ($name) {
+			case 'import':
+			    if (isset($attrs['location'])) {
+                    $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
+                    $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
+				} else {
+                    $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
+					if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
+						$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
+					}
+                    $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
+				}
+				break;
+			//wait for schema
+			//case 'types':
+			//	$this->status = 'schema';
+			//	break;
+			case 'message':
+				$this->status = 'message';
+				$this->messages[$attrs['name']] = array();
+				$this->currentMessage = $attrs['name'];
+				break;
+			case 'portType':
+				$this->status = 'portType';
+				$this->portTypes[$attrs['name']] = array();
+				$this->currentPortType = $attrs['name'];
+				break;
+			case "binding":
+				if (isset($attrs['name'])) {
+				// get binding name
+					if (strpos($attrs['name'], ':')) {
+			    		$this->currentBinding = $this->getLocalPart($attrs['name']);
+					} else {
+			    		$this->currentBinding = $attrs['name'];
+					} 
+					$this->status = 'binding';
+					$this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
+					$this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
+				} 
+				break;
+			case 'service':
+				$this->serviceName = $attrs['name'];
+				$this->status = 'service';
+				$this->debug('current service: ' . $this->serviceName);
+				break;
+			case 'definitions':
+				foreach ($attrs as $name => $value) {
+					$this->wsdl_info[$name] = $value;
+				} 
+				break;
+			} 
+		} 
+	} 
+
+	/**
+	* end-element handler
+	* 
+	* @param string $parser XML parser object
+	* @param string $name element name
+	* @access private 
+	*/
+	function end_element($parser, $name){ 
+		// unset schema status
+		if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) {
+			$this->status = "";
+            $this->appendDebug($this->currentSchema->getDebug());
+            $this->currentSchema->clearDebug();
+			$this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
+        	$this->debug('Parsing WSDL schema done');
+		} 
+		if ($this->status == 'schema') {
+			$this->currentSchema->schemaEndElement($parser, $name);
+		} else {
+			// bring depth down a notch
+			$this->depth--;
+		} 
+		// end documentation
+		if ($this->documentation) {
+			//TODO: track the node to which documentation should be assigned; it can be a part, message, etc.
+			//$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
+			$this->documentation = false;
+		} 
+	} 
+
+	/**
+	 * element content handler
+	 * 
+	 * @param string $parser XML parser object
+	 * @param string $data element content
+	 * @access private 
+	 */
+	function character_data($parser, $data)
+	{
+		$pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
+		if (isset($this->message[$pos]['cdata'])) {
+			$this->message[$pos]['cdata'] .= $data;
+		} 
+		if ($this->documentation) {
+			$this->documentation .= $data;
+		} 
+	} 
+	
+	function getBindingData($binding)
+	{
+		if (is_array($this->bindings[$binding])) {
+			return $this->bindings[$binding];
+		} 
+	}
+	
+	/**
+	 * returns an assoc array of operation names => operation data
+	 * 
+	 * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported)
+	 * @return array 
+	 * @access public 
+	 */
+	function getOperations($bindingType = 'soap')
+	{
+		$ops = array();
+		if ($bindingType == 'soap') {
+			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+		}
+		// loop thru ports
+		foreach($this->ports as $port => $portData) {
+			// binding type of port matches parameter
+			if ($portData['bindingType'] == $bindingType) {
+				//$this->debug("getOperations for port $port");
+				//$this->debug("port data: " . $this->varDump($portData));
+				//$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));
+				// merge bindings
+				if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
+					$ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
+				}
+			}
+		} 
+		return $ops;
+	} 
+	
+	/**
+	 * returns an associative array of data necessary for calling an operation
+	 * 
+	 * @param string $operation , name of operation
+	 * @param string $bindingType , type of binding eg: soap
+	 * @return array 
+	 * @access public 
+	 */
+	function getOperationData($operation, $bindingType = 'soap')
+	{
+		if ($bindingType == 'soap') {
+			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+		}
+		// loop thru ports
+		foreach($this->ports as $port => $portData) {
+			// binding type of port matches parameter
+			if ($portData['bindingType'] == $bindingType) {
+				// get binding
+				//foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
+				foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
+					// note that we could/should also check the namespace here
+					if ($operation == $bOperation) {
+						$opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
+					    return $opData;
+					} 
+				} 
+			}
+		} 
+	}
+	
+	/**
+	 * returns an associative array of data necessary for calling an operation
+	 * 
+	 * @param string $soapAction soapAction for operation
+	 * @param string $bindingType type of binding eg: soap
+	 * @return array 
+	 * @access public 
+	 */
+	function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
+		if ($bindingType == 'soap') {
+			$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+		}
+		// loop thru ports
+		foreach($this->ports as $port => $portData) {
+			// binding type of port matches parameter
+			if ($portData['bindingType'] == $bindingType) {
+				// loop through operations for the binding
+				foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
+					if ($opData['soapAction'] == $soapAction) {
+					    return $opData;
+					} 
+				} 
+			}
+		} 
+	}
+	
+	/**
+    * returns an array of information about a given type
+    * returns false if no type exists by the given name
+    *
+	*	 typeDef = array(
+	*	 'elements' => array(), // refs to elements array
+	*	'restrictionBase' => '',
+	*	'phpType' => '',
+	*	'order' => '(sequence|all)',
+	*	'attrs' => array() // refs to attributes array
+	*	)
+    *
+    * @param $type string the type
+    * @param $ns string namespace (not prefix) of the type
+    * @return mixed
+    * @access public
+    * @see xmlschema
+    */
+	function getTypeDef($type, $ns) {
+		$this->debug("in getTypeDef: type=$type, ns=$ns");
+		if ((! $ns) && isset($this->namespaces['tns'])) {
+			$ns = $this->namespaces['tns'];
+			$this->debug("in getTypeDef: type namespace forced to $ns");
+		}
+		if (isset($this->schemas[$ns])) {
+			$this->debug("in getTypeDef: have schema for namespace $ns");
+			for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
+				$xs = &$this->schemas[$ns][$i];
+				$t = $xs->getTypeDef($type);
+				$this->appendDebug($xs->getDebug());
+				$xs->clearDebug();
+				if ($t) {
+					if (!isset($t['phpType'])) {
+						// get info for type to tack onto the element
+						$uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
+						$ns = substr($t['type'], 0, strrpos($t['type'], ':'));
+						$etype = $this->getTypeDef($uqType, $ns);
+						if ($etype) {
+							$this->debug("found type for [element] $type:");
+							$this->debug($this->varDump($etype));
+							if (isset($etype['phpType'])) {
+								$t['phpType'] = $etype['phpType'];
+							}
+							if (isset($etype['elements'])) {
+								$t['elements'] = $etype['elements'];
+							}
+							if (isset($etype['attrs'])) {
+								$t['attrs'] = $etype['attrs'];
+							}
+						}
+					}
+					return $t;
+				}
+			}
+		} else {
+			$this->debug("in getTypeDef: do not have schema for namespace $ns");
+		}
+		return false;
+	}
+
+    /**
+    * prints html description of services
+    *
+    * @access private
+    */
+    function webDescription(){
+    	global $HTTP_SERVER_VARS;
+
+		if (isset($_SERVER)) {
+			$PHP_SELF = $_SERVER['PHP_SELF'];
+		} elseif (isset($HTTP_SERVER_VARS)) {
+			$PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
+		} else {
+			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
+		}
+
+		$b = '
+		<html><head><title>NuSOAP: '.$this->serviceName.'</title>
+		<style type="text/css">
+		    body    { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
+		    p       { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
+		    pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
+		    ul      { margin-top: 10px; margin-left: 20px; }
+		    li      { list-style-type: none; margin-top: 10px; color: #000000; }
+		    .content{
+			margin-left: 0px; padding-bottom: 2em; }
+		    .nav {
+			padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
+			margin-top: 10px; margin-left: 0px; color: #000000;
+			background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
+		    .title {
+			font-family: arial; font-size: 26px; color: #ffffff;
+			background-color: #999999; width: 105%; margin-left: 0px;
+			padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
+		    .hidden {
+			position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
+			font-family: arial; overflow: hidden; width: 600;
+			padding: 20px; font-size: 10px; background-color: #999999;
+			layer-background-color:#FFFFFF; }
+		    a,a:active  { color: charcoal; font-weight: bold; }
+		    a:visited   { color: #666666; font-weight: bold; }
+		    a:hover     { color: cc3300; font-weight: bold; }
+		</style>
+		<script language="JavaScript" type="text/javascript">
+		<!--
+		// POP-UP CAPTIONS...
+		function lib_bwcheck(){ //Browsercheck (needed)
+		    this.ver=navigator.appVersion
+		    this.agent=navigator.userAgent
+		    this.dom=document.getElementById?1:0
+		    this.opera5=this.agent.indexOf("Opera 5")>-1
+		    this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
+		    this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
+		    this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
+		    this.ie=this.ie4||this.ie5||this.ie6
+		    this.mac=this.agent.indexOf("Mac")>-1
+		    this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
+		    this.ns4=(document.layers && !this.dom)?1:0;
+		    this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
+		    return this
+		}
+		var bw = new lib_bwcheck()
+		//Makes crossbrowser object.
+		function makeObj(obj){
+		    this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
+		    if(!this.evnt) return false
+		    this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
+		    this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
+		    this.writeIt=b_writeIt;
+		    return this
+		}
+		// A unit of measure that will be added when setting the position of a layer.
+		//var px = bw.ns4||window.opera?"":"px";
+		function b_writeIt(text){
+		    if (bw.ns4){this.wref.write(text);this.wref.close()}
+		    else this.wref.innerHTML = text
+		}
+		//Shows the messages
+		var oDesc;
+		function popup(divid){
+		    if(oDesc = new makeObj(divid)){
+			oDesc.css.visibility = "visible"
+		    }
+		}
+		function popout(){ // Hides message
+		    if(oDesc) oDesc.css.visibility = "hidden"
+		}
+		//-->
+		</script>
+		</head>
+		<body>
+		<div class=content>
+			<br><br>
+			<div class=title>'.$this->serviceName.'</div>
+			<div class=nav>
+				<p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
+				Click on an operation name to view it&apos;s details.</p>
+				<ul>';
+				foreach($this->getOperations() as $op => $data){
+				    $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
+				    // create hidden div
+				    $b .= "<div id='$op' class='hidden'>
+				    <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
+				    foreach($data as $donnie => $marie){ // loop through opdata
+						if($donnie == 'input' || $donnie == 'output'){ // show input/output data
+						    $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
+						    foreach($marie as $captain => $tenille){ // loop through data
+								if($captain == 'parts'){ // loop thru parts
+								    $b .= "&nbsp;&nbsp;$captain:<br>";
+					                //if(is_array($tenille)){
+								    	foreach($tenille as $joanie => $chachi){
+											$b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
+								    	}
+					        		//}
+								} else {
+								    $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
+								}
+						    }
+						} else {
+						    $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
+						}
+				    }
+					$b .= '</div>';
+				}
+				$b .= '
+				<ul>
+			</div>
+		</div></body></html>';
+		return $b;
+    }
+
+	/**
+	* serialize the parsed wsdl
+	*
+	* @param mixed $debug whether to put debug=1 in endpoint URL
+	* @return string serialization of WSDL
+	* @access public 
+	*/
+	function serialize($debug = 0)
+	{
+		$xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
+		$xml .= "\n<definitions";
+		foreach($this->namespaces as $k => $v) {
+			$xml .= " xmlns:$k=\"$v\"";
+		} 
+		// 10.9.02 - add poulter fix for wsdl and tns declarations
+		if (isset($this->namespaces['wsdl'])) {
+			$xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
+		} 
+		if (isset($this->namespaces['tns'])) {
+			$xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
+		} 
+		$xml .= '>'; 
+		// imports
+		if (sizeof($this->import) > 0) {
+			foreach($this->import as $ns => $list) {
+				foreach ($list as $ii) {
+					if ($ii['location'] != '') {
+						$xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
+					} else {
+						$xml .= '<import namespace="' . $ns . '" />';
+					}
+				}
+			} 
+		} 
+		// types
+		if (count($this->schemas)>=1) {
+			$xml .= "\n<types>";
+			foreach ($this->schemas as $ns => $list) {
+				foreach ($list as $xs) {
+					$xml .= $xs->serializeSchema();
+				}
+			}
+			$xml .= '</types>';
+		} 
+		// messages
+		if (count($this->messages) >= 1) {
+			foreach($this->messages as $msgName => $msgParts) {
+				$xml .= "\n<message name=\"" . $msgName . '">';
+				if(is_array($msgParts)){
+					foreach($msgParts as $partName => $partType) {
+						// print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';
+						if (strpos($partType, ':')) {
+						    $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
+						} elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
+						    // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';
+						    $typePrefix = 'xsd';
+						} else {
+						    foreach($this->typemap as $ns => $types) {
+						        if (isset($types[$partType])) {
+						            $typePrefix = $this->getPrefixFromNamespace($ns);
+						        } 
+						    } 
+						    if (!isset($typePrefix)) {
+						        die("$partType has no namespace!");
+						    } 
+						}
+						$ns = $this->getNamespaceFromPrefix($typePrefix);
+						$typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns);
+						if ($typeDef['typeClass'] == 'element') {
+							$elementortype = 'element';
+						} else {
+							$elementortype = 'type';
+						}
+						$xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />';
+					}
+				}
+				$xml .= '</message>';
+			} 
+		} 
+		// bindings & porttypes
+		if (count($this->bindings) >= 1) {
+			$binding_xml = '';
+			$portType_xml = '';
+			foreach($this->bindings as $bindingName => $attrs) {
+				$binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
+				$binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
+				$portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
+				foreach($attrs['operations'] as $opName => $opParts) {
+					$binding_xml .= '<operation name="' . $opName . '">';
+					$binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
+					if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
+						$enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
+					} else {
+						$enc_style = '';
+					}
+					$binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
+					if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
+						$enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
+					} else {
+						$enc_style = '';
+					}
+					$binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
+					$binding_xml .= '</operation>';
+					$portType_xml .= '<operation name="' . $opParts['name'] . '"';
+					if (isset($opParts['parameterOrder'])) {
+					    $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
+					} 
+					$portType_xml .= '>';
+					if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
+						$portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
+					}
+					$portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>';
+					$portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>';
+					$portType_xml .= '</operation>';
+				} 
+				$portType_xml .= '</portType>';
+				$binding_xml .= '</binding>';
+			} 
+			$xml .= $portType_xml . $binding_xml;
+		} 
+		// services
+		$xml .= "\n<service name=\"" . $this->serviceName . '">';
+		if (count($this->ports) >= 1) {
+			foreach($this->ports as $pName => $attrs) {
+				$xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
+				$xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
+				$xml .= '</port>';
+			} 
+		} 
+		$xml .= '</service>';
+		return $xml . "\n</definitions>";
+	} 
+	
+	/**
+	 * serialize PHP values according to a WSDL message definition
+	 *
+	 * TODO
+	 * - multi-ref serialization
+	 * - validate PHP values against type definitions, return errors if invalid
+	 * 
+	 * @param string $operation operation name
+	 * @param string $direction (input|output)
+	 * @param mixed $parameters parameter value(s)
+	 * @return mixed parameters serialized as XML or false on error (e.g. operation not found)
+	 * @access public
+	 */
+	function serializeRPCParameters($operation, $direction, $parameters)
+	{
+		$this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
+		$this->appendDebug('parameters=' . $this->varDump($parameters));
+		
+		if ($direction != 'input' && $direction != 'output') {
+			$this->debug('The value of the \$direction argument needs to be either "input" or "output"');
+			$this->setError('The value of the \$direction argument needs to be either "input" or "output"');
+			return false;
+		} 
+		if (!$opData = $this->getOperationData($operation)) {
+			$this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
+			$this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
+			return false;
+		}
+		$this->debug('opData:');
+		$this->appendDebug($this->varDump($opData));
+
+		// Get encoding style for output and set to current
+		$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+		if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
+			$encodingStyle = $opData['output']['encodingStyle'];
+			$enc_style = $encodingStyle;
+		}
+
+		// set input params
+		$xml = '';
+		if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
+			
+			$use = $opData[$direction]['use'];
+			$this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize');
+			if (is_array($parameters)) {
+				$parametersArrayType = $this->isArraySimpleOrStruct($parameters);
+				$this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize');
+				foreach($opData[$direction]['parts'] as $name => $type) {
+					$this->debug('serializing part "'.$name.'" of type "'.$type.'"');
+					// Track encoding style
+					if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
+						$encodingStyle = $opData[$direction]['encodingStyle'];			
+						$enc_style = $encodingStyle;
+					} else {
+						$enc_style = false;
+					}
+					// NOTE: add error handling here
+					// if serializeType returns false, then catch global error and fault
+					if ($parametersArrayType == 'arraySimple') {
+						$p = array_shift($parameters);
+						$this->debug('calling serializeType w/indexed param');
+						$xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
+					} elseif (isset($parameters[$name])) {
+						$this->debug('calling serializeType w/named param');
+						$xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
+					} else {
+						// TODO: only send nillable
+						$this->debug('calling serializeType w/null param');
+						$xml .= $this->serializeType($name, $type, null, $use, $enc_style);
+					}
+				}
+			} else {
+				$this->debug('no parameters passed.');
+			}
+		}
+		$this->debug("serializeRPCParameters returning: $xml");
+		return $xml;
+	} 
+	
+	/**
+	 * serialize a PHP value according to a WSDL message definition
+	 * 
+	 * TODO
+	 * - multi-ref serialization
+	 * - validate PHP values against type definitions, return errors if invalid
+	 * 
+	 * @param string $ type name
+	 * @param mixed $ param value
+	 * @return mixed new param or false if initial value didn't validate
+	 * @access public
+	 * @deprecated
+	 */
+	function serializeParameters($operation, $direction, $parameters)
+	{
+		$this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
+		$this->appendDebug('parameters=' . $this->varDump($parameters));
+		
+		if ($direction != 'input' && $direction != 'output') {
+			$this->debug('The value of the \$direction argument needs to be either "input" or "output"');
+			$this->setError('The value of the \$direction argument needs to be either "input" or "output"');
+			return false;
+		} 
+		if (!$opData = $this->getOperationData($operation)) {
+			$this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
+			$this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
+			return false;
+		}
+		$this->debug('opData:');
+		$this->appendDebug($this->varDump($opData));
+		
+		// Get encoding style for output and set to current
+		$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+		if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
+			$encodingStyle = $opData['output']['encodingStyle'];
+			$enc_style = $encodingStyle;
+		}
+		
+		// set input params
+		$xml = '';
+		if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
+			
+			$use = $opData[$direction]['use'];
+			$this->debug("use=$use");
+			$this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
+			if (is_array($parameters)) {
+				$parametersArrayType = $this->isArraySimpleOrStruct($parameters);
+				$this->debug('have ' . $parametersArrayType . ' parameters');
+				foreach($opData[$direction]['parts'] as $name => $type) {
+					$this->debug('serializing part "'.$name.'" of type "'.$type.'"');
+					// Track encoding style
+					if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
+						$encodingStyle = $opData[$direction]['encodingStyle'];			
+						$enc_style = $encodingStyle;
+					} else {
+						$enc_style = false;
+					}
+					// NOTE: add error handling here
+					// if serializeType returns false, then catch global error and fault
+					if ($parametersArrayType == 'arraySimple') {
+						$p = array_shift($parameters);
+						$this->debug('calling serializeType w/indexed param');
+						$xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
+					} elseif (isset($parameters[$name])) {
+						$this->debug('calling serializeType w/named param');
+						$xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
+					} else {
+						// TODO: only send nillable
+						$this->debug('calling serializeType w/null param');
+						$xml .= $this->serializeType($name, $type, null, $use, $enc_style);
+					}
+				}
+			} else {
+				$this->debug('no parameters passed.');
+			}
+		}
+		$this->debug("serializeParameters returning: $xml");
+		return $xml;
+	} 
+	
+	/**
+	 * serializes a PHP value according a given type definition
+	 * 
+	 * @param string $name name of value (part or element)
+	 * @param string $type XML schema type of value (type or element)
+	 * @param mixed $value a native PHP value (parameter value)
+	 * @param string $use use for part (encoded|literal)
+	 * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
+	 * @param boolean $unqualified a kludge for what should be XML namespace form handling
+	 * @return string value serialized as an XML string
+	 * @access private
+	 */
+	function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
+	{
+		$this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
+		$this->appendDebug("value=" . $this->varDump($value));
+		if($use == 'encoded' && $encodingStyle) {
+			$encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
+		}
+
+		// if a soapval has been supplied, let its type override the WSDL
+    	if (is_object($value) && get_class($value) == 'soapval') {
+    		if ($value->type_ns) {
+    			$type = $value->type_ns . ':' . $value->type;
+		    	$forceType = true;
+		    	$this->debug("in serializeType: soapval overrides type to $type");
+    		} elseif ($value->type) {
+	    		$type = $value->type;
+		    	$forceType = true;
+		    	$this->debug("in serializeType: soapval overrides type to $type");
+	    	} else {
+	    		$forceType = false;
+		    	$this->debug("in serializeType: soapval does not override type");
+	    	}
+	    	$attrs = $value->attributes;
+	    	$value = $value->value;
+	    	$this->debug("in serializeType: soapval overrides value to $value");
+	    	if ($attrs) {
+	    		if (!is_array($value)) {
+	    			$value['!'] = $value;
+	    		}
+	    		foreach ($attrs as $n => $v) {
+	    			$value['!' . $n] = $v;
+	    		}
+		    	$this->debug("in serializeType: soapval provides attributes");
+		    }
+        } else {
+        	$forceType = false;
+        }
+
+		$xml = '';
+		if (strpos($type, ':')) {
+			$uqType = substr($type, strrpos($type, ':') + 1);
+			$ns = substr($type, 0, strrpos($type, ':'));
+			$this->debug("in serializeType: got a prefixed type: $uqType, $ns");
+			if ($this->getNamespaceFromPrefix($ns)) {
+				$ns = $this->getNamespaceFromPrefix($ns);
+				$this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
+			}
+
+			if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
+				$this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
+				if ($unqualified  && $use == 'literal') {
+					$elementNS = " xmlns=\"\"";
+				} else {
+					$elementNS = '';
+				}
+				if (is_null($value)) {
+					if ($use == 'literal') {
+						// TODO: depends on minOccurs
+						$xml = "<$name$elementNS/>";
+					} else {
+						// TODO: depends on nillable, which should be checked before calling this method
+						$xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
+					}
+					$this->debug("in serializeType: returning: $xml");
+					return $xml;
+				}
+		    	if ($uqType == 'boolean') {
+		    		if ((is_string($value) && $value == 'false') || (! $value)) {
+						$value = 'false';
+					} else {
+						$value = 'true';
+					}
+				} 
+				if ($uqType == 'string' && gettype($value) == 'string') {
+					$value = $this->expandEntities($value);
+				}
+				if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
+					$value = sprintf("%.0lf", $value);
+				}
+				// it's a scalar
+				// TODO: what about null/nil values?
+				// check type isn't a custom type extending xmlschema namespace
+				if (!$this->getTypeDef($uqType, $ns)) {
+					if ($use == 'literal') {
+						if ($forceType) {
+							$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
+						} else {
+							$xml = "<$name$elementNS>$value</$name>";
+						}
+					} else {
+						$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
+					}
+					$this->debug("in serializeType: returning: $xml");
+					return $xml;
+				}
+				$this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
+			} else if ($ns == 'http://xml.apache.org/xml-soap') {
+				$this->debug('in serializeType: appears to be Apache SOAP type');
+				if ($uqType == 'Map') {
+					$tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
+					if (! $tt_prefix) {
+						$this->debug('in serializeType: Add namespace for Apache SOAP type');
+						$tt_prefix = 'ns' . rand(1000, 9999);
+						$this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
+						// force this to be added to usedNamespaces
+						$tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
+					}
+					$contents = '';
+					foreach($value as $k => $v) {
+						$this->debug("serializing map element: key $k, value $v");
+						$contents .= '<item>';
+						$contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
+						$contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
+						$contents .= '</item>';
+					}
+					if ($use == 'literal') {
+						if ($forceType) {
+							$xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
+						} else {
+							$xml = "<$name>$contents</$name>";
+						}
+					} else {
+						$xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
+					}
+					$this->debug("in serializeType: returning: $xml");
+					return $xml;
+				}
+				$this->debug('in serializeType: Apache SOAP type, but only support Map');
+			}
+		} else {
+			// TODO: should the type be compared to types in XSD, and the namespace
+			// set to XSD if the type matches?
+			$this->debug("in serializeType: No namespace for type $type");
+			$ns = '';
+			$uqType = $type;
+		}
+		if(!$typeDef = $this->getTypeDef($uqType, $ns)){
+			$this->setError("$type ($uqType) is not a supported type.");
+			$this->debug("in serializeType: $type ($uqType) is not a supported type.");
+			return false;
+		} else {
+			$this->debug("in serializeType: found typeDef");
+			$this->appendDebug('typeDef=' . $this->varDump($typeDef));
+		}
+		$phpType = $typeDef['phpType'];
+		$this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); 
+		// if php type == struct, map value to the <all> element names
+		if ($phpType == 'struct') {
+			if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
+				$elementName = $uqType;
+				if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
+					$elementNS = " xmlns=\"$ns\"";
+				} else {
+					$elementNS = " xmlns=\"\"";
+				}
+			} else {
+				$elementName = $name;
+				if ($unqualified) {
+					$elementNS = " xmlns=\"\"";
+				} else {
+					$elementNS = '';
+				}
+			}
+			if (is_null($value)) {
+				if ($use == 'literal') {
+					// TODO: depends on minOccurs
+					$xml = "<$elementName$elementNS/>";
+				} else {
+					$xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
+				}
+				$this->debug("in serializeType: returning: $xml");
+				return $xml;
+			}
+			if (is_object($value)) {
+				$value = get_object_vars($value);
+			}
+			if (is_array($value)) {
+				$elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
+				if ($use == 'literal') {
+					if ($forceType) {
+						$xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
+					} else {
+						$xml = "<$elementName$elementNS$elementAttrs>";
+					}
+				} else {
+					$xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
+				}
+	
+				$xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
+				$xml .= "</$elementName>";
+			} else {
+				$this->debug("in serializeType: phpType is struct, but value is not an array");
+				$this->setError("phpType is struct, but value is not an array: see debug output for details");
+				$xml = '';
+			}
+		} elseif ($phpType == 'array') {
+			if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
+				$elementNS = " xmlns=\"$ns\"";
+			} else {
+				if ($unqualified) {
+					$elementNS = " xmlns=\"\"";
+				} else {
+					$elementNS = '';
+				}
+			}
+			if (is_null($value)) {
+				if ($use == 'literal') {
+					// TODO: depends on minOccurs
+					$xml = "<$name$elementNS/>";
+				} else {
+					$xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
+						$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
+						":Array\" " .
+						$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
+						':arrayType="' .
+						$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
+						':' .
+						$this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
+				}
+				$this->debug("in serializeType: returning: $xml");
+				return $xml;
+			}
+			if (isset($typeDef['multidimensional'])) {
+				$nv = array();
+				foreach($value as $v) {
+					$cols = ',' . sizeof($v);
+					$nv = array_merge($nv, $v);
+				} 
+				$value = $nv;
+			} else {
+				$cols = '';
+			} 
+			if (is_array($value) && sizeof($value) >= 1) {
+				$rows = sizeof($value);
+				$contents = '';
+				foreach($value as $k => $v) {
+					$this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
+					//if (strpos($typeDef['arrayType'], ':') ) {
+					if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
+					    $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
+					} else {
+					    $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
+					} 
+				}
+			} else {
+				$rows = 0;
+				$contents = null;
+			}
+			// TODO: for now, an empty value will be serialized as a zero element
+			// array.  Revisit this when coding the handling of null/nil values.
+			if ($use == 'literal') {
+				$xml = "<$name$elementNS>"
+					.$contents
+					."</$name>";
+			} else {
+				$xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
+					$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
+					.':arrayType="'
+					.$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
+					.":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
+					.$contents
+					."</$name>";
+			}
+		} elseif ($phpType == 'scalar') {
+			if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
+				$elementNS = " xmlns=\"$ns\"";
+			} else {
+				if ($unqualified) {
+					$elementNS = " xmlns=\"\"";
+				} else {
+					$elementNS = '';
+				}
+			}
+			if ($use == 'literal') {
+				if ($forceType) {
+					$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
+				} else {
+					$xml = "<$name$elementNS>$value</$name>";
+				}
+			} else {
+				$xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
+			}
+		}
+		$this->debug("in serializeType: returning: $xml");
+		return $xml;
+	}
+	
+	/**
+	 * serializes the attributes for a complexType
+	 *
+	 * @param array $typeDef our internal representation of an XML schema type (or element)
+	 * @param mixed $value a native PHP value (parameter value)
+	 * @param string $ns the namespace of the type
+	 * @param string $uqType the local part of the type
+	 * @return string value serialized as an XML string
+	 * @access private
+	 */
+	function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
+		$xml = '';
+		if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
+			$this->debug("serialize attributes for XML Schema type $ns:$uqType");
+			if (is_array($value)) {
+				$xvalue = $value;
+			} elseif (is_object($value)) {
+				$xvalue = get_object_vars($value);
+			} else {
+				$this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
+				$xvalue = array();
+			}
+			foreach ($typeDef['attrs'] as $aName => $attrs) {
+				if (isset($xvalue['!' . $aName])) {
+					$xname = '!' . $aName;
+					$this->debug("value provided for attribute $aName with key $xname");
+				} elseif (isset($xvalue[$aName])) {
+					$xname = $aName;
+					$this->debug("value provided for attribute $aName with key $xname");
+				} elseif (isset($attrs['default'])) {
+					$xname = '!' . $aName;
+					$xvalue[$xname] = $attrs['default'];
+					$this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
+				} else {
+					$xname = '';
+					$this->debug("no value provided for attribute $aName");
+				}
+				if ($xname) {
+					$xml .=  " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
+				}
+			} 
+		} else {
+			$this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
+		}
+		if (isset($typeDef['extensionBase'])) {
+			$ns = $this->getPrefix($typeDef['extensionBase']);
+			$uqType = $this->getLocalPart($typeDef['extensionBase']);
+			if ($this->getNamespaceFromPrefix($ns)) {
+				$ns = $this->getNamespaceFromPrefix($ns);
+			}
+			if ($typeDef = $this->getTypeDef($uqType, $ns)) {
+				$this->debug("serialize attributes for extension base $ns:$uqType");
+				$xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
+			} else {
+				$this->debug("extension base $ns:$uqType is not a supported type");
+			}
+		}
+		return $xml;
+	}
+
+	/**
+	 * serializes the elements for a complexType
+	 *
+	 * @param array $typeDef our internal representation of an XML schema type (or element)
+	 * @param mixed $value a native PHP value (parameter value)
+	 * @param string $ns the namespace of the type
+	 * @param string $uqType the local part of the type
+	 * @param string $use use for part (encoded|literal)
+	 * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
+	 * @return string value serialized as an XML string
+	 * @access private
+	 */
+	function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
+		$xml = '';
+		if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
+			$this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
+			if (is_array($value)) {
+				$xvalue = $value;
+			} elseif (is_object($value)) {
+				$xvalue = get_object_vars($value);
+			} else {
+				$this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
+				$xvalue = array();
+			}
+			// toggle whether all elements are present - ideally should validate against schema
+			if (count($typeDef['elements']) != count($xvalue)){
+				$optionals = true;
+			}
+			foreach ($typeDef['elements'] as $eName => $attrs) {
+				if (!isset($xvalue[$eName])) {
+					if (isset($attrs['default'])) {
+						$xvalue[$eName] = $attrs['default'];
+						$this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
+					}
+				}
+				// if user took advantage of a minOccurs=0, then only serialize named parameters
+				if (isset($optionals)
+				    && (!isset($xvalue[$eName])) 
+					&& ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
+					){
+					if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
+						$this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
+					}
+					// do nothing
+					$this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
+				} else {
+					// get value
+					if (isset($xvalue[$eName])) {
+					    $v = $xvalue[$eName];
+					} else {
+					    $v = null;
+					}
+					if (isset($attrs['form'])) {
+						$unqualified = ($attrs['form'] == 'unqualified');
+					} else {
+						$unqualified = false;
+					}
+					if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
+						$vv = $v;
+						foreach ($vv as $k => $v) {
+							if (isset($attrs['type']) || isset($attrs['ref'])) {
+								// serialize schema-defined type
+							    $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
+							} else {
+								// serialize generic type (can this ever really happen?)
+							    $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
+							    $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
+							}
+						}
+					} else {
+						if (isset($attrs['type']) || isset($attrs['ref'])) {
+							// serialize schema-defined type
+						    $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
+						} else {
+							// serialize generic type (can this ever really happen?)
+						    $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
+						    $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
+						}
+					}
+				}
+			} 
+		} else {
+			$this->debug("no elements to serialize for XML Schema type $ns:$uqType");
+		}
+		if (isset($typeDef['extensionBase'])) {
+			$ns = $this->getPrefix($typeDef['extensionBase']);
+			$uqType = $this->getLocalPart($typeDef['extensionBase']);
+			if ($this->getNamespaceFromPrefix($ns)) {
+				$ns = $this->getNamespaceFromPrefix($ns);
+			}
+			if ($typeDef = $this->getTypeDef($uqType, $ns)) {
+				$this->debug("serialize elements for extension base $ns:$uqType");
+				$xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
+			} else {
+				$this->debug("extension base $ns:$uqType is not a supported type");
+			}
+		}
+		return $xml;
+	}
+
+	/**
+	* adds an XML Schema complex type to the WSDL types
+	*
+	* @param string	name
+	* @param string typeClass (complexType|simpleType|attribute)
+	* @param string phpType: currently supported are array and struct (php assoc array)
+	* @param string compositor (all|sequence|choice)
+	* @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+	* @param array elements = array ( name => array(name=>'',type=>'') )
+	* @param array attrs = 	array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))
+	* @param string arrayType: namespace:name (xsd:string)
+	* @see xmlschema
+	* @access public
+	*/
+	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
+		if (count($elements) > 0) {
+	    	foreach($elements as $n => $e){
+	            // expand each element
+	            foreach ($e as $k => $v) {
+		            $k = strpos($k,':') ? $this->expandQname($k) : $k;
+		            $v = strpos($v,':') ? $this->expandQname($v) : $v;
+		            $ee[$k] = $v;
+		    	}
+	    		$eElements[$n] = $ee;
+	    	}
+	    	$elements = $eElements;
+		}
+		
+		if (count($attrs) > 0) {
+	    	foreach($attrs as $n => $a){
+	            // expand each attribute
+	            foreach ($a as $k => $v) {
+		            $k = strpos($k,':') ? $this->expandQname($k) : $k;
+		            $v = strpos($v,':') ? $this->expandQname($v) : $v;
+		            $aa[$k] = $v;
+		    	}
+	    		$eAttrs[$n] = $aa;
+	    	}
+	    	$attrs = $eAttrs;
+		}
+
+		$restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
+		$arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
+
+		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
+		$this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
+	}
+
+	/**
+	* adds an XML Schema simple type to the WSDL types
+	*
+	* @param string $name
+	* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+	* @param string $typeClass (should always be simpleType)
+	* @param string $phpType (should always be scalar)
+	* @param array $enumeration array of values
+	* @see xmlschema
+	* @access public
+	*/
+	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
+		$restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
+
+		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
+		$this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
+	}
+
+	/**
+	* adds an element to the WSDL types
+	*
+	* @param array $attrs attributes that must include name and type
+	* @see xmlschema
+	* @access public
+	*/
+	function addElement($attrs) {
+		$typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
+		$this->schemas[$typens][0]->addElement($attrs);
+	}
+
+	/**
+	* register an operation with the server
+	* 
+	* @param string $name operation (method) name
+	* @param array $in assoc array of input values: key = param name, value = param type
+	* @param array $out assoc array of output values: key = param name, value = param type
+	* @param string $namespace optional The namespace for the operation
+	* @param string $soapaction optional The soapaction for the operation
+	* @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically
+	* @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now)
+	* @param string $documentation optional The description to include in the WSDL
+	* @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
+	* @access public 
+	*/
+	function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
+		if ($use == 'encoded' && $encodingStyle == '') {
+			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+		}
+
+		if ($style == 'document') {
+			$elements = array();
+			foreach ($in as $n => $t) {
+				$elements[$n] = array('name' => $n, 'type' => $t);
+			}
+			$this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
+			$this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
+			$in = array('parameters' => 'tns:' . $name);
+
+			$elements = array();
+			foreach ($out as $n => $t) {
+				$elements[$n] = array('name' => $n, 'type' => $t);
+			}
+			$this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
+			$this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType'));
+			$out = array('parameters' => 'tns:' . $name . 'Response');
+		}
+
+		// get binding
+		$this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
+		array(
+		'name' => $name,
+		'binding' => $this->serviceName . 'Binding',
+		'endpoint' => $this->endpoint,
+		'soapAction' => $soapaction,
+		'style' => $style,
+		'input' => array(
+			'use' => $use,
+			'namespace' => $namespace,
+			'encodingStyle' => $encodingStyle,
+			'message' => $name . 'Request',
+			'parts' => $in),
+		'output' => array(
+			'use' => $use,
+			'namespace' => $namespace,
+			'encodingStyle' => $encodingStyle,
+			'message' => $name . 'Response',
+			'parts' => $out),
+		'namespace' => $namespace,
+		'transport' => 'http://schemas.xmlsoap.org/soap/http',
+		'documentation' => $documentation); 
+		// add portTypes
+		// add messages
+		if($in)
+		{
+			foreach($in as $pName => $pType)
+			{
+				if(strpos($pType,':')) {
+					$pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
+				}
+				$this->messages[$name.'Request'][$pName] = $pType;
+			}
+		} else {
+            $this->messages[$name.'Request']= '0';
+        }
+		if($out)
+		{
+			foreach($out as $pName => $pType)
+			{
+				if(strpos($pType,':')) {
+					$pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
+				}
+				$this->messages[$name.'Response'][$pName] = $pType;
+			}
+		} else {
+            $this->messages[$name.'Response']= '0';
+        }
+		return true;
+	} 
+}
+?><?php
+
+
+
+/**
+*
+* soap_parser class parses SOAP XML messages into native PHP values
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class soap_parser extends nusoap_base {
+
+	var $xml = '';
+	var $xml_encoding = '';
+	var $method = '';
+	var $root_struct = '';
+	var $root_struct_name = '';
+	var $root_struct_namespace = '';
+	var $root_header = '';
+    var $document = '';			// incoming SOAP body (text)
+	// determines where in the message we are (envelope,header,body,method)
+	var $status = '';
+	var $position = 0;
+	var $depth = 0;
+	var $default_namespace = '';
+	var $namespaces = array();
+	var $message = array();
+    var $parent = '';
+	var $fault = false;
+	var $fault_code = '';
+	var $fault_str = '';
+	var $fault_detail = '';
+	var $depth_array = array();
+	var $debug_flag = true;
+	var $soapresponse = NULL;
+	var $responseHeaders = '';	// incoming SOAP headers (text)
+	var $body_position = 0;
+	// for multiref parsing:
+	// array of id => pos
+	var $ids = array();
+	// array of id => hrefs => pos
+	var $multirefs = array();
+	// toggle for auto-decoding element content
+	var $decode_utf8 = true;
+
+	/**
+	* constructor that actually does the parsing
+	*
+	* @param    string $xml SOAP message
+	* @param    string $encoding character encoding scheme of message
+	* @param    string $method method for which XML is parsed (unused?)
+	* @param    string $decode_utf8 whether to decode UTF-8 to ISO-8859-1
+	* @access   public
+	*/
+	function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
+		parent::nusoap_base();
+		$this->xml = $xml;
+		$this->xml_encoding = $encoding;
+		$this->method = $method;
+		$this->decode_utf8 = $decode_utf8;
+
+		// Check whether content has been read.
+		if(!empty($xml)){
+			// Check XML encoding
+			$pos_xml = strpos($xml, '<?xml');
+			if ($pos_xml !== FALSE) {
+				$xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
+				if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
+					$xml_encoding = $res[1];
+					if (strtoupper($xml_encoding) != $encoding) {
+						$err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
+						$this->debug($err);
+						if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
+							$this->setError($err);
+							return;
+						}
+						// when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
+					} else {
+						$this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
+					}
+				} else {
+					$this->debug('No encoding specified in XML declaration');
+				}
+			} else {
+				$this->debug('No XML declaration');
+			}
+			$this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding);
+			// Create an XML parser - why not xml_parser_create_ns?
+			$this->parser = xml_parser_create($this->xml_encoding);
+			// Set the options for parsing the XML data.
+			//xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+			xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+			xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
+			// Set the object for the parser.
+			xml_set_object($this->parser, $this);
+			// Set the element handlers for the parser.
+			xml_set_element_handler($this->parser, 'start_element','end_element');
+			xml_set_character_data_handler($this->parser,'character_data');
+
+			// Parse the XML file.
+			if(!xml_parse($this->parser,$xml,true)){
+			    // Display an error message.
+			    $err = sprintf('XML error parsing SOAP payload on line %d: %s',
+			    xml_get_current_line_number($this->parser),
+			    xml_error_string(xml_get_error_code($this->parser)));
+				$this->debug($err);
+				$this->debug("XML payload:\n" . $xml);
+				$this->setError($err);
+			} else {
+				$this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
+				// get final value
+				$this->soapresponse = $this->message[$this->root_struct]['result'];
+				// get header value: no, because this is documented as XML string
+//				if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
+//					$this->responseHeaders = $this->message[$this->root_header]['result'];
+//				}
+				// resolve hrefs/ids
+				if(sizeof($this->multirefs) > 0){
+					foreach($this->multirefs as $id => $hrefs){
+						$this->debug('resolving multirefs for id: '.$id);
+						$idVal = $this->buildVal($this->ids[$id]);
+						if (is_array($idVal) && isset($idVal['!id'])) {
+							unset($idVal['!id']);
+						}
+						foreach($hrefs as $refPos => $ref){
+							$this->debug('resolving href at pos '.$refPos);
+							$this->multirefs[$id][$refPos] = $idVal;
+						}
+					}
+				}
+			}
+			xml_parser_free($this->parser);
+		} else {
+			$this->debug('xml was empty, didn\'t parse!');
+			$this->setError('xml was empty, didn\'t parse!');
+		}
+	}
+
+	/**
+	* start-element handler
+	*
+	* @param    resource $parser XML parser object
+	* @param    string $name element name
+	* @param    array $attrs associative array of attributes
+	* @access   private
+	*/
+	function start_element($parser, $name, $attrs) {
+		// position in a total number of elements, starting from 0
+		// update class level pos
+		$pos = $this->position++;
+		// and set mine
+		$this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
+		// depth = how many levels removed from root?
+		// set mine as current global depth and increment global depth value
+		$this->message[$pos]['depth'] = $this->depth++;
+
+		// else add self as child to whoever the current parent is
+		if($pos != 0){
+			$this->message[$this->parent]['children'] .= '|'.$pos;
+		}
+		// set my parent
+		$this->message[$pos]['parent'] = $this->parent;
+		// set self as current parent
+		$this->parent = $pos;
+		// set self as current value for this depth
+		$this->depth_array[$this->depth] = $pos;
+		// get element prefix
+		if(strpos($name,':')){
+			// get ns prefix
+			$prefix = substr($name,0,strpos($name,':'));
+			// get unqualified name
+			$name = substr(strstr($name,':'),1);
+		}
+		// set status
+		if($name == 'Envelope'){
+			$this->status = 'envelope';
+		} elseif($name == 'Header'){
+			$this->root_header = $pos;
+			$this->status = 'header';
+		} elseif($name == 'Body'){
+			$this->status = 'body';
+			$this->body_position = $pos;
+		// set method
+		} elseif($this->status == 'body' && $pos == ($this->body_position+1)){
+			$this->status = 'method';
+			$this->root_struct_name = $name;
+			$this->root_struct = $pos;
+			$this->message[$pos]['type'] = 'struct';
+			$this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
+		}
+		// set my status
+		$this->message[$pos]['status'] = $this->status;
+		// set name
+		$this->message[$pos]['name'] = htmlspecialchars($name);
+		// set attrs
+		$this->message[$pos]['attrs'] = $attrs;
+
+		// loop through atts, logging ns and type declarations
+        $attstr = '';
+		foreach($attrs as $key => $value){
+        	$key_prefix = $this->getPrefix($key);
+			$key_localpart = $this->getLocalPart($key);
+			// if ns declarations, add to class level array of valid namespaces
+            if($key_prefix == 'xmlns'){
+				if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){
+					$this->XMLSchemaVersion = $value;
+					$this->namespaces['xsd'] = $this->XMLSchemaVersion;
+					$this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
+				}
+                $this->namespaces[$key_localpart] = $value;
+				// set method namespace
+				if($name == $this->root_struct_name){
+					$this->methodNamespace = $value;
+				}
+			// if it's a type declaration, set type
+            } elseif($key_localpart == 'type'){
+            	$value_prefix = $this->getPrefix($value);
+                $value_localpart = $this->getLocalPart($value);
+				$this->message[$pos]['type'] = $value_localpart;
+				$this->message[$pos]['typePrefix'] = $value_prefix;
+                if(isset($this->namespaces[$value_prefix])){
+                	$this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
+                } else if(isset($attrs['xmlns:'.$value_prefix])) {
+					$this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
+                }
+				// should do something here with the namespace of specified type?
+			} elseif($key_localpart == 'arrayType'){
+				$this->message[$pos]['type'] = 'array';
+				/* do arrayType ereg here
+				[1]    arrayTypeValue    ::=    atype asize
+				[2]    atype    ::=    QName rank*
+				[3]    rank    ::=    '[' (',')* ']'
+				[4]    asize    ::=    '[' length~ ']'
+				[5]    length    ::=    nextDimension* Digit+
+				[6]    nextDimension    ::=    Digit+ ','
+				*/
+				$expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]';
+				if(ereg($expr,$value,$regs)){
+					$this->message[$pos]['typePrefix'] = $regs[1];
+					$this->message[$pos]['arrayTypePrefix'] = $regs[1];
+	                if (isset($this->namespaces[$regs[1]])) {
+	                	$this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
+	                } else if (isset($attrs['xmlns:'.$regs[1]])) {
+						$this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
+	                }
+					$this->message[$pos]['arrayType'] = $regs[2];
+					$this->message[$pos]['arraySize'] = $regs[3];
+					$this->message[$pos]['arrayCols'] = $regs[4];
+				}
+			// specifies nil value (or not)
+			} elseif ($key_localpart == 'nil'){
+				$this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
+			// some other attribute
+			} elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
+				$this->message[$pos]['xattrs']['!' . $key] = $value;
+			}
+
+			if ($key == 'xmlns') {
+				$this->default_namespace = $value;
+			}
+			// log id
+			if($key == 'id'){
+				$this->ids[$value] = $pos;
+			}
+			// root
+			if($key_localpart == 'root' && $value == 1){
+				$this->status = 'method';
+				$this->root_struct_name = $name;
+				$this->root_struct = $pos;
+				$this->debug("found root struct $this->root_struct_name, pos $pos");
+			}
+            // for doclit
+            $attstr .= " $key=\"$value\"";
+		}
+        // get namespace - must be done after namespace atts are processed
+		if(isset($prefix)){
+			$this->message[$pos]['namespace'] = $this->namespaces[$prefix];
+			$this->default_namespace = $this->namespaces[$prefix];
+		} else {
+			$this->message[$pos]['namespace'] = $this->default_namespace;
+		}
+        if($this->status == 'header'){
+        	if ($this->root_header != $pos) {
+	        	$this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
+	        }
+        } elseif($this->root_struct_name != ''){
+        	$this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
+        }
+	}
+
+	/**
+	* end-element handler
+	*
+	* @param    resource $parser XML parser object
+	* @param    string $name element name
+	* @access   private
+	*/
+	function end_element($parser, $name) {
+		// position of current element is equal to the last value left in depth_array for my depth
+		$pos = $this->depth_array[$this->depth--];
+
+        // get element prefix
+		if(strpos($name,':')){
+			// get ns prefix
+			$prefix = substr($name,0,strpos($name,':'));
+			// get unqualified name
+			$name = substr(strstr($name,':'),1);
+		}
+		
+		// build to native type
+		if(isset($this->body_position) && $pos > $this->body_position){
+			// deal w/ multirefs
+			if(isset($this->message[$pos]['attrs']['href'])){
+				// get id
+				$id = substr($this->message[$pos]['attrs']['href'],1);
+				// add placeholder to href array
+				$this->multirefs[$id][$pos] = 'placeholder';
+				// add set a reference to it as the result value
+				$this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
+            // build complexType values
+			} elseif($this->message[$pos]['children'] != ''){
+				// if result has already been generated (struct/array)
+				if(!isset($this->message[$pos]['result'])){
+					$this->message[$pos]['result'] = $this->buildVal($pos);
+				}
+			// build complexType values of attributes and possibly simpleContent
+			} elseif (isset($this->message[$pos]['xattrs'])) {
+				if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
+					$this->message[$pos]['xattrs']['!'] = null;
+				} elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
+	            	if (isset($this->message[$pos]['type'])) {
+						$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+					} else {
+						$parent = $this->message[$pos]['parent'];
+						if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
+							$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+						} else {
+							$this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
+						}
+					}
+				}
+				$this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
+			// set value of simpleType (or nil complexType)
+			} else {
+            	//$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
+				if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
+					$this->message[$pos]['xattrs']['!'] = null;
+				} elseif (isset($this->message[$pos]['type'])) {
+					$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+				} else {
+					$parent = $this->message[$pos]['parent'];
+					if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
+						$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+					} else {
+						$this->message[$pos]['result'] = $this->message[$pos]['cdata'];
+					}
+				}
+
+				/* add value to parent's result, if parent is struct/array
+				$parent = $this->message[$pos]['parent'];
+				if($this->message[$parent]['type'] != 'map'){
+					if(strtolower($this->message[$parent]['type']) == 'array'){
+						$this->message[$parent]['result'][] = $this->message[$pos]['result'];
+					} else {
+						$this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
+					}
+				}
+				*/
+			}
+		}
+		
+        // for doclit
+        if($this->status == 'header'){
+        	if ($this->root_header != $pos) {
+	        	$this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
+	        }
+        } elseif($pos >= $this->root_struct){
+        	$this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
+        }
+		// switch status
+		if($pos == $this->root_struct){
+			$this->status = 'body';
+			$this->root_struct_namespace = $this->message[$pos]['namespace'];
+		} elseif($name == 'Body'){
+			$this->status = 'envelope';
+		 } elseif($name == 'Header'){
+			$this->status = 'envelope';
+		} elseif($name == 'Envelope'){
+			//
+		}
+		// set parent back to my parent
+		$this->parent = $this->message[$pos]['parent'];
+	}
+
+	/**
+	* element content handler
+	*
+	* @param    resource $parser XML parser object
+	* @param    string $data element content
+	* @access   private
+	*/
+	function character_data($parser, $data){
+		$pos = $this->depth_array[$this->depth];
+		if ($this->xml_encoding=='UTF-8'){
+			// TODO: add an option to disable this for folks who want
+			// raw UTF-8 that, e.g., might not map to iso-8859-1
+			// TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
+			if($this->decode_utf8){
+				$data = utf8_decode($data);
+			}
+		}
+        $this->message[$pos]['cdata'] .= $data;
+        // for doclit
+        if($this->status == 'header'){
+        	$this->responseHeaders .= $data;
+        } else {
+        	$this->document .= $data;
+        }
+	}
+
+	/**
+	* get the parsed message
+	*
+	* @return	mixed
+	* @access   public
+	*/
+	function get_response(){
+		return $this->soapresponse;
+	}
+
+	/**
+	* get the parsed headers
+	*
+	* @return	string XML or empty if no headers
+	* @access   public
+	*/
+	function getHeaders(){
+	    return $this->responseHeaders;
+	}
+
+	/**
+	* decodes simple types into PHP variables
+	*
+	* @param    string $value value to decode
+	* @param    string $type XML type to decode
+	* @param    string $typens XML type namespace to decode
+	* @return	mixed PHP value
+	* @access   private
+	*/
+	function decodeSimple($value, $type, $typens) {
+		// TODO: use the namespace!
+		if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
+			return (string) $value;
+		}
+		if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
+			return (int) $value;
+		}
+		if ($type == 'float' || $type == 'double' || $type == 'decimal') {
+			return (double) $value;
+		}
+		if ($type == 'boolean') {
+			if (strtolower($value) == 'false' || strtolower($value) == 'f') {
+				return false;
+			}
+			return (boolean) $value;
+		}
+		if ($type == 'base64' || $type == 'base64Binary') {
+			$this->debug('Decode base64 value');
+			return base64_decode($value);
+		}
+		// obscure numeric types
+		if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
+			|| $type == 'nonNegativeInteger' || $type == 'positiveInteger'
+			|| $type == 'unsignedInt'
+			|| $type == 'unsignedShort' || $type == 'unsignedByte') {
+			return (int) $value;
+		}
+		// bogus: parser treats array with no elements as a simple type
+		if ($type == 'array') {
+			return array();
+		}
+		// everything else
+		return (string) $value;
+	}
+
+	/**
+	* builds response structures for compound values (arrays/structs)
+	* and scalars
+	*
+	* @param    integer $pos position in node tree
+	* @return	mixed	PHP value
+	* @access   private
+	*/
+	function buildVal($pos){
+		if(!isset($this->message[$pos]['type'])){
+			$this->message[$pos]['type'] = '';
+		}
+		$this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
+		// if there are children...
+		if($this->message[$pos]['children'] != ''){
+			$this->debug('in buildVal, there are children');
+			$children = explode('|',$this->message[$pos]['children']);
+			array_shift($children); // knock off empty
+			// md array
+			if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
+            	$r=0; // rowcount
+            	$c=0; // colcount
+            	foreach($children as $child_pos){
+					$this->debug("in buildVal, got an MD array element: $r, $c");
+					$params[$r][] = $this->message[$child_pos]['result'];
+				    $c++;
+				    if($c == $this->message[$pos]['arrayCols']){
+				    	$c = 0;
+						$r++;
+				    }
+                }
+            // array
+			} elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
+                $this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
+                foreach($children as $child_pos){
+                	$params[] = &$this->message[$child_pos]['result'];
+                }
+            // apache Map type: java hashtable
+            } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
+                $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
+                foreach($children as $child_pos){
+                	$kv = explode("|",$this->message[$child_pos]['children']);
+                   	$params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
+                }
+            // generic compound type
+            //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
+		    } else {
+	    		// Apache Vector type: treat as an array
+                $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']);
+				if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
+					$notstruct = 1;
+				} else {
+					$notstruct = 0;
+	            }
+            	//
+            	foreach($children as $child_pos){
+            		if($notstruct){
+            			$params[] = &$this->message[$child_pos]['result'];
+            		} else {
+            			if (isset($params[$this->message[$child_pos]['name']])) {
+            				// de-serialize repeated element name into an array
+            				if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
+            					$params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
+            				}
+            				$params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
+            			} else {
+					    	$params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
+					    }
+                	}
+                }
+			}
+			if (isset($this->message[$pos]['xattrs'])) {
+                $this->debug('in buildVal, handling attributes');
+				foreach ($this->message[$pos]['xattrs'] as $n => $v) {
+					$params[$n] = $v;
+				}
+			}
+			// handle simpleContent
+			if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
+                $this->debug('in buildVal, handling simpleContent');
+            	if (isset($this->message[$pos]['type'])) {
+					$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+				} else {
+					$parent = $this->message[$pos]['parent'];
+					if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
+						$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+					} else {
+						$params['!'] = $this->message[$pos]['cdata'];
+					}
+				}
+			}
+			return is_array($params) ? $params : array();
+		} else {
+        	$this->debug('in buildVal, no children, building scalar');
+			$cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
+        	if (isset($this->message[$pos]['type'])) {
+				return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+			}
+			$parent = $this->message[$pos]['parent'];
+			if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
+				return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+			}
+           	return $this->message[$pos]['cdata'];
+		}
+	}
+}
+
+
+
+?><?php
+
+
+
+/**
+*
+* soapclient_nusoap higher level class for easy usage.
+*
+* usage:
+*
+* // instantiate client with server info
+* $soapclient = new soapclient_nusoap( string path [ ,boolean wsdl] );
+*
+* // call method, get results
+* echo $soapclient->call( string methodname [ ,array parameters] );
+*
+* // bye bye client
+* unset($soapclient);
+*
+* @author   Dietrich Ayala <dietrich@ganx4.com>
+* @version  $Id$
+* @access   public
+*/
+class soapclient_nusoap extends nusoap_base  {
+
+	var $username = '';
+	var $password = '';
+	var $authtype = '';
+	var $certRequest = array();
+	var $requestHeaders = false;	// SOAP headers in request (text)
+	var $responseHeaders = '';		// SOAP headers from response (incomplete namespace resolution) (text)
+	var $document = '';				// SOAP body response portion (incomplete namespace resolution) (text)
+	var $endpoint;
+	var $forceEndpoint = '';		// overrides WSDL endpoint
+    var $proxyhost = '';
+    var $proxyport = '';
+	var $proxyusername = '';
+	var $proxypassword = '';
+    var $xml_encoding = '';			// character set encoding of incoming (response) messages
+	var $http_encoding = false;
+	var $timeout = 0;				// HTTP connection timeout
+	var $response_timeout = 30;		// HTTP response timeout
+	var $endpointType = '';			// soap|wsdl, empty for WSDL initialization error
+	var $persistentConnection = false;
+	var $defaultRpcParams = false;	// This is no longer used
+	var $request = '';				// HTTP request
+	var $response = '';				// HTTP response
+	var $responseData = '';			// SOAP payload of response
+	var $cookies = array();			// Cookies from response or for request
+    var $decode_utf8 = true;		// toggles whether the parser decodes element content w/ utf8_decode()
+	var $operations = array();		// WSDL operations, empty for WSDL initialization error
+	
+	/*
+	 * fault related variables
+	 */
+	/**
+	 * @var      fault
+	 * @access   public
+	 */
+	var $fault;
+	/**
+	 * @var      faultcode
+	 * @access   public
+	 */
+	var $faultcode;
+	/**
+	 * @var      faultstring
+	 * @access   public
+	 */
+	var $faultstring;
+	/**
+	 * @var      faultdetail
+	 * @access   public
+	 */
+	var $faultdetail;
+
+	/**
+	* constructor
+	*
+	* @param    mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object)
+	* @param    bool $wsdl optional, set to true if using WSDL
+	* @param	int $portName optional portName in WSDL document
+	* @param    string $proxyhost
+	* @param    string $proxyport
+	* @param	string $proxyusername
+	* @param	string $proxypassword
+	* @param	integer $timeout set the connection timeout
+	* @param	integer $response_timeout set the response timeout
+	* @access   public
+	*/
+	function soapclient_nusoap($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
+		parent::nusoap_base();
+		$this->endpoint = $endpoint;
+		$this->proxyhost = $proxyhost;
+		$this->proxyport = $proxyport;
+		$this->proxyusername = $proxyusername;
+		$this->proxypassword = $proxypassword;
+		$this->timeout = $timeout;
+		$this->response_timeout = $response_timeout;
+
+		// make values
+		if($wsdl){
+			if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
+				$this->wsdl = $endpoint;
+				$this->endpoint = $this->wsdl->wsdl;
+				$this->wsdlFile = $this->endpoint;
+				$this->debug('existing wsdl instance created from ' . $this->endpoint);
+			} else {
+				$this->wsdlFile = $this->endpoint;
+				
+				// instantiate wsdl object and parse wsdl file
+				$this->debug('instantiating wsdl class with doc: '.$endpoint);
+				$this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout);
+			}
+			$this->appendDebug($this->wsdl->getDebug());
+			$this->wsdl->clearDebug();
+			// catch errors
+			if($errstr = $this->wsdl->getError()){
+				$this->debug('got wsdl error: '.$errstr);
+				$this->setError('wsdl error: '.$errstr);
+			} elseif($this->operations = $this->wsdl->getOperations()){
+				$this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile);
+				$this->endpointType = 'wsdl';
+			} else {
+				$this->debug( 'getOperations returned false');
+				$this->setError('no operations defined in the WSDL document!');
+			}
+		} else {
+			$this->debug("instantiate SOAP with endpoint at $endpoint");
+			$this->endpointType = 'soap';
+		}
+	}
+
+	/**
+	* calls method, returns PHP native type
+	*
+	* @param    string $method SOAP server URL or path
+	* @param    mixed $params An array, associative or simple, of the parameters
+	*			              for the method call, or a string that is the XML
+	*			              for the call.  For rpc style, this call will
+	*			              wrap the XML in a tag named after the method, as
+	*			              well as the SOAP Envelope and Body.  For document
+	*			              style, this will only wrap with the Envelope and Body.
+	*			              IMPORTANT: when using an array with document style,
+	*			              in which case there
+	*                         is really one parameter, the root of the fragment
+	*                         used in the call, which encloses what programmers
+	*                         normally think of parameters.  A parameter array
+	*                         *must* include the wrapper.
+	* @param	string $namespace optional method namespace (WSDL can override)
+	* @param	string $soapAction optional SOAPAction value (WSDL can override)
+	* @param	mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
+	* @param	boolean $rpcParams optional (no longer used)
+	* @param	string	$style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
+	* @param	string	$use optional (encoded|literal) the use when serializing parameters (WSDL can override)
+	* @return	mixed	response from SOAP call
+	* @access   public
+	*/
+	function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
+		$this->operation = $operation;
+		$this->fault = false;
+		$this->setError('');
+		$this->request = '';
+		$this->response = '';
+		$this->responseData = '';
+		$this->faultstring = '';
+		$this->faultcode = '';
+		$this->opData = array();
+		
+		$this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
+		$this->appendDebug('params=' . $this->varDump($params));
+		$this->appendDebug('headers=' . $this->varDump($headers));
+		if ($headers) {
+			$this->requestHeaders = $headers;
+		}
+		// serialize parameters
+		if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
+			// use WSDL for operation
+			$this->opData = $opData;
+			$this->debug("found operation");
+			$this->appendDebug('opData=' . $this->varDump($opData));
+			if (isset($opData['soapAction'])) {
+				$soapAction = $opData['soapAction'];
+			}
+			if (! $this->forceEndpoint) {
+				$this->endpoint = $opData['endpoint'];
+			} else {
+				$this->endpoint = $this->forceEndpoint;
+			}
+			$namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] :	$namespace;
+			$style = $opData['style'];
+			$use = $opData['input']['use'];
+			// add ns to ns array
+			if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
+				$nsPrefix = 'ns' . rand(1000, 9999);
+				$this->wsdl->namespaces[$nsPrefix] = $namespace;
+			}
+            $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
+			// serialize payload
+			if (is_string($params)) {
+				$this->debug("serializing param string for WSDL operation $operation");
+				$payload = $params;
+			} elseif (is_array($params)) {
+				$this->debug("serializing param array for WSDL operation $operation");
+				$payload = $this->wsdl->serializeRPCParameters($operation,'input',$params);
+			} else {
+				$this->debug('params must be array or string');
+				$this->setError('params must be array or string');
+				return false;
+			}
+            $usedNamespaces = $this->wsdl->usedNamespaces;
+			if (isset($opData['input']['encodingStyle'])) {
+				$encodingStyle = $opData['input']['encodingStyle'];
+			} else {
+				$encodingStyle = '';
+			}
+			$this->appendDebug($this->wsdl->getDebug());
+			$this->wsdl->clearDebug();
+			if ($errstr = $this->wsdl->getError()) {
+				$this->debug('got wsdl error: '.$errstr);
+				$this->setError('wsdl error: '.$errstr);
+				return false;
+			}
+		} elseif($this->endpointType == 'wsdl') {
+			// operation not in WSDL
+			$this->appendDebug($this->wsdl->getDebug());
+			$this->wsdl->clearDebug();
+			$this->setError( 'operation '.$operation.' not present.');
+			$this->debug("operation '$operation' not present.");
+			return false;
+		} else {
+			// no WSDL
+			//$this->namespaces['ns1'] = $namespace;
+			$nsPrefix = 'ns' . rand(1000, 9999);
+			// serialize 
+			$payload = '';
+			if (is_string($params)) {
+				$this->debug("serializing param string for operation $operation");
+				$payload = $params;
+			} elseif (is_array($params)) {
+				$this->debug("serializing param array for operation $operation");
+				foreach($params as $k => $v){
+					$payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
+				}
+			} else {
+				$this->debug('params must be array or string');
+				$this->setError('params must be array or string');
+				return false;
+			}
+			$usedNamespaces = array();
+			if ($use == 'encoded') {
+				$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
+			} else {
+				$encodingStyle = '';
+			}
+		}
+		// wrap RPC calls with method element
+		if ($style == 'rpc') {
+			if ($use == 'literal') {
+				$this->debug("wrapping RPC request with literal method element");
+				if ($namespace) {
+					$payload = "<$operation xmlns=\"$namespace\">" . $payload . "</$operation>";
+				} else {
+					$payload = "<$operation>" . $payload . "</$operation>";
+				}
+			} else {
+				$this->debug("wrapping RPC request with encoded method element");
+				if ($namespace) {
+					$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
+								$payload .
+								"</$nsPrefix:$operation>";
+				} else {
+					$payload = "<$operation>" .
+								$payload .
+								"</$operation>";
+				}
+			}
+		}
+		// serialize envelope
+		$soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
+		$this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
+		$this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
+		// send
+		$return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
+		if($errstr = $this->getError()){
+			$this->debug('Error: '.$errstr);
+			return false;
+		} else {
+			$this->return = $return;
+			$this->debug('sent message successfully and got a(n) '.gettype($return));
+           	$this->appendDebug('return=' . $this->varDump($return));
+			
+			// fault?
+			if(is_array($return) && isset($return['faultcode'])){
+				$this->debug('got fault');
+				$this->setError($return['faultcode'].': '.$return['faultstring']);
+				$this->fault = true;
+				foreach($return as $k => $v){
+					$this->$k = $v;
+					$this->debug("$k = $v<br>");
+				}
+				return $return;
+			} elseif ($style == 'document') {
+				// NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
+				// we are only going to return the first part here...sorry about that
+				return $return;
+			} else {
+				// array of return values
+				if(is_array($return)){
+					// multiple 'out' parameters, which we return wrapped up
+					// in the array
+					if(sizeof($return) > 1){
+						return $return;
+					}
+					// single 'out' parameter (normally the return value)
+					$return = array_shift($return);
+					$this->debug('return shifted value: ');
+					$this->appendDebug($this->varDump($return));
+           			return $return;
+				// nothing returned (ie, echoVoid)
+				} else {
+					return "";
+				}
+			}
+		}
+	}
+
+	/**
+	* get available data pertaining to an operation
+	*
+	* @param    string $operation operation name
+	* @return	array array of data pertaining to the operation
+	* @access   public
+	*/
+	function getOperationData($operation){
+		if(isset($this->operations[$operation])){
+			return $this->operations[$operation];
+		}
+		$this->debug("No data for operation: $operation");
+	}
+
+    /**
+    * send the SOAP message
+    *
+    * Note: if the operation has multiple return values
+    * the return value of this method will be an array
+    * of those values.
+    *
+	* @param    string $msg a SOAPx4 soapmsg object
+	* @param    string $soapaction SOAPAction value
+	* @param    integer $timeout set connection timeout in seconds
+	* @param	integer $response_timeout set response timeout in seconds
+	* @return	mixed native PHP types.
+	* @access   private
+	*/
+	function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
+		$this->checkCookies();
+		// detect transport
+		switch(true){
+			// http(s)
+			case ereg('^http',$this->endpoint):
+				$this->debug('transporting via HTTP');
+				if($this->persistentConnection == true && is_object($this->persistentConnection)){
+					$http =& $this->persistentConnection;
+				} else {
+					$http = new soap_transport_http($this->endpoint);
+					if ($this->persistentConnection) {
+						$http->usePersistentConnection();
+					}
+				}
+				$http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
+				$http->setSOAPAction($soapaction);
+				if($this->proxyhost && $this->proxyport){
+					$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
+				}
+                if($this->authtype != '') {
+					$http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
+				}
+				if($this->http_encoding != ''){
+					$http->setEncoding($this->http_encoding);
+				}
+				$this->debug('sending message, length='.strlen($msg));
+				if(ereg('^http:',$this->endpoint)){
+				//if(strpos($this->endpoint,'http:')){
+					$this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
+				} elseif(ereg('^https',$this->endpoint)){
+				//} elseif(strpos($this->endpoint,'https:')){
+					//if(phpversion() == '4.3.0-dev'){
+						//$response = $http->send($msg,$timeout,$response_timeout);
+                   		//$this->request = $http->outgoing_payload;
+						//$this->response = $http->incoming_payload;
+					//} else
+					$this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
+				} else {
+					$this->setError('no http/s in endpoint url');
+				}
+				$this->request = $http->outgoing_payload;
+				$this->response = $http->incoming_payload;
+				$this->appendDebug($http->getDebug());
+				$this->UpdateCookies($http->incoming_cookies);
+
+				// save transport object if using persistent connections
+				if ($this->persistentConnection) {
+					$http->clearDebug();
+					if (!is_object($this->persistentConnection)) {
+						$this->persistentConnection = $http;
+					}
+				}
+				
+				if($err = $http->getError()){
+					$this->setError('HTTP Error: '.$err);
+					return false;
+				} elseif($this->getError()){
+					return false;
+				} else {
+					$this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
+					return $this->parseResponse($http->incoming_headers, $this->responseData);
+				}
+			break;
+			default:
+				$this->setError('no transport found, or selected transport is not yet supported!');
+			return false;
+			break;
+		}
+	}
+
+	/**
+	* processes SOAP message returned from server
+	*
+	* @param	array	$headers	The HTTP headers
+	* @param	string	$data		unprocessed response data from server
+	* @return	mixed	value of the message, decoded into a PHP type
+	* @access   private
+	*/
+    function parseResponse($headers, $data) {
+		$this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
+		if (!strstr($headers['content-type'], 'text/xml')) {
+			$this->setError('Response not of type text/xml');
+			return false;
+		}
+		if (strpos($headers['content-type'], '=')) {
+			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
+			$this->debug('Got response encoding: ' . $enc);
+			if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
+				$this->xml_encoding = strtoupper($enc);
+			} else {
+				$this->xml_encoding = 'US-ASCII';
+			}
+		} else {
+			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
+			$this->xml_encoding = 'ISO-8859-1';
+		}
+		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
+		$parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
+		// add parser debug data to our debug
+		$this->appendDebug($parser->getDebug());
+		// if parse errors
+		if($errstr = $parser->getError()){
+			$this->setError( $errstr);
+			// destroy the parser object
+			unset($parser);
+			return false;
+		} else {
+			// get SOAP headers
+			$this->responseHeaders = $parser->getHeaders();
+			// get decoded message
+			$return = $parser->get_response();
+            // add document for doclit support
+            $this->document = $parser->document;
+			// destroy the parser object
+			unset($parser);
+			// return decode message
+			return $return;
+		}
+	 }
+
+	/**
+	* sets the SOAP endpoint, which can override WSDL
+	*
+	* @param	$endpoint string The endpoint URL to use, or empty string or false to prevent override
+	* @access   public
+	*/
+	function setEndpoint($endpoint) {
+		$this->forceEndpoint = $endpoint;
+	}
+
+	/**
+	* set the SOAP headers
+	*
+	* @param	$headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers
+	* @access   public
+	*/
+	function setHeaders($headers){
+		$this->requestHeaders = $headers;
+	}
+
+	/**
+	* get the SOAP response headers (namespace resolution incomplete)
+	*
+	* @return	string
+	* @access   public
+	*/
+	function getHeaders(){
+		return $this->responseHeaders;
+	}
+
+	/**
+	* set proxy info here
+	*
+	* @param    string $proxyhost
+	* @param    string $proxyport
+	* @param	string $proxyusername
+	* @param	string $proxypassword
+	* @access   public
+	*/
+	function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
+		$this->proxyhost = $proxyhost;
+		$this->proxyport = $proxyport;
+		$this->proxyusername = $proxyusername;
+		$this->proxypassword = $proxypassword;
+	}
+
+	/**
+	* if authenticating, set user credentials here
+	*
+	* @param    string $username
+	* @param    string $password
+	* @param	string $authtype (basic|digest|certificate)
+	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
+	* @access   public
+	*/
+	function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
+		$this->username = $username;
+		$this->password = $password;
+		$this->authtype = $authtype;
+		$this->certRequest = $certRequest;
+	}
+	
+	/**
+	* use HTTP encoding
+	*
+	* @param    string $enc
+	* @access   public
+	*/
+	function setHTTPEncoding($enc='gzip, deflate'){
+		$this->http_encoding = $enc;
+	}
+	
+	/**
+	* use HTTP persistent connections if possible
+	*
+	* @access   public
+	*/
+	function useHTTPPersistentConnection(){
+		$this->persistentConnection = true;
+	}
+	
+	/**
+	* gets the default RPC parameter setting.
+	* If true, default is that call params are like RPC even for document style.
+	* Each call() can override this value.
+	*
+	* This is no longer used.
+	*
+	* @return boolean
+	* @access public
+	* @deprecated
+	*/
+	function getDefaultRpcParams() {
+		return $this->defaultRpcParams;
+	}
+
+	/**
+	* sets the default RPC parameter setting.
+	* If true, default is that call params are like RPC even for document style
+	* Each call() can override this value.
+	*
+	* This is no longer used.
+	*
+	* @param    boolean $rpcParams
+	* @access public
+	* @deprecated
+	*/
+	function setDefaultRpcParams($rpcParams) {
+		$this->defaultRpcParams = $rpcParams;
+	}
+	
+	/**
+	* dynamically creates an instance of a proxy class,
+	* allowing user to directly call methods from wsdl
+	*
+	* @return   object soap_proxy object
+	* @access   public
+	*/
+	function getProxy(){
+		$r = rand();
+		$evalStr = $this->_getProxyClassCode($r);
+		//$this->debug("proxy class: $evalStr";
+		// eval the class
+		eval($evalStr);
+		// instantiate proxy object
+		eval("\$proxy = new soap_proxy_$r('');");
+		// transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
+		$proxy->endpointType = 'wsdl';
+		$proxy->wsdlFile = $this->wsdlFile;
+		$proxy->wsdl = $this->wsdl;
+		$proxy->operations = $this->operations;
+		$proxy->defaultRpcParams = $this->defaultRpcParams;
+		// transfer other state
+		$proxy->username = $this->username;
+		$proxy->password = $this->password;
+		$proxy->authtype = $this->authtype;
+		$proxy->proxyhost = $this->proxyhost;
+		$proxy->proxyport = $this->proxyport;
+		$proxy->proxyusername = $this->proxyusername;
+		$proxy->proxypassword = $this->proxypassword;
+		$proxy->timeout = $this->timeout;
+		$proxy->response_timeout = $this->response_timeout;
+		$proxy->http_encoding = $this->http_encoding;
+		$proxy->persistentConnection = $this->persistentConnection;
+		$proxy->requestHeaders = $this->requestHeaders;
+		$proxy->soap_defencoding = $this->soap_defencoding;
+		$proxy->endpoint = $this->endpoint;
+		$proxy->forceEndpoint = $this->forceEndpoint;
+		return $proxy;
+	}
+
+	/**
+	* dynamically creates proxy class code
+	*
+	* @return   string PHP/NuSOAP code for the proxy class
+	* @access   private
+	*/
+	function _getProxyClassCode($r) {
+		if ($this->endpointType != 'wsdl') {
+			$evalStr = 'A proxy can only be created for a WSDL client';
+			$this->setError($evalStr);
+			return $evalStr;
+		}
+		$evalStr = '';
+		foreach ($this->operations as $operation => $opData) {
+			if ($operation != '') {
+				// create param string and param comment string
+				if (sizeof($opData['input']['parts']) > 0) {
+					$paramStr = '';
+					$paramArrayStr = '';
+					$paramCommentStr = '';
+					foreach ($opData['input']['parts'] as $name => $type) {
+						$paramStr .= "\$$name, ";
+						$paramArrayStr .= "'$name' => \$$name, ";
+						$paramCommentStr .= "$type \$$name, ";
+					}
+					$paramStr = substr($paramStr, 0, strlen($paramStr)-2);
+					$paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
+					$paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
+				} else {
+					$paramStr = '';
+					$paramCommentStr = 'void';
+				}
+				$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
+				$evalStr .= "// $paramCommentStr
+	function " . str_replace('.', '__', $operation) . "($paramStr) {
+		\$params = array($paramArrayStr);
+		return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
+	}
+	";
+				unset($paramStr);
+				unset($paramCommentStr);
+			}
+		}
+		$evalStr = 'class soap_proxy_'.$r.' extends soapclient_nusoap {
+	'.$evalStr.'
+}';
+		return $evalStr;
+	}
+
+	/**
+	* dynamically creates proxy class code
+	*
+	* @return   string PHP/NuSOAP code for the proxy class
+	* @access   public
+	*/
+	function getProxyClassCode() {
+		$r = rand();
+		return $this->_getProxyClassCode($r);
+	}
+
+	/**
+	* gets the HTTP body for the current request.
+	*
+	* @param string $soapmsg The SOAP payload
+	* @return string The HTTP body, which includes the SOAP payload
+	* @access private
+	*/
+	function getHTTPBody($soapmsg) {
+		return $soapmsg;
+	}
+	
+	/**
+	* gets the HTTP content type for the current request.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type for the current request.
+	* @access private
+	*/
+	function getHTTPContentType() {
+		return 'text/xml';
+	}
+	
+	/**
+	* gets the HTTP content type charset for the current request.
+	* returns false for non-text content types.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type charset for the current request.
+	* @access private
+	*/
+	function getHTTPContentTypeCharset() {
+		return $this->soap_defencoding;
+	}
+
+	/*
+	* whether or not parser should decode utf8 element content
+    *
+    * @return   always returns true
+    * @access   public
+    */
+    function decodeUTF8($bool){
+		$this->decode_utf8 = $bool;
+		return true;
+    }
+
+	/**
+	 * adds a new Cookie into $this->cookies array
+	 *
+	 * @param	string $name Cookie Name
+	 * @param	string $value Cookie Value
+	 * @return	if cookie-set was successful returns true, else false
+	 * @access	public
+	 */
+	function setCookie($name, $value) {
+		if (strlen($name) == 0) {
+			return false;
+		}
+		$this->cookies[] = array('name' => $name, 'value' => $value);
+		return true;
+	}
+
+	/**
+	 * gets all Cookies
+	 *
+	 * @return   array with all internal cookies
+	 * @access   public
+	 */
+	function getCookies() {
+		return $this->cookies;
+	}
+
+	/**
+	 * checks all Cookies and delete those which are expired
+	 *
+	 * @return   always return true
+	 * @access   private
+	 */
+	function checkCookies() {
+		if (sizeof($this->cookies) == 0) {
+			return true;
+		}
+		$this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
+		$curr_cookies = $this->cookies;
+		$this->cookies = array();
+		foreach ($curr_cookies as $cookie) {
+			if (! is_array($cookie)) {
+				$this->debug('Remove cookie that is not an array');
+				continue;
+			}
+			if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
+				if (strtotime($cookie['expires']) > time()) {
+					$this->cookies[] = $cookie;
+				} else {
+					$this->debug('Remove expired cookie ' . $cookie['name']);
+				}
+			} else {
+				$this->cookies[] = $cookie;
+			}
+		}
+		$this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
+		return true;
+	}
+
+	/**
+	 * updates the current cookies with a new set
+	 *
+	 * @param	array $cookies new cookies with which to update current ones
+	 * @return	always return true
+	 * @access	private
+	 */
+	function UpdateCookies($cookies) {
+		if (sizeof($this->cookies) == 0) {
+			// no existing cookies: take whatever is new
+			if (sizeof($cookies) > 0) {
+				$this->debug('Setting new cookie(s)');
+				$this->cookies = $cookies;
+			}
+			return true;
+		}
+		if (sizeof($cookies) == 0) {
+			// no new cookies: keep what we've got
+			return true;
+		}
+		// merge
+		foreach ($cookies as $newCookie) {
+			if (!is_array($newCookie)) {
+				continue;
+			}
+			if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
+				continue;
+			}
+			$newName = $newCookie['name'];
+
+			$found = false;
+			for ($i = 0; $i < count($this->cookies); $i++) {
+				$cookie = $this->cookies[$i];
+				if (!is_array($cookie)) {
+					continue;
+				}
+				if (!isset($cookie['name'])) {
+					continue;
+				}
+				if ($newName != $cookie['name']) {
+					continue;
+				}
+				$newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
+				$domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
+				if ($newDomain != $domain) {
+					continue;
+				}
+				$newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
+				$path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
+				if ($newPath != $path) {
+					continue;
+				}
+				$this->cookies[$i] = $newCookie;
+				$found = true;
+				$this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
+				break;
+			}
+			if (! $found) {
+				$this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
+				$this->cookies[] = $newCookie;
+			}
+		}
+		return true;
+	}
+}
+?>
diff --git a/htdocs/oscommerce_ws/ws_server/lib/nusoapmime.php b/htdocs/oscommerce_ws/ws_server/lib/nusoapmime.php
index 61909c91f478463857be7236d1a50b5a47a9b765..12b6702b86e80f47041e61ddecedab9198afc6f1 100644
--- a/htdocs/oscommerce_ws/ws_server/lib/nusoapmime.php
+++ b/htdocs/oscommerce_ws/ws_server/lib/nusoapmime.php
@@ -1,478 +1,478 @@
-<?php
-/*
-$Id$
-
-NuSOAP - Web Services Toolkit for PHP
-
-Copyright (c) 2002 NuSphere Corporation
-
-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
-
-If you have any questions or comments, please email:
-
-Dietrich Ayala
-dietrich@ganx4.com
-http://dietrich.ganx4.com/nusoap
-
-NuSphere Corporation
-http://www.nusphere.com
-
-*/
-
-/*require_once('nusoap.php');*/
-/* PEAR Mail_MIME library */
-require_once('Mail/mimeDecode.php');
-require_once('Mail/mimePart.php');
-
-/**
-* soapclientmime client supporting MIME attachments defined at
-* http://www.w3.org/TR/SOAP-attachments.  It depends on the PEAR Mail_MIME library.
-*
-* @author   Scott Nichol <snichol@sourceforge.net>
-* @author	Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
-* @version  $Id$
-* @access   public
-*/
-class soapclientmime extends soapclient_nusoap {
-	/**
-	 * @var array Each array element in the return is an associative array with keys
-	 * data, filename, contenttype, cid
-	 * @access private
-	 */
-	var $requestAttachments = array();
-	/**
-	 * @var array Each array element in the return is an associative array with keys
-	 * data, filename, contenttype, cid
-	 * @access private
-	 */
-	var $responseAttachments;
-	/**
-	 * @var string
-	 * @access private
-	 */
-	var $mimeContentType;
-	
-	/**
-	* adds a MIME attachment to the current request.
-	*
-	* If the $data parameter contains an empty string, this method will read
-	* the contents of the file named by the $filename parameter.
-	*
-	* If the $cid parameter is false, this method will generate the cid.
-	*
-	* @param string $data The data of the attachment
-	* @param string $filename The filename of the attachment (default is empty string)
-	* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
-	* @param string $cid The content-id (cid) of the attachment (default is false)
-	* @return string The content-id (cid) of the attachment
-	* @access public
-	*/
-	function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
-		if (! $cid) {
-			$cid = md5(uniqid(time()));
-		}
-
-		$info['data'] = $data;
-		$info['filename'] = $filename;
-		$info['contenttype'] = $contenttype;
-		$info['cid'] = $cid;
-		
-		$this->requestAttachments[] = $info;
-
-		return $cid;
-	}
-
-	/**
-	* clears the MIME attachments for the current request.
-	*
-	* @access public
-	*/
-	function clearAttachments() {
-		$this->requestAttachments = array();
-	}
-
-	/**
-	* gets the MIME attachments from the current response.
-	*
-	* Each array element in the return is an associative array with keys
-	* data, filename, contenttype, cid.  These keys correspond to the parameters
-	* for addAttachment.
-	*
-	* @return array The attachments.
-	* @access public
-	*/
-	function getAttachments() {
-		return $this->responseAttachments;
-	}
-
-	/**
-	* gets the HTTP body for the current request.
-	*
-	* @param string $soapmsg The SOAP payload
-	* @return string The HTTP body, which includes the SOAP payload
-	* @access private
-	*/
-	function getHTTPBody($soapmsg) {
-		if (count($this->requestAttachments) > 0) {
-			$params['content_type'] = 'multipart/related; type=text/xml';
-			$mimeMessage =& new Mail_mimePart('', $params);
-			unset($params);
-
-			$params['content_type'] = 'text/xml';
-			$params['encoding']     = '8bit';
-			$params['charset']      = $this->soap_defencoding;
-			$mimeMessage->addSubpart($soapmsg, $params);
-			
-			foreach ($this->requestAttachments as $att) {
-				unset($params);
-
-				$params['content_type'] = $att['contenttype'];
-				$params['encoding']     = 'base64';
-				$params['disposition']  = 'attachment';
-				$params['dfilename']    = $att['filename'];
-				$params['cid']          = $att['cid'];
-
-				if ($att['data'] == '' && $att['filename'] <> '') {
-					if ($fd = fopen($att['filename'], 'rb')) {
-						$data = fread($fd, filesize($att['filename']));
-						fclose($fd);
-					} else {
-						$data = '';
-					}
-					$mimeMessage->addSubpart($data, $params);
-				} else {
-					$mimeMessage->addSubpart($att['data'], $params);
-				}
-			}
-
-			$output = $mimeMessage->encode();
-			$mimeHeaders = $output['headers'];
-	
-			foreach ($mimeHeaders as $k => $v) {
-				$this->debug("MIME header $k: $v");
-				if (strtolower($k) == 'content-type') {
-					// PHP header() seems to strip leading whitespace starting
-					// the second line, so force everything to one line
-					$this->mimeContentType = str_replace("\r\n", " ", $v);
-				}
-			}
-	
-			return $output['body'];
-		}
-
-		return parent::getHTTPBody($soapmsg);
-	}
-	
-	/**
-	* gets the HTTP content type for the current request.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type for the current request.
-	* @access private
-	*/
-	function getHTTPContentType() {
-		if (count($this->requestAttachments) > 0) {
-			return $this->mimeContentType;
-		}
-		return parent::getHTTPContentType();
-	}
-	
-	/**
-	* gets the HTTP content type charset for the current request.
-	* returns false for non-text content types.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type charset for the current request.
-	* @access private
-	*/
-	function getHTTPContentTypeCharset() {
-		if (count($this->requestAttachments) > 0) {
-			return false;
-		}
-		return parent::getHTTPContentTypeCharset();
-	}
-
-	/**
-	* processes SOAP message returned from server
-	*
-	* @param	array	$headers	The HTTP headers
-	* @param	string	$data		unprocessed response data from server
-	* @return	mixed	value of the message, decoded into a PHP type
-	* @access   private
-	*/
-    function parseResponse($headers, $data) {
-		$this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
-		$this->responseAttachments = array();
-		if (strstr($headers['content-type'], 'multipart/related')) {
-			$this->debug('Decode multipart/related');
-			$input = '';
-			foreach ($headers as $k => $v) {
-				$input .= "$k: $v\r\n";
-			}
-			$params['input'] = $input . "\r\n" . $data;
-			$params['include_bodies'] = true;
-			$params['decode_bodies'] = true;
-			$params['decode_headers'] = true;
-			
-			$structure = Mail_mimeDecode::decode($params);
-
-			foreach ($structure->parts as $part) {
-				if (!isset($part->disposition)) {
-					$this->debug('Have root part of type ' . $part->headers['content-type']);
-					$return = parent::parseResponse($part->headers, $part->body);
-				} else {
-					$this->debug('Have an attachment of type ' . $part->headers['content-type']);
-					$info['data'] = $part->body;
-					$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
-					$info['contenttype'] = $part->headers['content-type'];
-					$info['cid'] = $part->headers['content-id'];
-					$this->responseAttachments[] = $info;
-				}
-			}
-		
-			if (isset($return)) {
-				return $return;
-			}
-			
-			$this->setError('No root part found in multipart/related content');
-			return;
-		}
-		$this->debug('Not multipart/related');
-		return parent::parseResponse($headers, $data);
-	}
-}
-
-/**
-* nusoapservermime server supporting MIME attachments defined at
-* http://www.w3.org/TR/SOAP-attachments.  It depends on the PEAR Mail_MIME library.
-*
-* @author   Scott Nichol <snichol@sourceforge.net>
-* @author	Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
-* @version  $Id$
-* @access   public
-*/
-class nusoapservermime extends soap_server {
-	/**
-	 * @var array Each array element in the return is an associative array with keys
-	 * data, filename, contenttype, cid
-	 * @access private
-	 */
-	var $requestAttachments = array();
-	/**
-	 * @var array Each array element in the return is an associative array with keys
-	 * data, filename, contenttype, cid
-	 * @access private
-	 */
-	var $responseAttachments;
-	/**
-	 * @var string
-	 * @access private
-	 */
-	var $mimeContentType;
-	
-	/**
-	* adds a MIME attachment to the current response.
-	*
-	* If the $data parameter contains an empty string, this method will read
-	* the contents of the file named by the $filename parameter.
-	*
-	* If the $cid parameter is false, this method will generate the cid.
-	*
-	* @param string $data The data of the attachment
-	* @param string $filename The filename of the attachment (default is empty string)
-	* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
-	* @param string $cid The content-id (cid) of the attachment (default is false)
-	* @return string The content-id (cid) of the attachment
-	* @access public
-	*/
-	function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
-		if (! $cid) {
-			$cid = md5(uniqid(time()));
-		}
-
-		$info['data'] = $data;
-		$info['filename'] = $filename;
-		$info['contenttype'] = $contenttype;
-		$info['cid'] = $cid;
-		
-		$this->responseAttachments[] = $info;
-
-		return $cid;
-	}
-
-	/**
-	* clears the MIME attachments for the current response.
-	*
-	* @access public
-	*/
-	function clearAttachments() {
-		$this->responseAttachments = array();
-	}
-
-	/**
-	* gets the MIME attachments from the current request.
-	*
-	* Each array element in the return is an associative array with keys
-	* data, filename, contenttype, cid.  These keys correspond to the parameters
-	* for addAttachment.
-	*
-	* @return array The attachments.
-	* @access public
-	*/
-	function getAttachments() {
-		return $this->requestAttachments;
-	}
-
-	/**
-	* gets the HTTP body for the current response.
-	*
-	* @param string $soapmsg The SOAP payload
-	* @return string The HTTP body, which includes the SOAP payload
-	* @access private
-	*/
-	function getHTTPBody($soapmsg) {
-		if (count($this->responseAttachments) > 0) {
-			$params['content_type'] = 'multipart/related; type=text/xml';
-			$mimeMessage =& new Mail_mimePart('', $params);
-			unset($params);
-
-			$params['content_type'] = 'text/xml';
-			$params['encoding']     = '8bit';
-			$params['charset']      = $this->soap_defencoding;
-			$mimeMessage->addSubpart($soapmsg, $params);
-			
-			foreach ($this->responseAttachments as $att) {
-				unset($params);
-
-				$params['content_type'] = $att['contenttype'];
-				$params['encoding']     = 'base64';
-				$params['disposition']  = 'attachment';
-				$params['dfilename']    = $att['filename'];
-				$params['cid']          = $att['cid'];
-
-				if ($att['data'] == '' && $att['filename'] <> '') {
-					if ($fd = fopen($att['filename'], 'rb')) {
-						$data = fread($fd, filesize($att['filename']));
-						fclose($fd);
-					} else {
-						$data = '';
-					}
-					$mimeMessage->addSubpart($data, $params);
-				} else {
-					$mimeMessage->addSubpart($att['data'], $params);
-				}
-			}
-
-			$output = $mimeMessage->encode();
-			$mimeHeaders = $output['headers'];
-	
-			foreach ($mimeHeaders as $k => $v) {
-				$this->debug("MIME header $k: $v");
-				if (strtolower($k) == 'content-type') {
-					// PHP header() seems to strip leading whitespace starting
-					// the second line, so force everything to one line
-					$this->mimeContentType = str_replace("\r\n", " ", $v);
-				}
-			}
-	
-			return $output['body'];
-		}
-
-		return parent::getHTTPBody($soapmsg);
-	}
-	
-	/**
-	* gets the HTTP content type for the current response.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type for the current response.
-	* @access private
-	*/
-	function getHTTPContentType() {
-		if (count($this->responseAttachments) > 0) {
-			return $this->mimeContentType;
-		}
-		return parent::getHTTPContentType();
-	}
-	
-	/**
-	* gets the HTTP content type charset for the current response.
-	* returns false for non-text content types.
-	*
-	* Note: getHTTPBody must be called before this.
-	*
-	* @return string the HTTP content type charset for the current response.
-	* @access private
-	*/
-	function getHTTPContentTypeCharset() {
-		if (count($this->responseAttachments) > 0) {
-			return false;
-		}
-		return parent::getHTTPContentTypeCharset();
-	}
-
-	/**
-	* processes SOAP message received from client
-	*
-	* @param	array	$headers	The HTTP headers
-	* @param	string	$data		unprocessed request data from client
-	* @return	mixed	value of the message, decoded into a PHP type
-	* @access   private
-	*/
-    function parseRequest($headers, $data) {
-		$this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
-		$this->requestAttachments = array();
-		if (strstr($headers['content-type'], 'multipart/related')) {
-			$this->debug('Decode multipart/related');
-			$input = '';
-			foreach ($headers as $k => $v) {
-				$input .= "$k: $v\r\n";
-			}
-			$params['input'] = $input . "\r\n" . $data;
-			$params['include_bodies'] = true;
-			$params['decode_bodies'] = true;
-			$params['decode_headers'] = true;
-			
-			$structure = Mail_mimeDecode::decode($params);
-
-			foreach ($structure->parts as $part) {
-				if (!isset($part->disposition)) {
-					$this->debug('Have root part of type ' . $part->headers['content-type']);
-					$return = parent::parseRequest($part->headers, $part->body);
-				} else {
-					$this->debug('Have an attachment of type ' . $part->headers['content-type']);
-					$info['data'] = $part->body;
-					$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
-					$info['contenttype'] = $part->headers['content-type'];
-					$info['cid'] = $part->headers['content-id'];
-					$this->requestAttachments[] = $info;
-				}
-			}
-		
-			if (isset($return)) {
-				return $return;
-			}
-			
-			$this->setError('No root part found in multipart/related content');
-			return;
-		}
-		$this->debug('Not multipart/related');
-		return parent::parseRequest($headers, $data);
-	}
-}
-?>
+<?php
+/*
+$Id$
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+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
+
+If you have any questions or comments, please email:
+
+Dietrich Ayala
+dietrich@ganx4.com
+http://dietrich.ganx4.com/nusoap
+
+NuSphere Corporation
+http://www.nusphere.com
+
+*/
+
+/*require_once('nusoap.php');*/
+/* PEAR Mail_MIME library */
+require_once('Mail/mimeDecode.php');
+require_once('Mail/mimePart.php');
+
+/**
+* soapclientmime client supporting MIME attachments defined at
+* http://www.w3.org/TR/SOAP-attachments.  It depends on the PEAR Mail_MIME library.
+*
+* @author   Scott Nichol <snichol@sourceforge.net>
+* @author	Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
+* @version  $Id$
+* @access   public
+*/
+class soapclientmime extends soapclient_nusoap {
+	/**
+	 * @var array Each array element in the return is an associative array with keys
+	 * data, filename, contenttype, cid
+	 * @access private
+	 */
+	var $requestAttachments = array();
+	/**
+	 * @var array Each array element in the return is an associative array with keys
+	 * data, filename, contenttype, cid
+	 * @access private
+	 */
+	var $responseAttachments;
+	/**
+	 * @var string
+	 * @access private
+	 */
+	var $mimeContentType;
+	
+	/**
+	* adds a MIME attachment to the current request.
+	*
+	* If the $data parameter contains an empty string, this method will read
+	* the contents of the file named by the $filename parameter.
+	*
+	* If the $cid parameter is false, this method will generate the cid.
+	*
+	* @param string $data The data of the attachment
+	* @param string $filename The filename of the attachment (default is empty string)
+	* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
+	* @param string $cid The content-id (cid) of the attachment (default is false)
+	* @return string The content-id (cid) of the attachment
+	* @access public
+	*/
+	function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
+		if (! $cid) {
+			$cid = md5(uniqid(time()));
+		}
+
+		$info['data'] = $data;
+		$info['filename'] = $filename;
+		$info['contenttype'] = $contenttype;
+		$info['cid'] = $cid;
+		
+		$this->requestAttachments[] = $info;
+
+		return $cid;
+	}
+
+	/**
+	* clears the MIME attachments for the current request.
+	*
+	* @access public
+	*/
+	function clearAttachments() {
+		$this->requestAttachments = array();
+	}
+
+	/**
+	* gets the MIME attachments from the current response.
+	*
+	* Each array element in the return is an associative array with keys
+	* data, filename, contenttype, cid.  These keys correspond to the parameters
+	* for addAttachment.
+	*
+	* @return array The attachments.
+	* @access public
+	*/
+	function getAttachments() {
+		return $this->responseAttachments;
+	}
+
+	/**
+	* gets the HTTP body for the current request.
+	*
+	* @param string $soapmsg The SOAP payload
+	* @return string The HTTP body, which includes the SOAP payload
+	* @access private
+	*/
+	function getHTTPBody($soapmsg) {
+		if (count($this->requestAttachments) > 0) {
+			$params['content_type'] = 'multipart/related; type=text/xml';
+			$mimeMessage =& new Mail_mimePart('', $params);
+			unset($params);
+
+			$params['content_type'] = 'text/xml';
+			$params['encoding']     = '8bit';
+			$params['charset']      = $this->soap_defencoding;
+			$mimeMessage->addSubpart($soapmsg, $params);
+			
+			foreach ($this->requestAttachments as $att) {
+				unset($params);
+
+				$params['content_type'] = $att['contenttype'];
+				$params['encoding']     = 'base64';
+				$params['disposition']  = 'attachment';
+				$params['dfilename']    = $att['filename'];
+				$params['cid']          = $att['cid'];
+
+				if ($att['data'] == '' && $att['filename'] <> '') {
+					if ($fd = fopen($att['filename'], 'rb')) {
+						$data = fread($fd, filesize($att['filename']));
+						fclose($fd);
+					} else {
+						$data = '';
+					}
+					$mimeMessage->addSubpart($data, $params);
+				} else {
+					$mimeMessage->addSubpart($att['data'], $params);
+				}
+			}
+
+			$output = $mimeMessage->encode();
+			$mimeHeaders = $output['headers'];
+	
+			foreach ($mimeHeaders as $k => $v) {
+				$this->debug("MIME header $k: $v");
+				if (strtolower($k) == 'content-type') {
+					// PHP header() seems to strip leading whitespace starting
+					// the second line, so force everything to one line
+					$this->mimeContentType = str_replace("\r\n", " ", $v);
+				}
+			}
+	
+			return $output['body'];
+		}
+
+		return parent::getHTTPBody($soapmsg);
+	}
+	
+	/**
+	* gets the HTTP content type for the current request.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type for the current request.
+	* @access private
+	*/
+	function getHTTPContentType() {
+		if (count($this->requestAttachments) > 0) {
+			return $this->mimeContentType;
+		}
+		return parent::getHTTPContentType();
+	}
+	
+	/**
+	* gets the HTTP content type charset for the current request.
+	* returns false for non-text content types.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type charset for the current request.
+	* @access private
+	*/
+	function getHTTPContentTypeCharset() {
+		if (count($this->requestAttachments) > 0) {
+			return false;
+		}
+		return parent::getHTTPContentTypeCharset();
+	}
+
+	/**
+	* processes SOAP message returned from server
+	*
+	* @param	array	$headers	The HTTP headers
+	* @param	string	$data		unprocessed response data from server
+	* @return	mixed	value of the message, decoded into a PHP type
+	* @access   private
+	*/
+    function parseResponse($headers, $data) {
+		$this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
+		$this->responseAttachments = array();
+		if (strstr($headers['content-type'], 'multipart/related')) {
+			$this->debug('Decode multipart/related');
+			$input = '';
+			foreach ($headers as $k => $v) {
+				$input .= "$k: $v\r\n";
+			}
+			$params['input'] = $input . "\r\n" . $data;
+			$params['include_bodies'] = true;
+			$params['decode_bodies'] = true;
+			$params['decode_headers'] = true;
+			
+			$structure = Mail_mimeDecode::decode($params);
+
+			foreach ($structure->parts as $part) {
+				if (!isset($part->disposition)) {
+					$this->debug('Have root part of type ' . $part->headers['content-type']);
+					$return = parent::parseResponse($part->headers, $part->body);
+				} else {
+					$this->debug('Have an attachment of type ' . $part->headers['content-type']);
+					$info['data'] = $part->body;
+					$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
+					$info['contenttype'] = $part->headers['content-type'];
+					$info['cid'] = $part->headers['content-id'];
+					$this->responseAttachments[] = $info;
+				}
+			}
+		
+			if (isset($return)) {
+				return $return;
+			}
+			
+			$this->setError('No root part found in multipart/related content');
+			return;
+		}
+		$this->debug('Not multipart/related');
+		return parent::parseResponse($headers, $data);
+	}
+}
+
+/**
+* nusoapservermime server supporting MIME attachments defined at
+* http://www.w3.org/TR/SOAP-attachments.  It depends on the PEAR Mail_MIME library.
+*
+* @author   Scott Nichol <snichol@sourceforge.net>
+* @author	Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
+* @version  $Id$
+* @access   public
+*/
+class nusoapservermime extends soap_server {
+	/**
+	 * @var array Each array element in the return is an associative array with keys
+	 * data, filename, contenttype, cid
+	 * @access private
+	 */
+	var $requestAttachments = array();
+	/**
+	 * @var array Each array element in the return is an associative array with keys
+	 * data, filename, contenttype, cid
+	 * @access private
+	 */
+	var $responseAttachments;
+	/**
+	 * @var string
+	 * @access private
+	 */
+	var $mimeContentType;
+	
+	/**
+	* adds a MIME attachment to the current response.
+	*
+	* If the $data parameter contains an empty string, this method will read
+	* the contents of the file named by the $filename parameter.
+	*
+	* If the $cid parameter is false, this method will generate the cid.
+	*
+	* @param string $data The data of the attachment
+	* @param string $filename The filename of the attachment (default is empty string)
+	* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
+	* @param string $cid The content-id (cid) of the attachment (default is false)
+	* @return string The content-id (cid) of the attachment
+	* @access public
+	*/
+	function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
+		if (! $cid) {
+			$cid = md5(uniqid(time()));
+		}
+
+		$info['data'] = $data;
+		$info['filename'] = $filename;
+		$info['contenttype'] = $contenttype;
+		$info['cid'] = $cid;
+		
+		$this->responseAttachments[] = $info;
+
+		return $cid;
+	}
+
+	/**
+	* clears the MIME attachments for the current response.
+	*
+	* @access public
+	*/
+	function clearAttachments() {
+		$this->responseAttachments = array();
+	}
+
+	/**
+	* gets the MIME attachments from the current request.
+	*
+	* Each array element in the return is an associative array with keys
+	* data, filename, contenttype, cid.  These keys correspond to the parameters
+	* for addAttachment.
+	*
+	* @return array The attachments.
+	* @access public
+	*/
+	function getAttachments() {
+		return $this->requestAttachments;
+	}
+
+	/**
+	* gets the HTTP body for the current response.
+	*
+	* @param string $soapmsg The SOAP payload
+	* @return string The HTTP body, which includes the SOAP payload
+	* @access private
+	*/
+	function getHTTPBody($soapmsg) {
+		if (count($this->responseAttachments) > 0) {
+			$params['content_type'] = 'multipart/related; type=text/xml';
+			$mimeMessage =& new Mail_mimePart('', $params);
+			unset($params);
+
+			$params['content_type'] = 'text/xml';
+			$params['encoding']     = '8bit';
+			$params['charset']      = $this->soap_defencoding;
+			$mimeMessage->addSubpart($soapmsg, $params);
+			
+			foreach ($this->responseAttachments as $att) {
+				unset($params);
+
+				$params['content_type'] = $att['contenttype'];
+				$params['encoding']     = 'base64';
+				$params['disposition']  = 'attachment';
+				$params['dfilename']    = $att['filename'];
+				$params['cid']          = $att['cid'];
+
+				if ($att['data'] == '' && $att['filename'] <> '') {
+					if ($fd = fopen($att['filename'], 'rb')) {
+						$data = fread($fd, filesize($att['filename']));
+						fclose($fd);
+					} else {
+						$data = '';
+					}
+					$mimeMessage->addSubpart($data, $params);
+				} else {
+					$mimeMessage->addSubpart($att['data'], $params);
+				}
+			}
+
+			$output = $mimeMessage->encode();
+			$mimeHeaders = $output['headers'];
+	
+			foreach ($mimeHeaders as $k => $v) {
+				$this->debug("MIME header $k: $v");
+				if (strtolower($k) == 'content-type') {
+					// PHP header() seems to strip leading whitespace starting
+					// the second line, so force everything to one line
+					$this->mimeContentType = str_replace("\r\n", " ", $v);
+				}
+			}
+	
+			return $output['body'];
+		}
+
+		return parent::getHTTPBody($soapmsg);
+	}
+	
+	/**
+	* gets the HTTP content type for the current response.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type for the current response.
+	* @access private
+	*/
+	function getHTTPContentType() {
+		if (count($this->responseAttachments) > 0) {
+			return $this->mimeContentType;
+		}
+		return parent::getHTTPContentType();
+	}
+	
+	/**
+	* gets the HTTP content type charset for the current response.
+	* returns false for non-text content types.
+	*
+	* Note: getHTTPBody must be called before this.
+	*
+	* @return string the HTTP content type charset for the current response.
+	* @access private
+	*/
+	function getHTTPContentTypeCharset() {
+		if (count($this->responseAttachments) > 0) {
+			return false;
+		}
+		return parent::getHTTPContentTypeCharset();
+	}
+
+	/**
+	* processes SOAP message received from client
+	*
+	* @param	array	$headers	The HTTP headers
+	* @param	string	$data		unprocessed request data from client
+	* @return	mixed	value of the message, decoded into a PHP type
+	* @access   private
+	*/
+    function parseRequest($headers, $data) {
+		$this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
+		$this->requestAttachments = array();
+		if (strstr($headers['content-type'], 'multipart/related')) {
+			$this->debug('Decode multipart/related');
+			$input = '';
+			foreach ($headers as $k => $v) {
+				$input .= "$k: $v\r\n";
+			}
+			$params['input'] = $input . "\r\n" . $data;
+			$params['include_bodies'] = true;
+			$params['decode_bodies'] = true;
+			$params['decode_headers'] = true;
+			
+			$structure = Mail_mimeDecode::decode($params);
+
+			foreach ($structure->parts as $part) {
+				if (!isset($part->disposition)) {
+					$this->debug('Have root part of type ' . $part->headers['content-type']);
+					$return = parent::parseRequest($part->headers, $part->body);
+				} else {
+					$this->debug('Have an attachment of type ' . $part->headers['content-type']);
+					$info['data'] = $part->body;
+					$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
+					$info['contenttype'] = $part->headers['content-type'];
+					$info['cid'] = $part->headers['content-id'];
+					$this->requestAttachments[] = $info;
+				}
+			}
+		
+			if (isset($return)) {
+				return $return;
+			}
+			
+			$this->setError('No root part found in multipart/related content');
+			return;
+		}
+		$this->debug('Not multipart/related');
+		return parent::parseRequest($headers, $data);
+	}
+}
+?>
diff --git a/htdocs/theme/.cvsignore b/htdocs/theme/.cvsignore
index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644
--- a/htdocs/theme/.cvsignore
+++ b/htdocs/theme/.cvsignore
@@ -1 +1 @@
-*.db
+*.db
diff --git a/htdocs/theme/auguria/.cvsignore b/htdocs/theme/auguria/.cvsignore
index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644
--- a/htdocs/theme/auguria/.cvsignore
+++ b/htdocs/theme/auguria/.cvsignore
@@ -1 +1 @@
-*.db
+*.db
diff --git a/htdocs/theme/bluelagoon/img/.cvsignore b/htdocs/theme/bluelagoon/img/.cvsignore
index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644
--- a/htdocs/theme/bluelagoon/img/.cvsignore
+++ b/htdocs/theme/bluelagoon/img/.cvsignore
@@ -1 +1 @@
-*.db
+*.db
diff --git a/htdocs/theme/common/.cvsignore b/htdocs/theme/common/.cvsignore
index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644
--- a/htdocs/theme/common/.cvsignore
+++ b/htdocs/theme/common/.cvsignore
@@ -1 +1 @@
-*.db
+*.db
diff --git a/htdocs/theme/common/mime/.cvsignore b/htdocs/theme/common/mime/.cvsignore
index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644
--- a/htdocs/theme/common/mime/.cvsignore
+++ b/htdocs/theme/common/mime/.cvsignore
@@ -1 +1 @@
-*.db
+*.db
diff --git a/htdocs/theme/common/treemenu/.cvsignore b/htdocs/theme/common/treemenu/.cvsignore
index 020f386440732e66fc724c21c1af2b723a402f79..78d24c2393017b5f628370404fbb29c91ccccc47 100644
--- a/htdocs/theme/common/treemenu/.cvsignore
+++ b/htdocs/theme/common/treemenu/.cvsignore
@@ -1,2 +1,2 @@
-*.db
-*.db
+*.db
+*.db
diff --git a/htdocs/theme/dev/img/.cvsignore b/htdocs/theme/dev/img/.cvsignore
index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644
--- a/htdocs/theme/dev/img/.cvsignore
+++ b/htdocs/theme/dev/img/.cvsignore
@@ -1 +1 @@
-*.db
+*.db
diff --git a/htdocs/theme/eldy/fckeditor/images/.cvsignore b/htdocs/theme/eldy/fckeditor/images/.cvsignore
index 020f386440732e66fc724c21c1af2b723a402f79..78d24c2393017b5f628370404fbb29c91ccccc47 100644
--- a/htdocs/theme/eldy/fckeditor/images/.cvsignore
+++ b/htdocs/theme/eldy/fckeditor/images/.cvsignore
@@ -1,2 +1,2 @@
-*.db
-*.db
+*.db
+*.db
diff --git a/htdocs/theme/eldy/img/.cvsignore b/htdocs/theme/eldy/img/.cvsignore
index a92ea3e3f61b3af6dee008b0256220c5731de0ab..98e6ef67fad8af56cb3721edbd420b3d6fcc0bb1 100644
--- a/htdocs/theme/eldy/img/.cvsignore
+++ b/htdocs/theme/eldy/img/.cvsignore
@@ -1 +1 @@
-*.db
+*.db