diff --git a/.tx/config b/.tx/config
index e4d1fc65732c7338a1672b6270523d8c6129d953..74875508f297e73c96d0ba800d3808f4c6422a1b 100644
--- a/.tx/config
+++ b/.tx/config
@@ -236,6 +236,18 @@ source_file = htdocs/langs/en_US/paypal.lang
 source_lang = en_US
 type = MOZILLAPROPERTIES
 
+[dolibarr.printgcp]
+file_filter = htdocs/langs/<lang>/printgcp.lang
+source_file = htdocs/langs/en_US/printgcp.lang
+source_lang = en_US
+type = MOZILLAPROPERTIES
+
+[dolibarr.printing]
+file_filter = htdocs/langs/<lang>/printing.lang
+source_file = htdocs/langs/en_US/printing.lang
+source_lang = en_US
+type = MOZILLAPROPERTIES
+
 [dolibarr.printipp]
 file_filter = htdocs/langs/<lang>/printipp.lang
 source_file = htdocs/langs/en_US/printipp.lang
diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php
index 7ef2f3bd4c9ac90e0e37dcec26bc5af55b6edca2..3efc6ba53253d44eb7b75b63f596b213fcf93683 100644
--- a/htdocs/comm/propal.php
+++ b/htdocs/comm/propal.php
@@ -550,7 +550,7 @@ else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST(
 	}
 }
 
-include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php';
+include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
 
 
 /*
diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php
index f20201ee5cc4a7ff6df76de4a2cb2e0681ffd0de..4c2e279418b8adbf9242feadadecc948847513e1 100644
--- a/htdocs/commande/card.php
+++ b/htdocs/commande/card.php
@@ -1141,7 +1141,7 @@ else if ($action == 'update_extras') {
 		$action = 'edit_extras';
 }
 
-include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php';
+include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
 
 
 /*
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index adb46ecdae91210191e5363011bd2fe2b38edb59..82b2b56d1eea2224d4da2c11b7499089d2f24ab7 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -1690,7 +1690,7 @@ else if ($action == 'remove_file') {
 	}
 }
 
-include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php';
+include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
 
 if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer)
 {
diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..431ac89a94e85e7b97781cc65900e84be2bc3578
--- /dev/null
+++ b/htdocs/core/actions_printing.inc.php
@@ -0,0 +1,64 @@
+<?php
+/* Copyright (C) 2014 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2014 Frederic France      <frederic.france@free.fr>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ * or see http://www.gnu.org/
+ */
+
+/**
+ *  \file           htdocs/core/actions_printing.inc.php
+ *  \brief          Code for actions print_file to print file with calling trigger
+ */
+
+
+// $action must be defined
+// $db, $user, $conf, $langs must be defined
+// Filename to print must be provided into 'file' parameter
+
+// Print file
+if ($action == 'print_file' and $user->rights->printing->read) 
+{
+    $langs->load("printing");
+    require_once DOL_DOCUMENT_ROOT . '/core/modules/printing/modules_printing.php';
+    $objectprint = new PrintingDriver($db);
+    $list = $objectprint->listDrivers($db, 10);
+    if (! empty($list)) {
+        $errorprint=0;
+        $printed=0;
+        foreach ($list as $driver) {
+            require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
+            $langs->load($driver);
+            $classname = 'printing_'.$driver;
+            $printer = new $classname($db);
+            //print '<pre>'.print_r($printer, true).'</pre>';
+
+            if (! empty($conf->global->{$printer->active})) {
+                $subdir=(GETPOST('printer', 'alpha')=='expedition'?'sending':'');
+                $errorprint = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha'), $subdir);
+                //if ($errorprint < 0) {
+                //    setEventMessage($interface->errors, 'errors');
+                //}
+                if ($errorprint=='') {
+                    setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file'))).' '.$langs->trans("ViaModule").' '.$printer->name);
+                    $printed++;
+                }
+            }
+        }
+        if ($printed==0) setEventMessage($langs->trans("NoActivePrintingModuleFound"));
+    } else {
+        setEventMessage($langs->trans("NoModuleFound"), 'warning');
+    }
+    $action = '';
+}
diff --git a/htdocs/core/actions_printipp.inc.php b/htdocs/core/actions_printipp.inc.php
deleted file mode 100644
index 3c18faa813b19b6f6400c37e61221669c639de29..0000000000000000000000000000000000000000
--- a/htdocs/core/actions_printipp.inc.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-/* Copyright (C) 2014 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 3 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, see <http://www.gnu.org/licenses/>.
- * or see http://www.gnu.org/
- */
-
-/**
- *	\file			htdocs/core/actions_printipp.inc.php
- *  \brief			Code for actions print_file to print file using ipp
- */
-
-
-// $action must be defined
-// $db, $user, $conf, $langs must be defined
-// Filename to print must be provided into 'file' parameter
-
-// Print file
-if ($action == 'print_file' and $user->rights->printipp->read) 
-{
-	$langs->load("printipp");
-	require_once DOL_DOCUMENT_ROOT . '/core/class/dolprintipp.class.php';
-	$printer = new dolPrintIPP($db, $conf->global->PRINTIPP_HOST, $conf->global->PRINTIPP_PORT, $user->login, $conf->global->PRINTIPP_USER, $conf->global->PRINTIPP_PASSWORD);
-	$result = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha'));
-	if ($result)
-	{
-		setEventMessage($result,'warnings');
-	}
-	else
-	{
-		setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file'))));
-	}
-	$action = '';
-}
diff --git a/htdocs/core/class/dolprintipp.class.php b/htdocs/core/class/dolprintipp.class.php
index b6e09547743b2bad1c3b53236ce482239c04d7cc..252b742cc9d52a19ed7a68f2339db9b64cfbeddd 100644
--- a/htdocs/core/class/dolprintipp.class.php
+++ b/htdocs/core/class/dolprintipp.class.php
@@ -28,7 +28,7 @@ class dolprintIPP
 {
     var $host;
     var $port;
-    var $userid;	/* user login */
+    var $userid;    /* user login */
     var $user;
     var $password;
     var $error;
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index bea2fa7347e1043f0ae5b500ee5e6dc912bb254d..91bf047f88a0bbd81ed2accf49d1cfb661d70781 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -273,9 +273,9 @@ class FormFile
         }
 
         $printer=0;
-        if (in_array($modulepart,array('facture','propal','proposal','order','commande')))	// This feature is implemented only for such elements
+        if (in_array($modulepart,array('facture','propal','proposal','order','commande','expedition')))	// This feature is implemented only for such elements
         {
-        	$printer = (!empty($user->rights->printipp->read) && !empty($conf->printipp->enabled))?true:false;
+            $printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false;
         }
 
         $hookmanager->initHooks(array('formfile'));
@@ -604,8 +604,8 @@ class FormFile
 						$out.= '<td align="right">';
 						if ($delallowed)
 						{
-							$out.= '<a href="'.$urlsource.(strpos($urlsource,'?')?'&':'?').'action=remove_file&file='.urlencode($relativepath);
-							$out.= ($param?'&'.$param:'');
+							$out.= '<a href="'.$urlsource.(strpos($urlsource,'?')?'&amp;':'?').'action=remove_file&amp;file='.urlencode($relativepath);
+							$out.= ($param?'&amp;'.$param:'');
 							//$out.= '&modulepart='.$modulepart; // TODO obsolete ?
 							//$out.= '&urlsource='.urlencode($urlsource); // TODO obsolete ?
 							$out.= '">'.img_picto($langs->trans("Delete"), 'delete.png').'</a>';
@@ -614,9 +614,9 @@ class FormFile
 						if ($printer)
 						{
 							//$out.= '<td align="right">';
-    	                    $out.= '&nbsp;<a href="'.$urlsource.(strpos($urlsource,'?')?'&':'?').'action=print_file&amp;printer='.$modulepart.'&amp;file='.urlencode($relativepath);
-        	                $out.= ($param?'&'.$param:'');
-            	            $out.= '">'.img_picto($langs->trans("Print"),'printer.png').'</a>';
+                            $out.= '&nbsp;<a href="'.$urlsource.(strpos($urlsource,'?')?'&amp;':'?').'action=print_file&amp;printer='.$modulepart.'&amp;file='.urlencode($relativepath);
+                            $out.= ($param?'&amp;'.$param:'');
+                            $out.= '">'.img_picto($langs->trans("PrintFile", $relativepath),'printer.png').'</a>';
 						}
 						if ($morepicto)
 						{
diff --git a/htdocs/core/modules/modPrintIPP.class.php b/htdocs/core/modules/modPrinting.class.php
similarity index 59%
rename from htdocs/core/modules/modPrintIPP.class.php
rename to htdocs/core/modules/modPrinting.class.php
index 3cdcd6cdfa65448208942199b75d1dd91cd73bbe..f578c463d43326dac7aba67f19b28f29c10a06eb 100644
--- a/htdocs/core/modules/modPrintIPP.class.php
+++ b/htdocs/core/modules/modPrinting.class.php
@@ -1,5 +1,6 @@
 <?php
-/* Copyright (C) 2013 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* Copyright (C) 2014 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2014 Frederic France      <frederic.france@free.fr>
  *
  * 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
@@ -15,42 +16,41 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-/**     \defgroup   printipp     Module printipp
- *      \brief      Module pour imprimer via CUPS
+/**     \defgroup   printing     Module printing
+ *      \brief      Module for activation of printing icon
  */
 
 /**
- *  \file       htdocs/core/modules/modPrintIPP.class.php
- *  \ingroup    printipp
- *  \brief      Fichier de description et activation du module OSCommerce2
+ *  \file       htdocs/core/modules/modPrinting.class.php
+ *  \ingroup    printing
+ *  \brief      Fichier de description et activation du module Printing
  */
-include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php");
+include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
 
 
 
 /**
- *  \class      modPrintIPP
- *  \brief      Classe de description et activation du module PrintIPP
+ *  \class      modPrinting
+ *  \brief      Classe de description et activation du module Printing
  */
-class modPrintIPP extends DolibarrModules
+class modPrinting extends DolibarrModules
 {
 
-	
-	/**
-	 *	Constructor
-	 *
-	 *  @param		DoliDB		$db      Database handler
-	 */
+    /**
+     *  Constructor
+     *
+     *  @param      DoliDB      $db      Database handler
+     */
     function  __construct($db)
     {
         $this->db = $db ;
-        $this->numero = 54000;
+        $this->numero = 112000;
         // Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
         // It is used to group modules in module setup page
         $this->family = "other";
         // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
         $this->name = preg_replace('/^mod/i','',get_class($this));
-        $this->description = "Print via Cups IPP Printer.";
+        $this->description = "Enable Printing System.";
         $this->version = 'dolibarr';    // 'development' or 'experimental' or 'dolibarr' or version
         $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
         // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific)
@@ -64,16 +64,15 @@ class modPrintIPP extends DolibarrModules
         $this->dirs = array();
 
         // Config pages
-        $this->config_page_url = array("printipp.php@printipp");
+        $this->config_page_url = array("printing.php@printing");
 
         // Dependances
-        $this->hidden =  (! empty($_SERVER["WINDIR"]));
         $this->depends = array();
         $this->requiredby = array();
-        $this->phpmin = array(5,1);                 	// Minimum version of PHP required by module
-        $this->need_dolibarr_version = array(3,7,-2);  	// Minimum version of Dolibarr required by module
+        $this->phpmin = array(5,1);                     // Minimum version of PHP required by module
+        $this->need_dolibarr_version = array(3,7,-2);   // Minimum version of Dolibarr required by module
         $this->conflictwith = array();
-        $this->langfiles = array("printipp");
+        $this->langfiles = array("printing");
 
         // Constantes
         $this->const = array();
@@ -83,7 +82,7 @@ class modPrintIPP extends DolibarrModules
 
         // Permissions
         $this->rights = array();
-        $this->rights_class = 'printipp';
+        $this->rights_class = 'printing';
 
         $r=0;
         // $this->rights[$r][0]     Id permission (unique tous modules confondus)
@@ -94,8 +93,8 @@ class modPrintIPP extends DolibarrModules
         // $this->rights[$r][5]     Niveau 2 pour nommer permission dans code
 
         $r++;
-        $this->rights[$r][0] = 54001;
-        $this->rights[$r][1] = 'Printer';
+        $this->rights[$r][0] = 112001;
+        $this->rights[$r][1] = 'Printing';
         $this->rights[$r][2] = 'r';
         $this->rights[$r][3] = 1;
         $this->rights[$r][4] = 'read';
@@ -106,16 +105,16 @@ class modPrintIPP extends DolibarrModules
 
         // This is to declare the Top Menu entry:
         $this->menu[$r]=array(  'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools',               // Put 0 if this is a top menu
-                                'type'=>'left',              // This is a Top menu entry
-                                'titre'=>'Printer',
-                                'mainmenu'=>'printer',
-                                'url'=>'/printipp/index.php',
-                                'langs'=>'printipp',            // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+                                'type'=>'left',                 // This is a Top menu entry
+                                'titre'=>'Printing',
+                                'mainmenu'=>'printing',
+                                'url'=>'/printing/index.php',
+                                'langs'=>'printing',            // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
                                 'position'=>300,
-                                'enabled'=>'$conf->printipp->enabled && $leftmenu==\'modulesadmintools\'',
-                                'perms'=>'$user->rights->printipp->read',    // Use 'perms'=>'1' if you want your menu with no permission rules
+                                'enabled'=>'$conf->printing->enabled && $leftmenu==\'modulesadmintools\'',
+                                'perms'=>'$user->rights->printing->read',    // Use 'perms'=>'1' if you want your menu with no permission rules
                                 'target'=>'',
-                                'user'=>0);                 // 0=Menu for internal users, 1=external users, 2=both
+                                'user'=>0);                     // 0=Menu for internal users, 1=external users, 2=both
 
         $r++;
 
@@ -123,13 +122,13 @@ class modPrintIPP extends DolibarrModules
     }
 
     /**
-	 *		Function called when module is enabled.
-	 *		The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
-	 *		It also creates data directories
-	 *
-     *      @param      string	$options    Options when enabling module ('', 'noboxes')
-	 *      @return     int             	1 if OK, 0 if KO
-	 */
+     *   Function called when module is enabled.
+     *   The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
+     *   It also creates data directories
+     *
+     *   @param      string	$options    Options when enabling module ('', 'noboxes')
+     *   @return     int                1 if OK, 0 if KO
+     */
     function init($options='')
     {
         $sql = array();
@@ -137,15 +136,15 @@ class modPrintIPP extends DolibarrModules
         return $this->_init($sql, $options);
     }
 
-   /**
-	 *		Function called when module is disabled.
-	 *      Remove from database constants, boxes and permissions from Dolibarr database.
-	 *		Data directories are not deleted
-	 *
-     *      @param      string	$options    Options when enabling module ('', 'noboxes')
-	 *      @return     int             	1 if OK, 0 if KO
-	 */
-    	function remove($options='')
+    /**
+     *   Function called when module is disabled.
+     *   Remove from database constants, boxes and permissions from Dolibarr database.
+     *   Data directories are not deleted
+     *
+     *   @param      string $options    Options when enabling module ('', 'noboxes')
+     *   @return     int                 1 if OK, 0 if KO
+     */
+    function remove($options='')
     {
         $sql = array();
 
diff --git a/htdocs/printipp/admin/index.html b/htdocs/core/modules/printing/index.html
similarity index 100%
rename from htdocs/printipp/admin/index.html
rename to htdocs/core/modules/printing/index.html
diff --git a/htdocs/core/modules/printing/modules_printing.php b/htdocs/core/modules/printing/modules_printing.php
new file mode 100644
index 0000000000000000000000000000000000000000..3b53711f58c455aff00c418bc215864eef693938
--- /dev/null
+++ b/htdocs/core/modules/printing/modules_printing.php
@@ -0,0 +1,86 @@
+<?php
+/*
+ * Copyright (C) 2014 Frederic France      <frederic.france@free.fr>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ * or see http://www.gnu.org/
+ */
+
+/**
+ *      \file       htdocs/core/modules/mailings/modules_printing.php
+ *      \ingroup    printing
+ *      \brief      File with parent class of printing modules
+ */
+require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+
+/**
+ *      Parent class of emailing target selectors modules
+ */
+class PrintingDriver
+{
+    var $db;
+    var $error;
+
+
+    /**
+     *  Constructor
+     *
+     *  @param      DoliDB      $db      Database handler
+     */
+    function __construct($db)
+    {
+        $this->db = $db;
+    }
+
+    /**
+     *  Return list of printing driver
+     *
+     *  @param  DoliDB  $db                 Database handler
+     *  @param  string  $maxfilenamelength  Max length of value to show
+     *  @return array                       List of drivers
+    */
+    static function listDrivers($db,$maxfilenamelength=0)
+    {
+        global $conf;
+
+        $type='printing';
+        $liste=array();
+
+        $moduledir=DOL_DOCUMENT_ROOT."/core/modules/printing/";
+        $tmpfiles=dol_dir_list($moduledir,'all',0,'\modules.php','','name',SORT_ASC,0);
+        foreach($tmpfiles as $record) {
+            $list[$record['fullname']]=str_replace('.modules.php', '',$record['name']);
+        }
+
+        return $list;
+    }
+
+    /**
+     *  Return description of Printing Module
+     *
+     *  @return     string      Return translation of key PrintingModuleDescXXX where XXX is module name, or $this->desc if not exists
+     */
+    function getDesc()
+    {
+        global $langs;
+        $langs->load("printing");
+        $transstring="PrintingModuleDesc".$this->name;
+        if ($langs->trans($transstring) != $transstring) return $langs->trans($transstring);
+        else return $this->desc;
+    }
+
+}
+
diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d4cb8a2c9811398e3c44331f52be11d76276872
--- /dev/null
+++ b/htdocs/core/modules/printing/printgcp.modules.php
@@ -0,0 +1,355 @@
+<?php
+/*
+ * Copyright (C) 2014 Frederic France      <frederic.france@free.fr>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ * or see http://www.gnu.org/
+ */
+
+/**
+ *      \file       htdocs/core/modules/printing/printgcp.modules.php
+ *      \ingroup    printing
+ *      \brief      File to provide printing with Google Cloud Print
+ */
+
+include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php';
+
+/**
+ *      \class      mailing_example
+ *      \brief      Class to provide printing with Google Cloud Print
+ */
+class printing_printgcp extends PrintingDriver
+{
+    var $name = 'printgcp';
+    var $desc = 'PrintGCPDesc';
+    var $picto = 'printer';
+    var $active = 'PRINTING_PRINTGCP';
+    var $conf = array();
+    var $login = '';
+    var $password = '';
+    var $authtoken = '';
+    var $db;
+
+    const LOGIN_URL = 'https://www.google.com/accounts/ClientLogin';
+    const PRINTERS_SEARCH_URL = 'https://www.google.com/cloudprint/interface/search';
+    const PRINT_URL = 'https://www.google.com/cloudprint/interface/submit';
+
+    /**
+     *  Constructor
+     *
+     *  @param      DoliDB      $db      Database handler
+     */
+    function __construct($db)
+    {
+        global $conf;
+
+        $this->db = $db;
+        $this->login = $conf->global->PRINTGCP_LOGIN;
+        $this->password = $conf->global->PRINTGCP_PASSWORD;
+        $this->authtoken = $conf->global->PRINTGCP_AUTHTOKEN;
+        $this->conf[] = array('varname'=>'PRINTGCP_LOGIN', 'required'=>1, 'example'=>'user@gmail.com', 'type'=>'text');
+        $this->conf[] = array('varname'=>'PRINTGCP_PASSWORD', 'required'=>1, 'example'=>'', 'type'=>'password');
+    }
+
+    /**
+     *  Return list of available printers
+     *
+     *  @return string                html list of printers
+     */
+    function listAvailablePrinters()
+    {
+        global $bc, $conf, $langs;
+        $langs->load('printgcp');
+        $var=true;
+
+        $html = '<tr class="liste_titre">';
+        $html.= '<td>'.$langs->trans('GCP_Name').'</td>';
+        $html.= '<td>'.$langs->trans('GCP_displayName').'</td>';
+        $html.= '<td>'.$langs->trans('GCP_Id').'</td>';
+        $html.= '<td>'.$langs->trans('GCP_OwnerName').'</td>';
+        $html.= '<td>'.$langs->trans('GCP_State').'</td>';
+        $html.= '<td>'.$langs->trans('GCP_connectionStatus').'</td>';
+        $html.= '<td>'.$langs->trans('GCP_Type').'</td>';
+        $html.= '<td align="center">'.$langs->trans("Select").'</td>';
+        $html.= '</tr>'."\n";
+        $list = $this->getlist_available_printers();
+        //$html.= '<td><pre>'.print_r($list,true).'</pre></td>';
+        $var = true;
+        foreach ($list['available'] as $printer_det)
+        {
+            $var=!$var;
+            $html.= "<tr ".$bc[$var].">";
+            $html.= '<td>'.$printer_det['name'].'</td>';
+            $html.= '<td>'.$printer_det['displayName'].'</td>';
+            $html.= '<td>'.$printer_det['id'].'</td>';  // id to identify printer to use
+            $html.= '<td>'.$printer_det['ownerName'].'</td>';
+            $html.= '<td>'.$printer_det['status'].'</td>';
+            $html.= '<td>'.$langs->trans('STATE_'.$printer_det['connectionStatus']).'</td>';
+            $html.= '<td>'.$langs->trans('TYPE_'.$printer_det['type']).'</td>';
+            // Defaut
+            $html.= '<td align="center">';
+            if ($conf->global->PRINTING_GCP_DEFAULT == $printer_det['id'])
+            {
+                $html.= img_picto($langs->trans("Default"),'on');
+            }
+            else
+                $html.= '<a href="'.$_SERVER["PHP_SELF"].'?action=setvalue&amp;mode=test&amp;varname=PRINTING_GCP_DEFAULT&amp;driver=printgcp&amp;value='.urlencode($printer_det['id']).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>';
+            $html.= '</td>';
+            $html.= '</tr>'."\n";
+        }
+
+        return $html;
+    }
+
+    /**
+     *  Return list of available printers
+     *
+     *  @return array                list of printers
+     */
+    function getlist_available_printers()
+    {
+        global $conf,$db;
+        if ($this->authtoken=='') {
+            $this->GoogleLogin();
+        }
+        $ret['available'] = $this->get_printer_detail();
+        return $ret;
+    }
+
+    /**
+     *  List of printers
+     *
+     *  @return array      list of printers
+     */
+    function get_printer_detail()
+    {
+        // Check if we have auth token
+        if(empty($this->authtoken)) {
+            // We don't have auth token so throw exception
+            throw new Exception("Please first login to Google by calling loginToGoogle function");
+        }
+        // Prepare auth headers with auth token
+        $authheaders = array("Authorization: GoogleLogin auth=".$this->authtoken,
+                             "GData-Version: 3.0",
+                            );
+        // Make Http call to get printers added by user to Google Cloud Print
+        $responsedata = $this->makeCurl(self::PRINTERS_SEARCH_URL,array(),$authheaders);
+        $printers = json_decode($responsedata);
+        // Check if we have printers?
+        if(is_null($printers)) {
+            // We dont have printers so return blank array
+            return array();
+        } else {
+            // We have printers so returns printers as array
+            return $this->parsePrinters($printers);
+        }
+    }
+
+    /**
+     *  Print selected file
+     *
+     * @param   string      $file       file
+     * @param   string      $module     module
+     * @param   string      $subdir     subdir for file
+     * @return  string                  '' if OK, Error message if KO
+     */
+    function print_file($file, $module, $subdir='')
+    {
+        global $conf, $user, $db;
+        if ($this->authtoken=='') {
+            $this->GoogleLogin();
+        }
+        // si $module=commande_fournisseur alors $conf->fournisseur->commande->dir_output
+        $fileprint=$conf->{$module}->dir_output;
+        if ($subdir!='') $fileprint.='/'.$subdir;
+        $fileprint.='/'.$file;
+        // select printer uri for module order, propal,...
+        $sql = 'SELECT rowid, printer_id, copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printgcp" AND userid='.$user->id;
+        $result = $db->query($sql);
+        if ($result)
+        {
+            $obj = $this->db->fetch_object($result);
+            if ($obj)
+            {
+                $printer_id=$obj->printer_id;
+            }
+            else
+            {
+                if (! empty($conf->global->PRINTING_GCP_DEFAULT))
+                {
+                    $printer_id=$conf->global->PRINTING_GCP_DEFAULT;
+                }
+                else
+                {
+                    return 'NoDefaultPrinterDefined';
+                }
+            }
+        }
+
+        $this->sendPrintToPrinter($printer_id, $file, $fileprint, 'application/pdf');
+    }
+
+    /**
+     *  Sends document to the printer
+     *
+     *  @param  string      $printerid      Printer id returned by Google Cloud Print
+     *  @param  string      $printjobtitle  Job Title 
+     *  @param  string      $filepath       File Path to be send to Google Cloud Print
+     *  @param  string      $contenttype    File content type by example application/pdf, image/png
+     *  @return array                       status array
+     */
+    public function sendPrintToPrinter($printerid,$printjobtitle,$filepath,$contenttype)
+    {
+        $errors=0;
+        // Check auth token
+        if(empty($this->authtoken)) {
+            $errors++;
+            setEventMessage('Please first login to Google', 'warning');
+        }
+        // Check if printer id
+        if(empty($printerid)) {
+            $errors++;
+            setEventMessage('No provided printer ID', 'warning');
+        }
+        // Open the file which needs to be print
+        $handle = fopen($filepath, "rb");
+        if(!$handle) {
+            $errors++;
+            setEventMessage('Could not read the file.');
+        }
+        // Read file content
+        $contents = fread($handle, filesize($filepath));
+        fclose($handle);
+        // Prepare post fields for sending print
+        $post_fields = array('printerid' => $printerid,
+                             'title' => $printjobtitle,
+                             'contentTransferEncoding' => 'base64',
+                             'content' => base64_encode($contents), // encode file content as base64
+                             'contentType' => $contenttype
+                            );
+        // Prepare authorization headers
+        $authheaders = array("Authorization: GoogleLogin auth=" . $this->authtoken);
+        // Make http call for sending print Job
+        $response = json_decode($this->makeCurl(self::PRINT_URL,$post_fields,$authheaders));
+        // Has document been successfully sent?
+        if($response->success=="1") {
+            return array('status' =>true,'errorcode' =>'','errormessage'=>"");
+        } else {
+            return array('status' =>false,'errorcode' =>$response->errorCode,'errormessage'=>$response->message);
+        }
+    }
+
+
+    /**
+     *  Login into Google Account
+     *
+     *  @return string           true or false
+     */
+    function GoogleLogin()
+    {
+        global $db, $conf;
+        // Prepare post fields required for the login
+        $loginpostfields = array("accountType" => "HOSTED_OR_GOOGLE",
+                                 "Email" => $this->login,
+                                 "Passwd" => $this->password,
+                                 "service" => "cloudprint",
+                                 "source" => "GCP"
+                                );
+        // Get the Auth token
+        $loginresponse = $this->makeCurl(self::LOGIN_URL,$loginpostfields);
+        $token = $this->getAuthToken($loginresponse);
+        if(! empty($token)&&!is_null($token)) {
+            $this->authtoken = $token;
+            $result=dolibarr_set_const($db, 'PRINTGCP_AUTHTOKEN', $token, 'chaine', 0, '', $conf->entity);
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
+    /**
+     *  Parse json response and return printers array
+     *
+     *  @param  string    $jsonobj  Json response object
+     *  @return array               return array of printers
+     */
+    private function parsePrinters($jsonobj)
+    {
+        $printers = array();
+        if (isset($jsonobj->printers)) {
+            foreach ($jsonobj->printers as $gcpprinter) {
+                $printers[] = array('id' =>$gcpprinter->id,
+                                    'name' =>$gcpprinter->name,
+                                    'defaultDisplayName' =>$gcpprinter->defaultDisplayName,
+                                    'displayName' =>$gcpprinter->displayName,
+                                    'ownerId' =>$gcpprinter->ownerId,
+                                    'ownerName' =>$gcpprinter->ownerName,
+                                    'connectionStatus' =>$gcpprinter->connectionStatus,
+                                    'status' =>$gcpprinter->status,
+                                    'type' =>$gcpprinter->type
+                                    );
+            }
+        }
+        return $printers;
+    }
+
+    /**
+     *  Parse data to get auth token
+     *
+     *  @param      string  $response   response from curl
+     *  @return     string              token
+     */
+    private function getAuthToken($response)
+    {
+        // Search Auth tag
+        preg_match("/Auth=([a-z0-9_-]+)/i", $response, $matches);
+        $authtoken = @$matches[1];
+        return $authtoken;
+    }
+
+    /**
+     *  Curl request
+     *
+     *  @param  string  $url            url to hit
+     *  @param  array   $postfields     array of post fields
+     *  @param  array   $headers        array of http headers
+     *  @return array                   response from curl
+     */
+    private function makeCurl($url,$postfields=array(),$headers=array())
+    {
+        // Curl Init
+        $curl = curl_init($url);
+        // Curl post request
+        if(! empty($postfields)) {
+            // As is HTTP post curl request so set post fields
+            curl_setopt($curl, CURLOPT_POST, true);
+            curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
+        }
+        // Curl request headers
+        if(! empty($headers)) {
+            // As curl requires header so set headers here
+            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+        }
+        curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+        // Execute the curl and return response
+        $response = curl_exec($curl);
+        curl_close($curl);
+        return $response;
+    }
+
+
+}
diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8a19bffa313c06225fe00bf6523f00870c69848
--- /dev/null
+++ b/htdocs/core/modules/printing/printipp.modules.php
@@ -0,0 +1,284 @@
+<?php
+/*
+ * Copyright (C) 2014 Frederic France      <frederic.france@free.fr>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ * or see http://www.gnu.org/
+ */
+
+/**
+ *      \file       htdocs/core/modules/printing/printipp.modules.php
+ *      \ingroup    mailing
+ *      \brief      File to provide printing with PrintIPP
+ */
+
+include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php';
+
+/**
+ *      \class      mailing_example
+ *      \brief      Class to provide printing with PrintIPP
+ */
+class printing_printipp extends PrintingDriver
+{
+    var $name='printipp';
+    var $desc='PrintIPPDesc';
+    var $picto='printer';
+    var $active='PRINTING_PRINTIPP';
+    var $conf=array();
+    var $host;
+    var $port;
+    var $userid;    /* user login */
+    var $user;
+    var $password;
+    var $error;
+    var $db;
+
+
+    /**
+     *  Constructor
+     *
+     *  @param      DoliDB      $db      Database handler
+     */
+    function __construct($db)
+    {
+        global $conf;
+
+        $this->db=$db;
+        $this->host=$conf->global->PRINTIPP_HOST;
+        $this->port=$conf->global->PRINTIPP_PORT;
+        $this->user=$conf->global->PRINTIPP_USER;
+        $this->password=$conf->global->PRINTIPP_PASSWORD;
+        $this->conf[] = array('varname'=>'PRINTIPP_HOST', 'required'=>1, 'example'=>'localhost', 'type'=>'text');
+        $this->conf[] = array('varname'=>'PRINTIPP_PORT', 'required'=>1, 'example'=>'631', 'type'=>'text');
+        $this->conf[] = array('varname'=>'PRINTIPP_USER', 'required'=>0, 'example'=>'', 'type'=>'text');
+        $this->conf[] = array('varname'=>'PRINTIPP_PASSWORD', 'required'=>0, 'example'=>'', 'type'=>'password');
+    }
+
+    /**
+     *  Print selected file
+     *
+     * @param   string      $file       file
+     * @param   string      $module     module
+     * @param   string      $subdir     subdirectory of document like for expedition subdir is sendings
+     *
+     * @return  string                  '' if OK, Error message if KO
+     */
+    function print_file($file, $module, $subdir='')
+    {
+        global $conf, $user, $db;
+
+        include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php';
+        
+        $ipp = new CupsPrintIPP();
+        $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose
+        $ipp->setHost($this->host);
+        $ipp->setPort($this->port);
+        $ipp->setJobName($file,true);
+        $ipp->setUserName($this->userid);
+        if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password);
+
+        // select printer uri for module order, propal,...
+        $sql = 'SELECT rowid,printer_id,copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printipp" AND userid='.$user->id;
+        $result = $db->query($sql);
+        if ($result)
+        {
+            $obj = $this->db->fetch_object($result);
+            if ($obj)
+            {
+                $ipp->setPrinterURI($obj->printer_id);
+            }
+            else
+            {
+                if (! empty($conf->global->PRINTIPP_URI_DEFAULT))
+                {
+                    $ipp->setPrinterURI($conf->global->PRINTIPP_URI_DEFAULT);
+                }
+                else
+                {
+                    return 'NoDefaultPrinterDefined';
+                }
+            }
+        }
+        
+        // Set number of copy
+        $ipp->setCopies($obj->copy);
+        $fileprint=$conf->{$module}->dir_output;
+        if ($subdir!='') $fileprint.='/'.$subdir;
+        $fileprint.='/'.$file;
+        $ipp->setData($fileprint);
+        $ipp->printJob();
+        
+        return '';
+    }
+
+    /**
+     *  Return list of available printers
+     *
+     *  @return string                html list of printers
+     */
+    function listAvailablePrinters()
+    {
+        global $bc, $conf, $langs;
+        $var=true;
+
+        $html = '<tr class="liste_titre">';
+        $html.= '<td>'.$langs->trans('IPP_Uri').'</td>';
+        $html.= '<td>'.$langs->trans('IPP_Name').'</td>';
+        $html.= '<td>'.$langs->trans('IPP_State').'</td>';
+        $html.= '<td>'.$langs->trans('IPP_State_reason').'</td>';
+        $html.= '<td>'.$langs->trans('IPP_State_reason1').'</td>';
+        $html.= '<td>'.$langs->trans('IPP_BW').'</td>';
+        $html.= '<td>'.$langs->trans('IPP_Color').'</td>';
+        //$html.= '<td>'.$langs->trans('IPP_Device').'</td>';
+        $html.= '<td>'.$langs->trans('IPP_Media').'</td>';
+        $html.= '<td>'.$langs->trans('IPP_Supported').'</td>';
+        $html.= '<td align="center">'.$langs->trans("Select").'</td>';
+        $html.= "</tr>\n";
+        $list = $this->getlist_available_printers();
+        $var = true;
+        foreach ($list as $value)
+        {
+            $var=!$var;
+            $printer_det = $this->get_printer_detail($value);
+            $html.= "<tr ".$bc[$var].">";
+            $html.= '<td>'.$value.'</td>';
+            //$html.= '<td><pre>'.print_r($printer_det,true).'</pre></td>';
+            $html.= '<td>'.$printer_det->printer_name->_value0.'</td>';
+            $html.= '<td>'.$langs->trans('STATE_IPP_'.$printer_det->printer_state->_value0).'</td>';
+            $html.= '<td>'.$langs->trans('STATE_IPP_'.$printer_det->printer_state_reasons->_value0).'</td>';
+            $html.= '<td>'.(! empty($printer_det->printer_state_reasons->_value1)?$langs->trans('STATE_IPP_'.$printer_det->printer_state_reasons->_value1):'').'</td>';
+            $html.= '<td>'.$langs->trans('IPP_COLOR_'.$printer_det->printer_type->_value2).'</td>';
+            $html.= '<td>'.$langs->trans('IPP_COLOR_'.$printer_det->printer_type->_value3).'</td>';
+            //$html.= '<td>'.$printer_det->device_uri->_value0.'</td>';
+            $html.= '<td>'.$printer_det->media_default->_value0.'</td>';
+            $html.= '<td>'.$langs->trans('MEDIA_IPP_'.$printer_det->media_type_supported->_value1).'</td>';
+            // Defaut
+            $html.= '<td align="center">';
+            if ($conf->global->PRINTIPP_URI_DEFAULT == $value)
+            {
+                $html.= img_picto($langs->trans("Default"),'on');
+            }
+            else
+                $html.= '<a href="'.$_SERVER["PHP_SELF"].'?action=setvalue&amp;mode=test&amp;varname=PRINTIPP_URI_DEFAULT&amp;driver=printipp&amp;value='.urlencode($value).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>';
+            $html.= '</td>';
+            $html.= '</tr>'."\n";
+        }
+
+        return $html;
+    }
+
+    /**
+     *  Return list of available printers
+     *
+     *  @return array                list of printers
+     */
+    function getlist_available_printers()
+    {
+        global $conf,$db;
+        include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php';
+        $ipp = new CupsPrintIPP();
+        $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose
+        $ipp->setHost($this->host);
+        $ipp->setPort($this->port);
+        $ipp->setUserName($this->userid);
+        if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password);
+        $ipp->getPrinters();
+        return $ipp->available_printers;
+    }
+
+    /**
+     *  Get printer detail
+     *
+     *  @param  string  $uri    URI
+     *  @return array           List of attributes
+     */
+    function get_printer_detail($uri)
+    {
+        global $conf,$db;
+
+        include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php';
+        $ipp = new CupsPrintIPP();
+        $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose
+        $ipp->setHost($this->host);
+        $ipp->setPort($this->port);
+        $ipp->setUserName($this->userid);
+        if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password);
+        $ipp->setPrinterURI($uri);
+        $ipp->getPrinterAttributes();
+        return $ipp->printer_attributes;
+    }
+
+    /**
+     *  List jobs print
+     *
+     * @param   string      $module     module
+     *
+     *  @return void
+     */
+    function list_jobs($module)
+    {
+        global $conf, $db, $bc;
+        include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php';
+        $ipp = new CupsPrintIPP();
+        $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose
+        $ipp->setHost($this->host);
+        $ipp->setPort($this->port);
+        $ipp->setUserName($this->userid);
+        if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password);
+        // select printer uri for module order, propal,...
+        $sql = 'SELECT rowid,printer_uri,printer_name FROM '.MAIN_DB_PREFIX.'printer_ipp WHERE module="'.$module.'"';
+        $result = $this->db->query($sql);
+        if ($result)
+        {
+            $obj = $this->db->fetch_object($result);
+            if ($obj)
+            {
+                $ipp->setPrinterURI($obj->printer_uri);
+            }
+            else
+            {
+                // All printers
+                $ipp->setPrinterURI("ipp://localhost:631/printers/");
+            }
+        }
+        // Getting Jobs
+        $ipp->getJobs(false,0,'completed',false);
+        print '<table width="100%" class="noborder">';
+        print '<tr class="liste_titre">';
+        print "<td>Id</td>";
+        print "<td>Owner</td>";
+        print "<td>Printer</td>";
+        print "<td>File</td>";
+        print "<td>Status</td>";
+        print "<td>Cancel</td>";
+        print "</tr>\n";
+        $jobs = $ipp->jobs_attributes;
+        $var = True;
+        //print '<pre>'.print_r($jobs,true).'</pre>';
+        foreach ($jobs as $value )
+        {
+            $var=!$var;
+            print "<tr ".$bc[$var].">";
+            print '<td>'.$value->job_id->_value0.'</td>';
+            print '<td>'.$value->job_originating_user_name->_value0.'</td>';
+            print '<td>'.$value->printer_uri->_value0.'</td>';
+            print '<td>'.$value->job_name->_value0.'</td>';
+            print '<td>'.$value->job_state->_value0.'</td>';
+            print '<td>'.$value->job_uri->_value0.'</td>';
+            print '</tr>';
+        }
+        print "</table>";
+    }
+
+}
diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php
index 7ccd24f871bafc2ebcd8abd0c650b7ddb3f0e3b5..29260ba3bb61b7f72cf519ea45229f90fa16209b 100644
--- a/htdocs/expedition/card.php
+++ b/htdocs/expedition/card.php
@@ -429,6 +429,8 @@ if (GETPOST('removedfile','alpha'))
     $action ='presend';
 }
 
+include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
+
 /*
  * Send mail
 */
diff --git a/htdocs/includes/printipp/BasicIPP.php b/htdocs/includes/printipp/BasicIPP.php
index 3869c75bc06fdb01ca8617543591a156c0166273..1cc7851fab2e796db2d915625ac6ee0c3072c6c0 100644
--- a/htdocs/includes/printipp/BasicIPP.php
+++ b/htdocs/includes/printipp/BasicIPP.php
@@ -1,6 +1,6 @@
 <?php
-/* vim: set expandtab tabstop=2 shiftwidth=2 foldmethod=marker: */
-/* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/BasicIPP.php,v 1.6 2010/08/22 15:45:17 harding Exp $
+
+/* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/BasicIPP.php,v 1.7 2012/03/01 17:21:04 harding Exp $
  *
  * Class BasicIPP - Send Basic IPP requests, Get and parses IPP Responses.
  *
@@ -35,1966 +35,1948 @@
    - RFC 3380
    - RFC 3382
  */
-/*
-   TODO: beta tests on other servers than Cups
- */
-// required and included files
+
 require_once ("http_class.php");
-/*
-// If you want http backend from http://www.phpclasses.org/browse/package/3.html
-require_once("HTTP/http.php");
-include_once("SASL/sasl.php");
-include_once("SASL/basic_sasl_client.php");
-include_once("SASL/digest_sasl_client.php");
-include_once("SASL/ntlm_sasl_client.php");
- */
-/**
- * Class and Function List:
- * Function list:
- * - __construct()
- * - getErrorFormatted()
- * - getErrno()
- * - setPort()
- * - setUnix()
- * - setHost()
- * - setTimeout()
- * - setPrinterURI()
- * - setData()
- * - setRawText()
- * - unsetRawText()
- * - setBinary()
- * - setFormFeed()
- * - unsetFormFeed()
- * - setCharset()
- * - setLanguage()
- * - setDocumentFormat()
- * - setMimeMediaType()
- * - setCopies()
- * - setDocumentName()
- * - setJobName()
- * - setUserName()
- * - setAuthentification()
- * - setAuthentication()
- * - setSides()
- * - setFidelity()
- * - unsetFidelity()
- * - setMessage()
- * - setPageRanges()
- * - setAttribute()
- * - unsetAttribute()
- * - setLog()
- * - printDebug()
- * - getDebug()
- * - printJob()
- * - _sendHttp()
- * - _initTags()
- * - _setOperationId()
- * - _setJobId()
- * - _setJobUri()
- * - _parseServerOutput()
- * - _parseHttpHeaders()
- * - _parseIppVersion()
- * - _parseStatusCode()
- * - _parseRequestID()
- * - _interpretInteger()
- * - _parseResponse()
- * - _stringJob()
- * - _buildValues()
- * - _giveMeStringLength()
- * - _enumBuild()
- * - _integerBuild()
- * - _rangeOfIntegerBuild()
- * - _setJobAttribute()
- * - _setOperationAttribute()
- * - _setPrinterAttribute()
- * - _putDebug()
- * - _errorLog()
- * Classes list:
- * - ippException extends Exception
- * - BasicIPP
- */
-/***********************
- *
- * ippException class
- *
- ************************/
-class ippException extends Exception
+
+class ippException extends \Exception
 {
- protected $errno;
- public function __construct($msg, $errno = null) 
- {
-  parent::__construct($msg);
-  $this->errno = $errno;
- }
- public function getErrorFormatted() 
- {
-  $return = sprintf("[ipp]: %s -- " . _(" file %s, line %s"),
-    $this->getMessage() , $this->getFile() , $this->getLine());
-  return $return;
- }
- public function getErrno() 
- {
-  return $this->errno;
- }
+    protected $errno;
+
+    public function __construct($msg, $errno = null) 
+    {
+        parent::__construct($msg);
+        $this->errno = $errno;
+    }
+
+    public function getErrorFormatted() 
+    {
+        $return = sprintf("[ipp]: %s -- " . _(" file %s, line %s"),
+            $this->getMessage() , $this->getFile() , $this->getLine());
+        return $return;
+    }
+
+    public function getErrno() 
+    {
+        return $this->errno;
+    }
 }
 
 class BasicIPP
 {
- //
- // variables declaration
- //
-
- // setup variables
-
- public $paths = array(
-   "root" => "/",
-   "admin" => "/admin/",
-   "printers" => "/printers/",
-   "jobs" => "/jobs/"
-   );
- public $http_timeout = 30; // timeout at http connection (seconds) 0 => default => 30.
- public $http_data_timeout = 30; // data reading timeout (milliseconds) 0 => default => 30.
- public $ssl = false;
- public $debug_level = 3; // max 3: almost silent
- public $alert_on_end_tag; // debugging purpose: echo "END tag OK" if (1 and  reads while end tag)
- public $with_exceptions = 0; // compatibility mode for old scripts
- public $handle_http_exceptions = 1;
-
- // readables variables
-
- public $jobs = array();
- public $jobs_uri = array();
- public $status = array();
- public $response_completed = array();
- public $last_job = "";
- public $attributes; // object you can read: attributes after validateJob()
- public $printer_attributes; // object you can read: printer's attributes after getPrinterAttributes()
- public $job_attributes; // object you can read: last job attributes
- public $jobs_attributes; // object you can read: jobs attributes after getJobs()
- public $available_printers = array();
- public $printers_uri = array();
- public $debug = array();
- public $response;
-
- // protected variables;
- protected $log_level = 2; // max 3: very verbose
- protected $log_type = 3; // 3: file | 1: e-mail | 0: logger
- protected $log_destination; // e-mail or file
- protected $serveroutput;
- protected $setup;
- protected $stringjob;
- protected $data;
- protected $debug_count = 0;
- protected $username;
- protected $charset;
- protected $password;
- protected $requesring_user;
- protected $client_hostname = "localhost";
- protected $stream;
- protected $host = "localhost";
- protected $port = "631";
- protected $printer_uri;
- protected $timeout = "20"; //20 secs
- protected $errNo;
- protected $errStr;
- protected $datatype;
- protected $datahead;
- protected $datatail;
- public $meta;
- protected $operation_id;
- protected $delay;
- protected $error_generation; //devel feature
- protected $debug_http = 0;
- protected $no_disconnect;
- protected $job_tags;
- protected $operation_tags;
- protected $index;
- protected $collection; //RFC3382
- protected $collection_index; //RFC3382
- protected $collection_key = array(); //RFC3382
- protected $collection_depth = - 1; //RFC3382
- protected $end_collection = false; //RFC3382
- protected $collection_nbr = array(); //RFC3382
- protected $unix = false; // true -> use unix sockets instead of http
-
- // constructor
- public function __construct() 
- {
-  $tz = getenv("date.timezone");
-  if (!$tz) $tz = @date_default_timezone_get();
-  date_default_timezone_set($tz);
-  $this->meta = new stdClass();
-  $this->setup = new stdClass();
-  $this->values = new stdClass();
-  $this->serveroutput = new stdClass();
-  $this->error_generation = new stdClass();
-  $this->_parsing = new stdClass();
-  self::_initTags();
- }
-
- /*****************
-  *
-  * PUBLIC FUNCTIONS
-  *
-  *******************/
-
- //
- // SETUP
- //
-
- public function setPort($port = '631') 
- {
-  $this->port = $port;
-  self::_putDebug("Port is " . $this->port, 2);
- }
-
- public function setUnix($socket = '/var/run/cups/cups.sock') 
- {
-  $this->host = $socket;
-  $this->unix = true;
-  self::_putDebug("Host is " . $this->host, 2);
- }
-
- public function setHost($host = 'localhost') 
- {
-  $this->host = $host;
-  $this->unix = false;
-  self::_putDebug("Host is " . $this->host, 2);
- }
-
- public function setTimeout($timeout) 
- {
-  $this->timeout = $timeout;
- }
-
- public function setPrinterURI($uri) 
- {
-  $length = strlen($uri);
-  $length = chr($length);
-  while (strlen($length) < 2) $length = chr(0x00) . $length;
-  $this->meta->printer_uri = chr(0x45) // uri type | value-tag
-   . chr(0x00) . chr(0x0B) // name-length
-   . "printer-uri" // printer-uri | name
-   . $length . $uri;
-  $this->printer_uri = $uri;
-  self::_putDebug(sprintf(_("Printer URI: %s") , $uri) , 2);
-  $this->setup->uri = 1;
- }
-
- public function setData($data) 
- {
-  $this->data = $data;
-  self::_putDebug("Data set", 2);
- }
-
- public function setRawText() 
- {
-  $this->setup->datatype = 'TEXT';
-  $this->meta->mime_media_type = "";
-  $this->setup->mime_media_type = 1;
-  $this->datahead = chr(0x16);
-  if (is_readable($this->data)) 
-  {
-   //It's a filename.  Open and stream.
-   $data = fopen($this->data, "rb");
-   while (!feof($data)) $output = fread($data, 8192);
-  }
-  else
-  {
-   $output = $this->data;
-  }
-  if (substr($output, -1, 1) != chr(0x0c)) if (!isset($this->setup->noFormFeed)) $this->datatail = chr(0x0c);
-  self::_putDebug(_("Forcing data to be interpreted as RAW TEXT") , 2);
- }
-
- public function unsetRawText() 
- {
-  $this->setup->datatype = 'BINARY';
-  $this->datahead = '';
-  $this->datatail = '';
-  self::_putDebug(_("Unset forcing data to be interpreted as RAW TEXT") , 2);
- }
-
- public function setBinary() 
- {
-  self::unsetRawText();
- }
-
- public function setFormFeed() 
- {
-  $this->datatail = "\r\n" . chr(0x0c);
-  unset($this->setup->noFormFeed);
- }
-
- public function unsetFormFeed() 
- {
-  $this->datatail = '';
-  $this->setup->noFormFeed = 1;
- }
-
- public function setCharset($charset = 'us-ascii') 
- {
-  $charset = strtolower($charset);
-  $this->charset = $charset;
-  $this->meta->charset = chr(0x47) // charset type | value-tag
-   . chr(0x00) . chr(0x12) // name-length
-   . "attributes-charset" // attributes-charset | name
-   . self::_giveMeStringLength($charset) // value-length
-   . $charset; // value
-  self::_putDebug(sprintf(_("Charset: %s") , $charset) , 2);
-  $this->setup->charset = 1;
- }
-
- public function setLanguage($language = 'en_us') 
- {
-  $language = strtolower($language);
-  $this->meta->language = chr(0x48) // natural-language type | value-tag
-   . chr(0x00) . chr(0x1B) //  name-length
-   . "attributes-natural-language" //attributes-natural-language
-   . self::_giveMeStringLength($language) // value-length
-   . $language; // value
-  self::_putDebug(sprintf(_("Language: %s") , $language) , 2);
-  $this->setup->language = 1;
- }
-
- public function setDocumentFormat($mime_media_type = 'application/octet-stream') 
- {
-  self::setBinary();
-  $length = chr(strlen($mime_media_type));
-  while (strlen($length) < 2) $length = chr(0x00) . $length;
-  self::_putDebug(sprintf(_("mime type: %s") , $mime_media_type) , 2);
-  $this->meta->mime_media_type = chr(0x49) // document-format tag
-   . self::_giveMeStringLength('document-format') . 'document-format' //
-   . self::_giveMeStringLength($mime_media_type) . $mime_media_type; // value
-  $this->setup->mime_media_type = 1;
- }
-
- // setDocumentFormat alias for backward compatibility
- public function setMimeMediaType($mime_media_type = "application/octet-stream") 
- {
-  self::setDocumentFormat($mime_media_type);
- }
-
- public function setCopies($nbrcopies = 1) 
- {
-  $this->meta->copies = "";
-  if ($nbrcopies == 1 || !$nbrcopies) return true;
-  $copies = self::_integerBuild($nbrcopies);
-  $this->meta->copies = chr(0x21) // integer type | value-tag
-   . chr(0x00) . chr(0x06) //             name-length
-   . "copies" // copies    |             name
-   . self::_giveMeStringLength($copies) // value-length
-   . $copies;
-  self::_putDebug(sprintf(_("Copies: %s") , $nbrcopies) , 2);
-  $this->setup->copies = 1;
- }
-
- public function setDocumentName($document_name = "") 
- {
-  $this->meta->document_name = "";
-  if (!$document_name) return true;
-  $document_name = substr($document_name, 0, 1023);
-  $length = strlen($document_name);
-  $length = chr($length);
-  while (strlen($length) < 2) $length = chr(0x00) . $length;
-  self::_putDebug(sprintf(_("document name: %s") , $document_name) , 2);
-  $this->meta->document_name = chr(0x41) // textWithoutLanguage tag
-   . chr(0x00) . chr(0x0d) // name-length
-   . "document-name" // mimeMediaType
-   . self::_giveMeStringLength($document_name) . $document_name; // value
-
- }
-
- public function setJobName($jobname = '', $absolute = false) 
- {
-  $this->meta->jobname = '';
-  if ($jobname == '') 
-  {
-   $this->meta->jobname = '';
-   return true;
-  }
-  $postpend = date('-H:i:s-') . $this->_setJobId();
-  if ($absolute) $postpend = '';
-  if (isset($this->values->jobname) && $jobname == '(PHP)')
-  {
-   $jobname = $this->values->jobname;
-  }
-  $this->values->jobname = $jobname;
-  $jobname.= $postpend;
-  $this->meta->jobname = chr(0x42) // nameWithoutLanguage type || value-tag
-   . chr(0x00) . chr(0x08) //  name-length
-   . "job-name" //  job-name || name
-   . self::_giveMeStringLength($jobname) // value-length
-   . $jobname; // value
-  self::_putDebug(sprintf(_("Job name: %s") , $jobname) , 2);
-  $this->setup->jobname = 1;
- }
-
- public function setUserName($username = 'PHP-SERVER') 
- {
-  $this->requesting_user = $username;
-  $this->meta->username = '';
-  if (!$username) return true;
-  if ($username == 'PHP-SERVER' && isset($this->meta->username)) return TRUE;
-  /*
-     $value_length = 0x00;
-     for ($i = 0; $i < strlen($username); $i++) 
-     {
-     $value_length+= 0x01;
-     }
-     $value_length = chr($value_length);
-     while (strlen($value_length) < 2) $value_length = chr(0x00) . $value_length;
-   */
-  $this->meta->username = chr(0x42) // keyword type || value-tag
-   . chr(0x00) . chr(0x14) // name-length
-   . "requesting-user-name" 
-   . self::_giveMeStringLength($username) // value-length
-   . $username;
-  self::_putDebug(sprintf(_("Username: %s") , $username) , 2);
-  $this->setup->username = 1;
- }
-
- public function setAuthentification($username, $password) 
- {
-  self::setAuthentication($username, $password);
- }
-
- public function setAuthentication($username, $password) 
- {
-  $this->password = $password;
-  $this->username = $username;
-  self::_putDebug(_("Setting password") , 2);
-  $this->setup->password = 1;
- }
-
- public function setSides($sides = 2) 
- {
-  $this->meta->sides = '';
-  if (!$sides) return true;
-  switch ($sides) 
-  {
-   case 1:
-    $sides = "one-sided";
-    break;
-
-   case 2:
-    $sides = "two-sided-long-edge";
-    break;
-
-    case "2CE":
-     $sides = "two-sided-short-edge";
-    break;
-
-   default:
-    $sides = $sides; // yeah, what ?
-    break;
-  }
-  $this->meta->sides = chr(0x44) // keyword type | value-tag
-   . chr(0x00) . chr(0x05) //        name-length
-   . "sides" // sides |             name
-   . self::_giveMeStringLength($sides) //               value-length
-   . $sides; // one-sided |          value
-  self::_putDebug(sprintf(_("Sides value set to %s") , $sides) , 2);
- }
-
- public function setFidelity() 
- {
-  // whether the server can't replace any attributes
-  // (eg, 2 sided print is not possible,
-  // so print one sided) and DO NOT THE JOB.
-  $this->meta->fidelity = chr(0x22) // boolean type  |  value-tag
-   . chr(0x00) . chr(0x16) //                  name-length
-   . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name
-   . chr(0x00) . chr(0x01) //  value-length
-   . chr(0x01); //  true | value
-  self::_putDebug(_("Fidelity attribute is set (paranoid mode)") , 3);
- }
-
- public function unsetFidelity() 
- {
-  // whether the server can replace any attributes
-  // (eg, 2 sided print is not possible,
-  // so print one sided) and DO THE JOB.
-  $this->meta->fidelity = chr(0x22) //  boolean type | value-tag
-   . chr(0x00) . chr(0x16) //        name-length
-   . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name
-   . chr(0x00) . chr(0x01) //               value-length
-   . chr(0x00); // false |                   value
-  self::_putDebug(_("Fidelity attribute is unset") , 2);
- }
-
- public function setMessage($message = '')
- {
-  $this->meta->message = '';
-  if (!$message) return true;
-  $this->meta->message = 
-   chr(0x41) // attribute type = textWithoutLanguage
-   . chr(0x00) 
-   . chr(0x07) 
-   . "message" 
-   . self::_giveMeStringLength(substr($message, 0, 127))
-   . substr($message, 0, 127);
-  self::_putDebug(sprintf(_('Setting message to "%s"') , $message) , 2);
- }
-
- public function setPageRanges($page_ranges) 
- {
-  // $pages_ranges = string:  "1:5 10:25 40:52 ..."
-  // to unset, specify an empty string.
-  $this->meta->page_range = '';
-  if (!$page_ranges) return true;
-  $page_ranges = trim(str_replace("-", ":", $page_ranges));
-  $first = true;
-  #$page_ranges = split(' ', $page_ranges);
-  $page_ranges = preg_split('# #', $page_ranges);
-  foreach($page_ranges as $page_range) 
-  {
-   $value = self::_rangeOfIntegerBuild($page_range);
-   if ($first)
-   {
-    $this->meta->page_ranges .= 
-     $this->tags_types['rangeOfInteger']['tag'] 
-     . self::_giveMeStringLength('page-ranges') 
-     . 'page-ranges' 
-     . self::_giveMeStringLength($value) 
-     . $value;
-   }
-   else
-   {
-    $this->meta->page_ranges .= 
-     $this->tags_types['rangeOfInteger']['tag'] 
-     . self::_giveMeStringLength('') 
-     . self::_giveMeStringLength($value) 
-     . $value;
-    $first = false;
-   }
-  }
- }
-
- public function setAttribute($attribute, $values) 
- {
-  $operation_attributes_tags = array_keys($this->operation_tags);
-  $job_attributes_tags = array_keys($this->job_tags);
-  $printer_attributes_tags = array_keys($this->printer_tags);
-  self::unsetAttribute($attribute);
-  if (in_array($attribute, $operation_attributes_tags)) 
-  {
-   if (!is_array($values))
-   {
-    self::_setOperationAttribute($attribute, $values);
-   }
-   else
-   {
-    foreach($values as $value)
+    public $paths = array(
+        "root" => "/",
+        "admin" => "/admin/",
+        "printers" => "/printers/",
+        "jobs" => "/jobs/"
+    );
+    public $http_timeout = 30; // timeout at http connection (seconds) 0 => default => 30.
+    public $http_data_timeout = 30; // data reading timeout (milliseconds) 0 => default => 30.
+    public $ssl = false;
+    public $debug_level = 3; // max 3: almost silent
+    public $alert_on_end_tag; // debugging purpose: echo "END tag OK" if (1 and  reads while end tag)
+    public $with_exceptions = 0; // compatibility mode for old scripts
+    public $handle_http_exceptions = 1;
+
+    // readables variables
+    public $jobs = array();
+    public $jobs_uri = array();
+    public $status = array();
+    public $response_completed = array();
+    public $last_job = "";
+    public $attributes; // object you can read: attributes after validateJob()
+    public $printer_attributes; // object you can read: printer's attributes after getPrinterAttributes()
+    public $job_attributes; // object you can read: last job attributes
+    public $jobs_attributes; // object you can read: jobs attributes after getJobs()
+    public $available_printers = array();
+    public $printer_map = array();
+    public $printers_uri = array();
+    public $debug = array();
+    public $response;
+    public $meta;
+
+    // protected variables;
+    protected $log_level = 2; // max 3: very verbose
+    protected $log_type = 3; // 3: file | 1: e-mail | 0: logger
+    protected $log_destination; // e-mail or file
+    protected $serveroutput;
+    protected $setup;
+    protected $stringjob;
+    protected $data;
+    protected $debug_count = 0;
+    protected $username;
+    protected $charset;
+    protected $password;
+    protected $requesring_user;
+    protected $client_hostname = "localhost";
+    protected $stream;
+    protected $host = "localhost";
+    protected $port = "631";
+    protected $requesting_user = '';
+    protected $printer_uri;
+    protected $timeout = "20"; //20 secs
+    protected $errNo;
+    protected $errStr;
+    protected $datatype;
+    protected $datahead;
+    protected $datatail;
+    protected $operation_id;
+    protected $delay;
+    protected $error_generation; //devel feature
+    protected $debug_http = 0;
+    protected $no_disconnect;
+    protected $job_tags;
+    protected $operation_tags;
+    protected $index;
+    protected $collection; //RFC3382
+    protected $collection_index; //RFC3382
+    protected $collection_key = array(); //RFC3382
+    protected $collection_depth = - 1; //RFC3382
+    protected $end_collection = false; //RFC3382
+    protected $collection_nbr = array(); //RFC3382
+    protected $unix = false; // true -> use unix sockets instead of http
+    protected $output;
+
+    public function __construct() 
     {
-     self::_setOperationAttribute($attribute, $value);
+        $tz = getenv("date.timezone");
+        if (!$tz)
+        {
+            $tz = @date_default_timezone_get();
+        }
+
+        date_default_timezone_set($tz);
+        $this->meta = new \stdClass();
+        $this->setup = new \stdClass();
+        $this->values = new \stdClass();
+        $this->serveroutput = new \stdClass();
+        $this->error_generation = new \stdClass();
+        $this->_parsing = new \stdClass();
+        self::_initTags();
     }
-   }
-  }
-  elseif (in_array($attribute, $job_attributes_tags)) 
-  {
-   if (!is_array($values))
-   {
-    self::_setJobAttribute($attribute, $values);
-   }
-   else 
-   {
-    foreach($values as $value)
+
+    public function setPort($port = '631') 
     {
-     self::_setJobAttribute($attribute, $value);
+        $this->port = $port;
+        self::_putDebug("Port is " . $this->port, 2);
     }
-   }
-  }
-  elseif (in_array($attribute, $printer_attributes_tags)) 
-  {
-   if (!is_array($values))
-   {
-    self::_setPrinterAttribute($attribute, $values);
-   }
-   else
-   {
-    foreach($values as $value)
+
+    public function setUnix($socket = '/var/run/cups/cups.sock') 
     {
-     self::_setPrinterAttribute($attribute, $value);
+        $this->host = $socket;
+        $this->unix = true;
+        self::_putDebug("Host is " . $this->host, 2);
     }
-   }
-  }
-  else
-  {
-   trigger_error(
-     sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'),
-      $attribute) , E_USER_NOTICE);
-   self::_putDebug(
-     sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'),
-      $attribute) , 3);
-   self::_errorLog(
-     sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'),
-      $attribute) , 2);
-   return FALSE;
-  }
- }
-
- public function unsetAttribute($attribute) 
- {
-  $operation_attributes_tags = array_keys($this->operation_tags);
-  $job_attributes_tags = array_keys($this->job_tags);
-  $printer_attributes_tags = array_keys($this->printer_tags);
-  if (in_array($attribute, $operation_attributes_tags)) 
-  {
-   unset( 
-     $this->operation_tags[$attribute]['value'],
-     $this->operation_tags[$attribute]['systag']
-        );
-  }
-  elseif (in_array($attribute, $job_attributes_tags))
-  {
-   unset(
-     $this->job_tags[$attribute]['value'],
-     $this->job_tags[$attribute]['systag']
-        );
-  }
-  elseif (in_array($attribute, $printer_attributes_tags))
-  {
-   unset(
-     $this->printer_tags[$attribute]['value'],
-     $this->printer_tags[$attribute]['systag']
-        );
-  }
-  else 
-  {
-   trigger_error(
-     sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'),
-      $attribute) , E_USER_NOTICE);
-   self::_putDebug(
-     sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'),
-      $attribute) , 3);
-   self::_errorLog(
-     sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'),
-      $attribute) , 2);
-   return FALSE;
-  }
-  return true;
- }
-
- //
- // LOGGING / DEBUGGING
- //
-
- public function setLog($log_destination, $destination_type = 'file', $level = 2) 
- {
-
-  if (is_string($log_destination) && !empty($log_destination))
-  {
-   $this->log_destination = $log_destination;
-  }
-
-  switch ($destination_type) 
-  {
-   case 'file':
-   case 3:
-    $this->log_destination = $log_destination;
-    $this->log_type = 3;
-    break;
-
-   case 'logger':
-   case 0:
-    $this->log_destination = '';
-    $this->log_type = 0;
-    break;
-
-   case 'e-mail':
-   case 1:
-    $this->log_destination = $log_destination;
-    $this->log_type = 1;
-    break;
-  }
-  $this->log_level = $level;
- }
-
- public function printDebug() 
- {
-  for ($i = 0; $i < $this->debug_count; $i++)
-  {
-   echo $this->debug[$i], "\n";
-  }
-  $this->debug = array();
-  $this->debug_count = 0;
- }
-
- public function getDebug() 
- {
-  $debug = '';
-  for ($i = 0; $i < $this->debug_count; $i++)
-  {
-   $debug.= $this->debug[$i];
-  }
-  $this->debug = array();
-  $this->debug_count = 0;
-  return $debug;
- }
-
- //
- // OPERATIONS
- //
-
- public function printJob() 
- {
-  // this BASIC version of printJob do not parse server
-  // output for job's attributes
-  self::_putDebug(
-    sprintf(
-     "************** Date: %s ***********",
-     date('Y-m-d H:i:s')
-           )
-          );
-  if (!$this->_stringJob()) return FALSE;
-  if (is_readable($this->data)) 
-  {
-   self::_putDebug(_("Printing a FILE"));
-   $this->output = $this->stringjob;
-   if ($this->setup->datatype == "TEXT")
-   {
-    $this->output.= chr(0x16);
-   }
-   $post_values = array(
-     "Content-Type" => "application/ipp",
-     "Data" => $this->output,
-     "File" => $this->data
-     );
-   if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed))
-   {
-    $post_values = array_merge(
-      $post_values,
-      array(
-       "Filetype" => "TEXT"
-           )
-      );
-   }
-  }
-  else
-  {
-   self::_putDebug(_("Printing DATA"));
-   $this->output = 
-    $this->stringjob
-    . $this->datahead
-    . $this->data
-    . $this->datatail;
-   $post_values = array(
-     "Content-Type" => "application/ipp",
-     "Data" => $this->output
-     );
-  }
-  if (self::_sendHttp($post_values, $this->paths["printers"]))
-  {
-   self::_parseServerOutput();
-  }
-  if (isset($this->serveroutput) && isset($this->serveroutput->status)) 
-  {
-   $this->status = array_merge($this->status, array(
-      $this->serveroutput->status
-      ));
-   if ($this->serveroutput->status == "successfull-ok")
-   {
-    self::_errorLog(
-      sprintf("printing job %s: ", $this->last_job) 
-      . $this->serveroutput->status,
-      3);
-   }
-   else
-   {
-    self::_errorLog(
-      sprintf("printing job: ", $this->last_job) 
-      . $this->serveroutput->status,
-      1);
-   }
-   return $this->serveroutput->status;
-  }
-
-  $this->status = 
-   array_merge($this->status, array("OPERATION FAILED"));
-  $this->jobs = 
-   array_merge($this->jobs, array(""));
-  $this->jobs_uri = 
-   array_merge($this->jobs_uri, array(""));
-
-  self::_errorLog("printing job : OPERATION FAILED", 1);
-  return false;
- }
-
-
- /******************
-  *
-  * PROTECTED FUNCTIONS
-  *
-  *******************/
-
- //
- // HTTP OUTPUT
- //
-
- protected function _sendHttp($post_values, $uri) 
- {
-  /*
-     This function Copyright (C) 2005-2006 Thomas Harding, Manuel Lemos
-   */
-  $this->response_completed[] = "no";
-  unset($this->serverouptut);
-  self::_putDebug(_("Processing HTTP request") , 2);
-  $this->serveroutput->headers = array();
-  $this->serveroutput->body = "";
-  $http = new http_class;
-  if (!$this->unix) $http->host = $this->host;
-  else $http->host = "localhost";
-  $http->with_exceptions = $this->with_exceptions;
-  if ($this->debug_http) 
-  {
-   $http->debug = 1;
-   $http->html_debug = 0;
-  }
-  else
-  {
-   $http->debug = 0;
-   $http->html_debug = 0;
-  }
-  $url = "http://" . $this->host;
-  if ($this->ssl) $url = "https://" . $this->host;
-  if ($this->unix) $url = "unix://" . $this->host;
-  $http->port = $this->port;
-  $http->timeout = $this->http_timeout;
-  $http->data_timeout = $this->http_data_timeout;
-  $http->force_multipart_form_post = false;
-  $http->user = $this->username;
-  $http->password = $this->password;
-  $error = $http->GetRequestArguments($url, $arguments);
-  $arguments["RequestMethod"] = "POST";
-  $arguments["Headers"] = array(
-    "Content-Type" => "application/ipp"
-    );
-  $arguments["BodyStream"] = array(
-    array(
-     "Data" => $post_values["Data"]
-         )
-    );
-  if (isset($post_values["File"])) $arguments["BodyStream"][] = array(
-    "File" => $post_values["File"]
-    );
-  if (isset($post_values["FileType"]) 
-    && !strcmp($post_values["FileType"], "TEXT"))
-  {
-   $arguments["BodyStream"][] = array("Data" => Chr(12));
-  }
-  $arguments["RequestURI"] = $uri;
-  if ($this->with_exceptions && $this->handle_http_exceptions) 
-  {
-   try
-   {
-    $success = $http->Open($arguments);
-   }
-   catch(httpException $e) 
-   {
-    throw new ippException(
-      sprintf("http error: %s", $e->getMessage()),
-      $e->getErrno());
-   }
-  }
-  else
-  {
-   $success = $http->Open($arguments);
-  }
-  if ($success[0] == true) 
-  {
-   $success = $http->SendRequest($arguments);
-   if ($success[0] == true) 
-   {
-    self::_putDebug("H T T P    R E Q U E S T :");
-    self::_putDebug("Request headers:");
-    for (Reset($http->request_headers) , $header = 0; $header < count($http->request_headers); Next($http->request_headers) , $header++) 
+
+    public function setHost($host = 'localhost') 
     {
-     $header_name = Key($http->request_headers);
-     if (GetType($http->request_headers[$header_name]) == "array") 
-     {
-      for ($header_value = 0; $header_value < count($http->request_headers[$header_name]); $header_value++)
-      {
-       self::_putDebug($header_name . ": " . $http->request_headers[$header_name][$header_value]);
-      }
-     }
-     else
-     {
-      self::_putDebug($header_name . ": " . $http->request_headers[$header_name]);
-     }
+        $this->host = $host;
+        $this->unix = false;
+        self::_putDebug("Host is " . $this->host, 2);
     }
-    self::_putDebug("Request body:");
-    self::_putDebug(
-      htmlspecialchars($http->request_body) 
-      . "*********** END REQUEST BODY *********"
-            );
-    $i = 0;
-    $headers = array();
-    unset($this->serveroutput->headers);
-    $http->ReadReplyHeaders($headers);
-    self::_putDebug("H T T P    R E S P O N S E :");
-    self::_putDebug("Response headers:");
-    for (Reset($headers) , $header = 0; $header < count($headers); Next($headers) , $header++) 
+
+    public function setTimeout($timeout) 
     {
-     $header_name = Key($headers);
-     if (GetType($headers[$header_name]) == "array") 
-     {
-      for ($header_value = 0; $header_value < count($headers[$header_name]); $header_value++) 
-      {
-       self::_putDebug($header_name . ": " . $headers[$header_name][$header_value]);
-       $this->serveroutput->headers[$i] = 
-        $header_name . ": " 
-        . $headers[$header_name][$header_value];
-       $i++;
-      }
-     }
-     else
-     {
-      self::_putDebug($header_name . ": " . $headers[$header_name]);
-      $this->serveroutput->headers[$i] = 
-       $header_name 
-       . ": " 
-       . $headers[$header_name];
-      $i++;
-     }
+        $this->timeout = $timeout;
     }
-    self::_putDebug("\n\nResponse body:\n");
-    $this->serveroutput->body = "";
-    for (;;) 
+
+    public function setPrinterURI($uri) 
     {
-     $http->ReadReplyBody($body, 1024);
-     if (strlen($body) == 0) break;
+        $length = strlen($uri);
+        $length = chr($length);
+        while (strlen($length) < 2) $length = chr(0x00) . $length;
+        $this->meta->printer_uri = chr(0x45) // uri type | value-tag
+            . chr(0x00) . chr(0x0B) // name-length
+            . "printer-uri" // printer-uri | name
+            . $length . $uri;
+        $this->printer_uri = $uri;
+        self::_putDebug(sprintf(_("Printer URI: %s") , $uri) , 2);
+        $this->setup->uri = 1;
+    }
 
-     self::_putDebug(htmlentities($body));
-     $this->serveroutput->body.= $body;
+    public function setData($data) 
+    {
+        $this->data = $data;
+        self::_putDebug("Data set", 2);
+    }
+
+    public function setRawText() 
+    {
+        $this->setup->datatype = 'TEXT';
+        $this->meta->mime_media_type = "";
+        $this->setup->mime_media_type = 1;
+        $this->datahead = chr(0x16);
+        if (is_readable($this->data)) 
+        {
+            //It's a filename.  Open and stream.
+            $data = fopen($this->data, "rb");
+            while (!feof($data)) $output = fread($data, 8192);
+        }
+        else
+        {
+            $output = $this->data;
+        }
+        if (substr($output, -1, 1) != chr(0x0c)) {
+            if (!isset($this->setup->noFormFeed))
+            {
+                $this->datatail = chr(0x0c);
+            }
+        }
+        self::_putDebug(_("Forcing data to be interpreted as RAW TEXT") , 2);
+    }
+
+    public function unsetRawText() 
+    {
+        $this->setup->datatype = 'BINARY';
+        $this->datahead = '';
+        $this->datatail = '';
+        self::_putDebug(_("Unset forcing data to be interpreted as RAW TEXT") , 2);
+    }
+
+    public function setBinary() 
+    {
+        self::unsetRawText();
+    }
+
+    public function setFormFeed() 
+    {
+        $this->datatail = "\r\n" . chr(0x0c);
+        unset($this->setup->noFormFeed);
     }
-    self::_putDebug("********* END RESPONSE BODY ********");
-   }
-  }
-  $http->Close();
-  return true;
- }
-
- //
- // INIT
- //
-
- protected function _initTags() 
- {
-  $this->tags_types = array(
-    "unsupported" => array(
-     "tag" => chr(0x10) ,
-     "build" => ""
-     ) ,
-    "reserved" => array(
-     "tag" => chr(0x11) ,
-     "build" => ""
-     ) ,
-    "unknown" => array(
-     "tag" => chr(0x12) ,
-     "build" => ""
-     ) ,
-    "no-value" => array(
-     "tag" => chr(0x13) ,
-     "build" => "no_value"
-     ) ,
-    "integer" => array(
-     "tag" => chr(0x21) ,
-     "build" => "integer"
-     ) ,
-    "boolean" => array(
-      "tag" => chr(0x22) ,
-      "build" => "boolean"
-      ) ,
-    "enum" => array(
-      "tag" => chr(0x23) ,
-      "build" => "enum"
-            ) ,
-    "octetString" => array(
-      "tag" => chr(0x30) ,
-      "build" => "octet_string"
-      ) ,
-    "datetime" => array(
-      "tag" => chr(0x31) ,
-      "build" => "datetime"
-      ) ,
-    "resolution" => array(
-      "tag" => chr(0x32) ,
-      "build" => "resolution"
-      ) ,
-    "rangeOfInteger" => array(
-      "tag" => chr(0x33) ,
-      "build" => "range_of_integers"
-      ) ,
-    "textWithLanguage" => array(
-      "tag" => chr(0x35) ,
-      "build" => "string"
-      ) ,
-    "nameWithLanguage" => array(
-      "tag" => chr(0x36) ,
-      "build" => "string"
-      ) ,
-    /*
-       "text" => array ("tag" => chr(0x40),
-       "build" => "string"),
-       "text string" => array ("tag" => chr(0x40),
-       "build" => "string"),
-     */
-    "textWithoutLanguage" => array(
-      "tag" => chr(0x41) ,
-      "build" => "string"
-      ) ,
-    "nameWithoutLanguage" => array(
-      "tag" => chr(0x42) ,
-      "buid" => "string"
-      ) ,
-    "keyword" => array(
-      "tag" => chr(0x44) ,
-      "build" => "string"
-      ) ,
-    "uri" => array(
-      "tag" => chr(0x45) ,
-      "build" => "string"
-           ) ,
-    "uriScheme" => array(
-      "tag" => chr(0x46) ,
-      "build" => "string"
-      ) ,
-    "charset" => array(
-      "tag" => chr(0x47) ,
-      "build" => "string"
-      ) ,
-    "naturalLanguage" => array(
-      "tag" => chr(0x48) ,
-      "build" => "string"
-      ) ,
-    "mimeMediaType" => array(
-      "tag" => chr(0x49) ,
-      "build" => "string"
-      ) ,
-    "extendedAttributes" => array(
-      "tag" => chr(0x7F) ,
-      "build" => "extended"
-      ) ,
-    );
-  $this->operation_tags = array(
-    "compression" => array(
-     "tag" => "keyword"
-     ) ,
-    "document-natural-language" => array(
-     "tag" => "naturalLanguage"
-     ) ,
-    "job-k-octets" => array(
-     "tag" => "integer"
-     ) ,
-    "job-impressions" => array(
-     "tag" => "integer"
-     ) ,
-    "job-media-sheets" => array(
-     "tag" => "integer"
-     ) ,
-    );
-  $this->job_tags = array(
-    "job-priority" => array(
-     "tag" => "integer"
-     ) ,
-    "job-hold-until" => array(
-     "tag" => "keyword"
-     ) ,
-    "job-sheets" => array(
-     "tag" => "keyword"
-     ) , //banner page
-    "multiple-document-handling" => array(
-     "tag" => "keyword"
-     ) ,
-    //"copies" => array("tag" => "integer"),
-    "finishings" => array(
-     "tag" => "enum"
-     ) ,
-    //"page-ranges" => array("tag" => "rangeOfInteger"), // has its own function
-    //"sides" => array("tag" => "keyword"), // has its own function
-    "number-up" => array(
-     "tag" => "integer"
-     ) ,
-    "orientation-requested" => array(
-      "tag" => "enum"
-      ) ,
-    "media" => array(
-      "tag" => "keyword"
-      ) ,
-    "printer-resolution" => array(
-      "tag" => "resolution"
-      ) ,
-    "print-quality" => array(
-      "tag" => "enum"
-      ) ,
-    "job-message-from-operator" => array(
-      "tag" => "textWithoutLanguage"
-      ) ,
-    );
-  $this->printer_tags = array(
-    "requested-attributes" => array(
-     "tag" => "keyword"
-     )
-    );
- }
-
- //
- // SETUP
- //
-
- protected function _setOperationId() 
- {
-  $prepend = '';
-  $this->operation_id+= 1;
-  $this->meta->operation_id = self::_integerBuild($this->operation_id);
-  self::_putDebug("operation id is: " . $this->operation_id, 2);
- }
-
- protected function _setJobId() 
- {
-  $this->meta->jobid+= 1;
-  $prepend = '';
-  $prepend_length = 4 - strlen($this->meta->jobid);
-  for ($i = 0; $i < $prepend_length; $i++) $prepend.= '0';
-  return $prepend . $this->meta->jobid;
- }
-
- protected function _setJobUri($job_uri) 
- {
-  $this->meta->job_uri = chr(0x45) // type uri
-   . chr(0x00) . chr(0x07) // name-length
-   . "job-uri"
-   //. chr(0x00).chr(strlen($job_uri))
-   . self::_giveMeStringLength($job_uri) . $job_uri;
-  self::_putDebug("job-uri is: " . $job_uri, 2);
- }
-
- //
- // RESPONSE PARSING
- //
-
- protected function _parseServerOutput() 
- {
-  $this->serveroutput->response = array();
-  if (!self::_parseHttpHeaders()) return FALSE;
-  $this->_parsing->offset = 0;
-  self::_parseIppVersion();
-  self::_parseStatusCode();
-  self::_parseRequestID();
-  $this->_parseResponse();
-  //devel
-  self::_putDebug(
-    sprintf("***** IPP STATUS: %s ******", $this->serveroutput->status),
-    4);
-  self::_putDebug("****** END OF OPERATION ****");
-  return true;
- }
-
- protected function _parseHttpHeaders() 
- {
-  $response = "";
-  switch ($this->serveroutput->headers[0]) 
-  {
-   case "http/1.1 200 ok: ":
-    $this->serveroutput->httpstatus = "HTTP/1.1 200 OK";
-   $response = "OK";
-   break;
-
-   // primitive http/1.0 for Lexmark printers (from Rick Baril)
-   case "http/1.0 200 ok: ":
-    $this->serveroutput->httpstatus = "HTTP/1.0 200 OK";
-   $response = "OK";
-   break;
-
-   case "http/1.1 100 continue: ":
-    $this->serveroutput->httpstatus = "HTTP/1.1 100 CONTINUE";
-   $response = "OK";
-   break;
-
-   case "":
-    $this->serveroutput->httpstatus = "HTTP/1.1 000 No Response From Server";
-   $this->serveroutput->status = "HTTP-ERROR-000_NO_RESPONSE_FROM_SERVER";
-   trigger_error("No Response From Server", E_USER_WARNING);
-   self::_errorLog("No Response From Server", 1);
-   $this->disconnected = 1;
-   return FALSE;
-   break;
-
-   default:
-   $server_response = preg_replace("/: $/", '', $this->serveroutput->headers[0]);
-   #$strings = split(' ', $server_response, 3);
-   $strings = preg_split('# #', $server_response, 3);
-   $errno = $strings[1];
-   $string = strtoupper(str_replace(' ', '_', $strings[2]));
-   trigger_error(
-     sprintf(_("server responds %s") , $server_response),
-     E_USER_WARNING);
-   self::_errorLog("server responds " . $server_response, 1);
-   $this->serveroutput->httpstatus =
-    strtoupper($strings[0])
-    . " "
-    . $errno
-    . " "
-    . ucfirst($strings[2]);
-
-   $this->serveroutput->status =
-    "HTTP-ERROR-"
-    . $errno
-    . "-"
-    . $string;
-   $this->disconnected = 1;
-   return FALSE;
-   break;
-  }
-  unset($this->serveroutput->headers);
-  return TRUE;
- }
-
- protected function _parseIppVersion() 
- {
-  $ippversion =
-   (ord($this->serveroutput->body[$this->_parsing->offset]) * 256)
-   + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
-  switch ($ippversion) 
-  {
-   case 0x0101:
-    $this->serveroutput->ipp_version = "1.1";
-    break;
-
-   default:
-    $this->serveroutput->ipp_version =
-     sprintf("%u.%u (Unknown)",
-       ord($this->serveroutput->body[$this->_parsing->offset]) * 256,
-       ord($this->serveroutput->body[$this->_parsing->offset + 1]));
-    break;
-  }
-  self::_putDebug("I P P    R E S P O N S E :\n\n");
-  self::_putDebug(
-    sprintf("IPP version %s%s: %s",
-     ord($this->serveroutput->body[$this->_parsing->offset]),
-     ord($this->serveroutput->body[$this->_parsing->offset + 1]),
-     $this->serveroutput->ipp_version));
-  $this->_parsing->offset+= 2;
-  return;
- }
-
- protected function _parseStatusCode() 
- {
-  $status_code =
-   (ord($this->serveroutput->body[$this->_parsing->offset]) * 256)
-   + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
-  $this->serveroutput->status = "NOT PARSED";
-  $this->_parsing->offset+= 2;
-  if (strlen($this->serveroutput->body) < $this->_parsing->offset)
-  {
-   return false;
-  }
-  if ($status_code < 0x00FF) 
-  {
-   $this->serveroutput->status = "successfull";
-  }
-  elseif ($status_code < 0x01FF) 
-  {
-   $this->serveroutput->status = "informational";
-  }
-  elseif ($status_code < 0x02FF) 
-  {
-   $this->serveroutput->status = "redirection";
-  }
-  elseif ($status_code < 0x04FF) 
-  {
-   $this->serveroutput->status = "client-error";
-  }
-  elseif ($status_code < 0x05FF) 
-  {
-   $this->serveroutput->status = "server-error";
-  }
-  switch ($status_code) 
-  {
-   case 0x0000:
-    $this->serveroutput->status = "successfull-ok";
-    break;
-
-   case 0x0001:
-    $this->serveroutput->status = "successful-ok-ignored-or-substituted-attributes";
-    break;
-
-   case 0x002:
-    $this->serveroutput->status = "successful-ok-conflicting-attributes";
-    break;
-
-   case 0x0400:
-    $this->serveroutput->status = "client-error-bad-request";
-    break;
-
-   case 0x0401:
-    $this->serveroutput->status = "client-error-forbidden";
-    break;
-
-   case 0x0402:
-    $this->serveroutput->status = "client-error-not-authenticated";
-    break;
-
-   case 0x0403:
-    $this->serveroutput->status = "client-error-not-authorized";
-    break;
-
-   case 0x0404:
-    $this->serveroutput->status = "client-error-not-possible";
-    break;
-
-   case 0x0405:
-    $this->serveroutput->status = "client-error-timeout";
-    break;
-
-   case 0x0406:
-    $this->serveroutput->status = "client-error-not-found";
-    break;
-
-   case 0x0407:
-    $this->serveroutput->status = "client-error-gone";
-    break;
-
-   case 0x0408:
-    $this->serveroutput->status = "client-error-request-entity-too-large";
-    break;
-
-   case 0x0409:
-    $this->serveroutput->status = "client-error-request-value-too-long";
-    break;
-
-   case 0x040A:
-    $this->serveroutput->status = "client-error-document-format-not-supported";
-    break;
-
-   case 0x040B:
-    $this->serveroutput->status = "client-error-attributes-or-values-not-supported";
-    break;
-
-   case 0x040C:
-    $this->serveroutput->status = "client-error-uri-scheme-not-supported";
-    break;
-
-   case 0x040D:
-    $this->serveroutput->status = "client-error-charset-not-supported";
-    break;
-
-   case 0x040E:
-    $this->serveroutput->status = "client-error-conflicting-attributes";
-    break;
-
-   case 0x040F:
-    $this->serveroutput->status = "client-error-compression-not-supported";
-    break;
-
-   case 0x0410:
-    $this->serveroutput->status = "client-error-compression-error";
-    break;
-
-   case 0x0411:
-    $this->serveroutput->status = "client-error-document-format-error";
-    break;
-
-   case 0x0412:
-    $this->serveroutput->status = "client-error-document-access-error";
-    break;
-
-   case 0x0413: // RFC3380
-    $this->serveroutput->status = "client-error-attributes-not-settable";
-    break;
-
-   case 0x0500:
-    $this->serveroutput->status = "server-error-internal-error";
-    break;
-
-   case 0x0501:
-    $this->serveroutput->status = "server-error-operation-not-supported";
-    break;
-
-   case 0x0502:
-    $this->serveroutput->status = "server-error-service-unavailable";
-    break;
-
-   case 0x0503:
-    $this->serveroutput->status = "server-error-version-not-supported";
-    break;
-
-   case 0x0504:
-    $this->serveroutput->status = "server-error-device-error";
-    break;
-
-   case 0x0505:
-    $this->serveroutput->status = "server-error-temporary-error";
-    break;
-
-   case 0x0506:
-    $this->serveroutput->status = "server-error-not-accepting-jobs";
-    break;
-
-   case 0x0507:
-    $this->serveroutput->status = "server-error-busy";
-    break;
-
-   case 0x0508:
-    $this->serveroutput->status = "server-error-job-canceled";
-    break;
-
-   case 0x0509:
-    $this->serveroutput->status = "server-error-multiple-document-jobs-not-supported";
-    break;
-
-   default:
-    break;
-  }
-  self::_putDebug(
-    sprintf(
-     "status-code: %s%s: %s ",
-     $this->serveroutput->body[$this->_parsing->offset],
-     $this->serveroutput->body[$this->_parsing->offset + 1],
-     $this->serveroutput->status),
-    4);
-  return;
- }
-
- protected function _parseRequestID() 
- {
-  $this->serveroutput->request_id =
-   self::_interpretInteger(
-     substr($this->serveroutput->body, $this->_parsing->offset, 4)
-     );
-  self::_putDebug("request-id " . $this->serveroutput->request_id, 2);
-  $this->_parsing->offset+= 4;
-  return;
- }
-
- protected function _interpretInteger($value) 
- {
-  // they are _signed_ integers
-  $value_parsed = 0;
-  for ($i = strlen($value); $i > 0; $i --)
-  {
-   $value_parsed +=
-    (
-     (1 << (($i - 1) * 8)) 
-     * 
-     ord($value[strlen($value) - $i])
-    );
 
-  }
-  if ($value_parsed >= 2147483648)
-  {
-   $value_parsed -= 4294967296;
-  }
-  return $value_parsed;
- }
-
- protected function _parseResponse() 
- {
- }
-
- //
- // REQUEST BUILDING
- //
-
- protected function _stringJob() 
- {
-  if (!isset($this->setup->charset)) self::setCharset('us-ascii');
-  if (!isset($this->setup->datatype)) self::setBinary();
-  if (!isset($this->setup->uri)) 
-  {
-   $this->getPrinters();
-   unset($this->jobs[count($this->jobs) - 1]);
-   unset($this->jobs_uri[count($this->jobs_uri) - 1]);
-   unset($this->status[count($this->status) - 1]);
-   if (array_key_exists(0, $this->available_printers))
-   {
-    self::setPrinterURI($this->available_printers[0]);
-   }
-   else 
-   {
-    trigger_error(
-      _("_stringJob: Printer URI is not set: die"),
-      E_USER_WARNING);
-    self::_putDebug(_("_stringJob: Printer URI is not set: die") , 4);
-    self::_errorLog(" Printer URI is not set, die", 2);
-    return FALSE;
-   }
-  }
-  if (!isset($this->setup->copies)) self::setCopies(1);
-  if (!isset($this->setup->language)) self::setLanguage('en_us');
-  if (!isset($this->setup->mime_media_type)) self::setMimeMediaType();
-  if (!isset($this->setup->jobname)) self::setJobName();
-  unset($this->setup->jobname);
-  if (!isset($this->meta->username)) self::setUserName();
-  if (!isset($this->meta->fidelity)) $this->meta->fidelity = '';
-  if (!isset($this->meta->document_name)) $this->meta->document_name = '';
-  if (!isset($this->meta->sides)) $this->meta->sides = '';
-  if (!isset($this->meta->page_ranges)) $this->meta->page_ranges = '';
-  $jobattributes = '';
-  $operationattributes = '';
-  $printerattributes = '';
-  $this->_buildValues($operationattributes, $jobattributes, $printerattributes);
-  self::_setOperationId();
-  if (!isset($this->error_generation->request_body_malformed))
-  {
-   $this->error_generation->request_body_malformed = "";
-  }
-  $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
-   . chr(0x00) . chr(0x02) // Print-Job | operation-id
-   . $this->meta->operation_id //           request-id
-   . chr(0x01) // start operation-attributes | operation-attributes-tag
-   . $this->meta->charset
-   . $this->meta->language
-   . $this->meta->printer_uri
-   . $this->meta->username
-   . $this->meta->jobname
-   . $this->meta->fidelity
-   . $this->meta->document_name
-   . $this->meta->mime_media_type
-   . $operationattributes;
-  if ($this->meta->copies || $this->meta->sides || $this->meta->page_ranges || !empty($jobattributes)) 
-  {
-   $this->stringjob .=
-    chr(0x02) // start job-attributes | job-attributes-tag
-    . $this->meta->copies
-    . $this->meta->sides
-    . $this->meta->page_ranges
-    . $jobattributes
-    ;
-  }
-  $this->stringjob.= chr(0x03); // end-of-attributes | end-of-attributes-tag
-  self::_putDebug(
-    sprintf(_("String sent to the server is: %s"),
-     $this->stringjob)
-          );
-  return TRUE;
- }
-
- protected function _buildValues(&$operationattributes, &$jobattributes, &$printerattributes) 
- {
-  $operationattributes = '';
-  foreach($this->operation_tags as $key => $values) 
-  {
-   $item = 0;
-   if (array_key_exists('value', $values))
-   {
-    foreach($values['value'] as $item_value) 
+    public function unsetFormFeed() 
     {
-     if ($item == 0)
-     {
-      $operationattributes .=
-       $values['systag'] 
-       . self::_giveMeStringLength($key) 
-       . $key 
-       . self::_giveMeStringLength($item_value) 
-       . $item_value;
-     }
-     else
-     {
-      $operationattributes .= 
-       $values['systag'] 
-       . self::_giveMeStringLength('') 
-       . self::_giveMeStringLength($item_value) 
-       . $item_value;
-     }
-     $item++;
+        $this->datatail = '';
+        $this->setup->noFormFeed = 1;
     }
-   }
-  }
-  $jobattributes = '';
-  foreach($this->job_tags as $key => $values) 
-  {
-   $item = 0;
-   if (array_key_exists('value', $values)) 
-   {
-    foreach($values['value'] as $item_value) 
+
+    public function setCharset($charset = 'utf-8') 
     {
-     if ($item == 0)
-     { 
-      $jobattributes .=
-       $values['systag'] 
-       . self::_giveMeStringLength($key)
-       . $key
-       . self::_giveMeStringLength($item_value)
-       . $item_value;
-     }
-     else
-     {
-      $jobattributes .=
-       $values['systag']
-       . self::_giveMeStringLength('')
-       . self::_giveMeStringLength($item_value)
-       . $item_value;
-     }
-     $item++;
+        $charset = strtolower($charset);
+        $this->charset = $charset;
+        $this->meta->charset = chr(0x47) // charset type | value-tag
+            . chr(0x00) . chr(0x12) // name-length
+            . "attributes-charset" // attributes-charset | name
+            . self::_giveMeStringLength($charset) // value-length
+            . $charset; // value
+        self::_putDebug(sprintf(_("Charset: %s") , $charset) , 2);
+        $this->setup->charset = 1;
     }
-   }
-  }
-  $printerattributes = '';
-  foreach($this->printer_tags as $key => $values) 
-  {
-   $item = 0;
-   if (array_key_exists('value', $values))
-   {
-    foreach($values['value'] as $item_value) 
+
+    public function setLanguage($language = 'en_us') 
     {
-     if ($item == 0)
-     {
-      $printerattributes .=
-       $values['systag']
-       . self::_giveMeStringLength($key)
-       . $key
-       . self::_giveMeStringLength($item_value)
-       . $item_value;
-     }
-     else
-     {
-      $printerattributes .=
-       $values['systag']
-       . self::_giveMeStringLength('')
-       . self::_giveMeStringLength($item_value)
-       . $item_value;
-     }
-     $item++;
+        $language = strtolower($language);
+        $this->meta->language = chr(0x48) // natural-language type | value-tag
+            . chr(0x00) . chr(0x1B) //  name-length
+            . "attributes-natural-language" //attributes-natural-language
+            . self::_giveMeStringLength($language) // value-length
+            . $language; // value
+        self::_putDebug(sprintf(_("Language: %s") , $language) , 2);
+        $this->setup->language = 1;
     }
-   }
-  }
-  reset($this->job_tags);
-  reset($this->operation_tags);
-  reset($this->printer_tags);
-  return true;
- }
-
- protected function _giveMeStringLength($string) 
- {
-  $length = strlen($string);
-  if ($length > ((0xFF << 8) + 0xFF)  )
-  {
-   $errmsg = sprintf (
-     _('max string length for an ipp meta-information = %d, while here %d'),
-     ((0xFF << 8) + 0xFF), $length);
-
-   if ($this->with_exceptions)
-   {
-    throw new ippException($errmsg);
-   }
-   else
-   {
-    trigger_error ($errmsg, E_USER_ERROR);
-   }
-  }
-  $int1 = $length & 0xFF;
-  $length -= $int1;
-  $length = $length >> 8;
-  $int2 = $length & 0xFF;
-  return chr($int2) . chr($int1);
- }
-
- protected function _enumBuild($tag, $value) 
- {
-  switch ($tag) 
-  {
-   case "orientation-requested":
-    switch ($value) 
+
+    public function setDocumentFormat($mime_media_type = 'application/octet-stream') 
     {
-     case 'portrait':
-      $value = chr(3);
-      break;
+        self::setBinary();
+        $length = chr(strlen($mime_media_type));
+        while (strlen($length) < 2) $length = chr(0x00) . $length;
+        self::_putDebug(sprintf(_("mime type: %s") , $mime_media_type) , 2);
+        $this->meta->mime_media_type = chr(0x49) // document-format tag
+            . self::_giveMeStringLength('document-format') . 'document-format' //
+            . self::_giveMeStringLength($mime_media_type) . $mime_media_type; // value
+        $this->setup->mime_media_type = 1;
+    }
+
+    // setDocumentFormat alias for backward compatibility
+    public function setMimeMediaType($mime_media_type = "application/octet-stream") 
+    {
+        self::setDocumentFormat($mime_media_type);
+    }
 
-     case 'landscape':
-      $value = chr(4);
-      break;
+    public function setCopies($nbrcopies = 1) 
+    {
+        $this->meta->copies = "";
+
+        if ($nbrcopies == 1 || !$nbrcopies)
+        {
+            return true;
+        }
+
+        $copies = self::_integerBuild($nbrcopies);
+        $this->meta->copies = chr(0x21) // integer type | value-tag
+            . chr(0x00) . chr(0x06) //             name-length
+            . "copies" // copies    |             name
+            . self::_giveMeStringLength($copies) // value-length
+            . $copies;
+        self::_putDebug(sprintf(_("Copies: %s") , $nbrcopies) , 2);
+        $this->setup->copies = 1;
+    }
 
-     case 'reverse-landscape':
-      $value = chr(5);
-      break;
+    public function setDocumentName($document_name = "") 
+    {
+        $this->meta->document_name = "";
+        if (!$document_name) {
+            return true;
+        }
+        $document_name = substr($document_name, 0, 1023);
+        $length = strlen($document_name);
+        $length = chr($length);
+        while (strlen($length) < 2) $length = chr(0x00) . $length;
+        self::_putDebug(sprintf(_("document name: %s") , $document_name) , 2);
+        $this->meta->document_name = chr(0x41) // textWithoutLanguage tag
+            . chr(0x00) . chr(0x0d) // name-length
+            . "document-name" // mimeMediaType
+            . self::_giveMeStringLength($document_name) . $document_name; // value
 
-     case 'reverse-portrait':
-      $value = chr(6);
-      break;
     }
-   break;
 
-   case "print-quality":
-    switch ($value) 
+    public function setJobName($jobname = '', $absolute = false) 
     {
-     case 'draft':
-      $value = chr(3);
-      break;
+        $this->meta->jobname = '';
+        if ($jobname == '') 
+        {
+            $this->meta->jobname = '';
+            return true;
+        }
+        $postpend = date('-H:i:s-') . $this->_setJobId();
+        if ($absolute) {
+            $postpend = '';
+        }
+        if (isset($this->values->jobname) && $jobname == '(PHP)')
+        {
+            $jobname = $this->values->jobname;
+        }
+        $this->values->jobname = $jobname;
+        $jobname.= $postpend;
+        $this->meta->jobname = chr(0x42) // nameWithoutLanguage type || value-tag
+            . chr(0x00) . chr(0x08) //  name-length
+            . "job-name" //  job-name || name
+            . self::_giveMeStringLength($jobname) // value-length
+            . $jobname; // value
+        self::_putDebug(sprintf(_("Job name: %s") , $jobname) , 2);
+        $this->setup->jobname = 1;
+    }
 
-     case 'normal':
-      $value = chr(4);
-      break;
+    public function setUserName($username = 'PHP-SERVER') 
+    {
+        $this->requesting_user = $username;
+        $this->meta->username = '';
+        if (!$username) {
+            return true;
+        }
+        if ($username == 'PHP-SERVER' && isset($this->meta->username)) {
+            return TRUE;
+        }
+        /*
+        $value_length = 0x00;
+        for ($i = 0; $i < strlen($username); $i++) 
+        {
+            $value_length+= 0x01;
+        }
+        $value_length = chr($value_length);
+        while (strlen($value_length) < 2) $value_length = chr(0x00) . $value_length;
+        */
+        $this->meta->username = chr(0x42) // keyword type || value-tag
+            . chr(0x00) . chr(0x14) // name-length
+            . "requesting-user-name" 
+            . self::_giveMeStringLength($username) // value-length
+            . $username;
+        self::_putDebug(sprintf(_("Username: %s") , $username) , 2);
+        $this->setup->username = 1;
+    }
 
-     case 'high':
-      $value = chr(5);
-      break;
+    public function setAuthentification($username, $password) 
+    {
+        self::setAuthentication($username, $password);
     }
-   break;
 
-   case "finishing":
-    switch ($value) 
+    public function setAuthentication($username, $password) 
     {
-     case 'none':
-      $value = chr(3);
-      break;
+        $this->password = $password;
+        $this->username = $username;
+        self::_putDebug(_("Setting password") , 2);
+        $this->setup->password = 1;
+    }
 
-     case 'staple':
-      $value = chr(4);
-      break;
+    public function setSides($sides = 2) 
+    {
+        $this->meta->sides = '';
+        if (!$sides)
+        {
+            return true;
+        }
+
+        switch ($sides) 
+        {
+            case 1:
+                $sides = "one-sided";
+                break;
+
+            case 2:
+                $sides = "two-sided-long-edge";
+                break;
+
+            case "2CE":
+                $sides = "two-sided-short-edge";
+                break;
+        }
+
+        $this->meta->sides = chr(0x44) // keyword type | value-tag
+            . chr(0x00) . chr(0x05) //        name-length
+            . "sides" // sides |             name
+            . self::_giveMeStringLength($sides) //               value-length
+            . $sides; // one-sided |          value
+        self::_putDebug(sprintf(_("Sides value set to %s") , $sides) , 2);
+    }
 
-     case 'punch':
-      $value = chr(5);
-      break;
+    public function setFidelity() 
+    {
+        // whether the server can't replace any attributes
+        // (eg, 2 sided print is not possible,
+        // so print one sided) and DO NOT THE JOB.
+        $this->meta->fidelity = chr(0x22) // boolean type  |  value-tag
+            . chr(0x00) . chr(0x16) //                  name-length
+            . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name
+            . chr(0x00) . chr(0x01) //  value-length
+            . chr(0x01); //  true | value
+        self::_putDebug(_("Fidelity attribute is set (paranoid mode)") , 3);
+    }
 
-     case 'cover':
-      $value = chr(6);
-      break;
+    public function unsetFidelity() 
+    {
+        // whether the server can replace any attributes
+        // (eg, 2 sided print is not possible,
+        // so print one sided) and DO THE JOB.
+        $this->meta->fidelity = chr(0x22) //  boolean type | value-tag
+            . chr(0x00) . chr(0x16) //        name-length
+            . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name
+            . chr(0x00) . chr(0x01) //               value-length
+            . chr(0x00); // false |                   value
+        self::_putDebug(_("Fidelity attribute is unset") , 2);
+    }
 
-     case 'bind':
-      $value = chr(7);
-      break;
+    public function setMessage($message = '')
+    {
+        $this->meta->message = '';
+        if (!$message) {
+            return true;
+        }
+        $this->meta->message = 
+            chr(0x41) // attribute type = textWithoutLanguage
+                . chr(0x00) 
+                . chr(0x07) 
+                . "message" 
+                . self::_giveMeStringLength(substr($message, 0, 127))
+                . substr($message, 0, 127);
+        self::_putDebug(sprintf(_('Setting message to "%s"') , $message) , 2);
+    }
 
-     case 'saddle-stitch':
-      $value = chr(8);
-      break;
+    public function setPageRanges($page_ranges) 
+    {
+        // $pages_ranges = string:  "1:5 10:25 40:52 ..."
+        // to unset, specify an empty string.
+        $this->meta->page_range = '';
+        if (!$page_ranges) {
+            return true;
+        }
+        $page_ranges = trim(str_replace("-", ":", $page_ranges));
+        $first = true;
+        #$page_ranges = split(' ', $page_ranges);
+        $page_ranges = preg_split('# #', $page_ranges);
+        foreach($page_ranges as $page_range) 
+        {
+            $value = self::_rangeOfIntegerBuild($page_range);
+            if ($first)
+            {
+                $this->meta->page_ranges .= 
+                $this->tags_types['rangeOfInteger']['tag'] 
+                    . self::_giveMeStringLength('page-ranges') 
+                    . 'page-ranges' 
+                    . self::_giveMeStringLength($value) 
+                    . $value;
+            }
+            else
+            {
+                $this->meta->page_ranges .= 
+                $this->tags_types['rangeOfInteger']['tag'] 
+                    . self::_giveMeStringLength('') 
+                    . self::_giveMeStringLength($value) 
+                    . $value;
+                $first = false;
+            }
+        }
+    }
 
-     case 'edge-stitch':
-      $value = chr(9);
-      break;
+    public function setAttribute($attribute, $values) 
+    {
+        $operation_attributes_tags = array_keys($this->operation_tags);
+        $job_attributes_tags = array_keys($this->job_tags);
+        $printer_attributes_tags = array_keys($this->printer_tags);
+        self::unsetAttribute($attribute);
+        if (in_array($attribute, $operation_attributes_tags)) 
+        {
+            if (!is_array($values))
+            {
+                self::_setOperationAttribute($attribute, $values);
+            }
+            else
+            {
+                foreach($values as $value)
+                {
+                    self::_setOperationAttribute($attribute, $value);
+                }
+            }
+        }
+        elseif (in_array($attribute, $job_attributes_tags)) 
+        {
+            if (!is_array($values))
+            {
+                self::_setJobAttribute($attribute, $values);
+            }
+            else 
+            {
+                foreach($values as $value)
+                {
+                    self::_setJobAttribute($attribute, $value);
+                }
+            }
+        }
+        elseif (in_array($attribute, $printer_attributes_tags)) 
+        {
+            if (!is_array($values))
+            {
+                self::_setPrinterAttribute($attribute, $values);
+            }
+            else
+            {
+                foreach($values as $value)
+                {
+                    self::_setPrinterAttribute($attribute, $value);
+                }
+            }
+        }
+        else
+        {
+            trigger_error(
+                sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'),
+                    $attribute) , E_USER_NOTICE);
+            self::_putDebug(
+                sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'),
+                    $attribute) , 3);
+            self::_errorLog(
+                sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'),
+                    $attribute) , 2);
+            return FALSE;
+        }
+    }
 
-     case 'staple-top-left':
-      $value = chr(20);
-      break;
+    public function unsetAttribute($attribute) 
+    {
+        $operation_attributes_tags = array_keys($this->operation_tags);
+        $job_attributes_tags = array_keys($this->job_tags);
+        $printer_attributes_tags = array_keys($this->printer_tags);
+        if (in_array($attribute, $operation_attributes_tags)) 
+        {
+            unset( 
+                $this->operation_tags[$attribute]['value'],
+                $this->operation_tags[$attribute]['systag']
+            );
+        }
+        elseif (in_array($attribute, $job_attributes_tags))
+        {
+            unset(
+                $this->job_tags[$attribute]['value'],
+                $this->job_tags[$attribute]['systag']
+            );
+        }
+        elseif (in_array($attribute, $printer_attributes_tags))
+        {
+            unset(
+                $this->printer_tags[$attribute]['value'],
+                $this->printer_tags[$attribute]['systag']
+            );
+        }
+        else 
+        {
+            trigger_error(
+                sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'),
+                    $attribute) , E_USER_NOTICE);
+            self::_putDebug(
+                sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'),
+                    $attribute) , 3);
+            self::_errorLog(
+                sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'),
+                    $attribute) , 2);
+            return FALSE;
+        }
+        return true;
+    }
+
+    //
+    // LOGGING / DEBUGGING
+    //
+    /**
+     * Sets log file destination. Creates the file if has permission.
+     *
+     * @param string $log_destination
+     * @param string $destination_type
+     * @param int $level
+     *
+     * @throws ippException
+     */
+    public function setLog($log_destination, $destination_type = 'file', $level = 2) 
+    {
+        if (!file_exists($log_destination) && is_writable(dirname($log_destination)))
+        {
+            touch($log_destination);
+            chmod($log_destination, 0777);
+        }
+
+        switch ($destination_type) 
+        {
+            case 'file':
+            case 3:
+                $this->log_destination = $log_destination;
+                $this->log_type = 3;
+                break;
+
+            case 'logger':
+            case 0:
+                $this->log_destination = '';
+                $this->log_type = 0;
+                break;
+
+            case 'e-mail':
+            case 1:
+                $this->log_destination = $log_destination;
+                $this->log_type = 1;
+                break;
+        }
+        $this->log_level = $level;
+    }
+
+    public function printDebug() 
+    {
+        for ($i = 0; $i < $this->debug_count; $i++)
+        {
+            echo $this->debug[$i], "\n";
+        }
+        $this->debug = array();
+        $this->debug_count = 0;
+    }
+
+    public function getDebug() 
+    {
+        $debug = '';
+        for ($i = 0; $i < $this->debug_count; $i++)
+        {
+            $debug.= $this->debug[$i];
+        }
+        $this->debug = array();
+        $this->debug_count = 0;
+        return $debug;
+    }
+
+    //
+    // OPERATIONS
+    //
+    public function printJob() 
+    {
+        // this BASIC version of printJob do not parse server
+        // output for job's attributes
+        self::_putDebug(
+            sprintf(
+                "************** Date: %s ***********",
+                date('Y-m-d H:i:s')
+            )
+        );
+        if (!$this->_stringJob()) {
+            return FALSE;
+        }
+        if (is_readable($this->data)) 
+        {
+            self::_putDebug(_("Printing a FILE"));
+            $this->output = $this->stringjob;
+            if ($this->setup->datatype == "TEXT")
+            {
+                $this->output.= chr(0x16);
+            }
+            $post_values = array(
+                "Content-Type" => "application/ipp",
+                "Data" => $this->output,
+                "File" => $this->data
+            );
+            if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed))
+            {
+                $post_values = array_merge(
+                    $post_values,
+                    array(
+                        "Filetype" => "TEXT"
+                    )
+                );
+            }
+        }
+        else
+        {
+            self::_putDebug(_("Printing DATA"));
+            $this->output = 
+                $this->stringjob
+                    . $this->datahead
+                    . $this->data
+                    . $this->datatail;
+            $post_values = array(
+                "Content-Type" => "application/ipp",
+                "Data" => $this->output
+            );
+        }
+        if (self::_sendHttp($post_values, $this->paths["printers"]))
+        {
+            self::_parseServerOutput();
+        }
+        if (isset($this->serveroutput) && isset($this->serveroutput->status)) 
+        {
+            $this->status = array_merge($this->status, array(
+                $this->serveroutput->status
+            ));
+            if ($this->serveroutput->status == "successfull-ok")
+            {
+                self::_errorLog(
+                    sprintf("printing job %s: ", $this->last_job) 
+                        . $this->serveroutput->status,
+                    3);
+            }
+            else
+            {
+                self::_errorLog(
+                    sprintf("printing job: ", $this->last_job) 
+                        . $this->serveroutput->status,
+                    1);
+            }
+                return $this->serveroutput->status;
+        }
+
+    $this->status = 
+        array_merge($this->status, array("OPERATION FAILED"));
+        $this->jobs = 
+            array_merge($this->jobs, array(""));
+        $this->jobs_uri = 
+            array_merge($this->jobs_uri, array(""));
+
+        self::_errorLog("printing job : OPERATION FAILED", 1);
+        return false;
+    }
+
+    //
+    // HTTP OUTPUT
+    //
+    protected function _sendHttp($post_values, $uri) 
+    {
+        /*
+            This function Copyright (C) 2005-2006 Thomas Harding, Manuel Lemos
+        */
+        $this->response_completed[] = "no";
+        unset($this->serverouptut);
+        self::_putDebug(_("Processing HTTP request") , 2);
+        $this->serveroutput->headers = array();
+        $this->serveroutput->body = "";
+        $http = new http_class;
+        if (!$this->unix) {
+            $http->host = $this->host;
+        }
+        else {
+            $http->host = "localhost";
+        }
+        $http->with_exceptions = $this->with_exceptions;
+        if ($this->debug_http) 
+        {
+            $http->debug = 1;
+            $http->html_debug = 0;
+        }
+        else
+        {
+            $http->debug = 0;
+            $http->html_debug = 0;
+        }
+        $url = "http://" . $this->host;
+        if ($this->ssl) {
+            $url = "https://" . $this->host;
+        }
+        if ($this->unix) {
+            $url = "unix://" . $this->host;
+        }
+        $http->port = $this->port;
+        $http->timeout = $this->http_timeout;
+        $http->data_timeout = $this->http_data_timeout;
+        $http->force_multipart_form_post = false;
+        $http->user = $this->username;
+        $http->password = $this->password;
+        $error = $http->GetRequestArguments($url, $arguments);
+        $arguments["RequestMethod"] = "POST";
+        $arguments["Headers"] = array(
+            "Content-Type" => "application/ipp"
+        );
+        $arguments["BodyStream"] = array(
+            array(
+                "Data" => $post_values["Data"]
+            )
+        );
+        if (isset($post_values["File"])) {
+            $arguments["BodyStream"][] = array(
+                "File" => $post_values["File"]
+            );
+        }
+        if (isset($post_values["FileType"]) 
+            && !strcmp($post_values["FileType"], "TEXT")
+        )
+        {
+            $arguments["BodyStream"][] = array("Data" => Chr(12));
+        }
+        $arguments["RequestURI"] = $uri;
+        if ($this->with_exceptions && $this->handle_http_exceptions) 
+        {
+            try
+            {
+                $success = $http->Open($arguments);
+            }
+            catch(httpException $e) 
+            {
+                throw new ippException(
+                    sprintf("http error: %s", $e->getMessage()),
+                        $e->getErrno());
+            }
+        }
+        else
+        {
+            $success = $http->Open($arguments);
+        }
+        if ($success[0] == true) 
+        {
+            $success = $http->SendRequest($arguments);
+            if ($success[0] == true) 
+            {
+                self::_putDebug("H T T P    R E Q U E S T :");
+                self::_putDebug("Request headers:");
+                for (Reset($http->request_headers) , $header = 0; $header < count($http->request_headers); Next($http->request_headers) , $header++) 
+                {
+                    $header_name = Key($http->request_headers);
+                    if (GetType($http->request_headers[$header_name]) == "array") 
+                    {
+                        for ($header_value = 0; $header_value < count($http->request_headers[$header_name]); $header_value++)
+                        {
+                            self::_putDebug($header_name . ": " . $http->request_headers[$header_name][$header_value]);
+                        }
+                    }
+                    else
+                    {
+                        self::_putDebug($header_name . ": " . $http->request_headers[$header_name]);
+                    }
+                }
+                self::_putDebug("Request body:");
+                self::_putDebug(
+                    htmlspecialchars($http->request_body) 
+                        . "*********** END REQUEST BODY *********"
+                );
+                $i = 0;
+                $headers = array();
+                unset($this->serveroutput->headers);
+                $http->ReadReplyHeaders($headers);
+                self::_putDebug("H T T P    R E S P O N S E :");
+                self::_putDebug("Response headers:");
+                for (Reset($headers) , $header = 0; $header < count($headers); Next($headers) , $header++) 
+                {
+                    $header_name = Key($headers);
+                    if (GetType($headers[$header_name]) == "array") 
+                    {
+                        for ($header_value = 0; $header_value < count($headers[$header_name]); $header_value++) 
+                        {
+                            self::_putDebug($header_name . ": " . $headers[$header_name][$header_value]);
+                            $this->serveroutput->headers[$i] = 
+                                $header_name . ": " 
+                                    . $headers[$header_name][$header_value];
+                            $i++;
+                        }
+                    }
+                    else
+                    {
+                        self::_putDebug($header_name . ": " . $headers[$header_name]);
+                        $this->serveroutput->headers[$i] = 
+                            $header_name 
+                                . ": " 
+                                . $headers[$header_name];
+                        $i++;
+                    }
+                }
+                self::_putDebug("\n\nResponse body:\n");
+                $this->serveroutput->body = "";
+                for (;;) 
+                {
+                    $http->ReadReplyBody($body, 1024);
+                    if (strlen($body) == 0) {
+                        break;
+                    }
+
+                    self::_putDebug(htmlentities($body));
+                    $this->serveroutput->body.= $body;
+                }
+                self::_putDebug("********* END RESPONSE BODY ********");
+            }
+        }
+        $http->Close();
+        return true;
+    }
 
-     case 'staple-bottom-left':
-      $value = chr(21);
-      break;
+    //
+    // INIT
+    //
+    protected function _initTags() 
+    {
+        $this->tags_types = array(
+            "unsupported" => array(
+                "tag" => chr(0x10) ,
+                "build" => ""
+            ) ,
+            "reserved" => array(
+                "tag" => chr(0x11) ,
+                "build" => ""
+            ) ,
+            "unknown" => array(
+                "tag" => chr(0x12) ,
+                "build" => ""
+            ) ,
+            "no-value" => array(
+                "tag" => chr(0x13) ,
+                "build" => "no_value"
+            ) ,
+            "integer" => array(
+                "tag" => chr(0x21) ,
+                "build" => "integer"
+            ) ,
+            "boolean" => array(
+                "tag" => chr(0x22) ,
+                "build" => "boolean"
+            ) ,
+            "enum" => array(
+                "tag" => chr(0x23) ,
+                "build" => "enum"
+            ) ,
+            "octetString" => array(
+                "tag" => chr(0x30) ,
+                "build" => "octet_string"
+            ) ,
+            "datetime" => array(
+                "tag" => chr(0x31) ,
+                "build" => "datetime"
+            ) ,
+            "resolution" => array(
+                "tag" => chr(0x32) ,
+                "build" => "resolution"
+            ) ,
+            "rangeOfInteger" => array(
+                "tag" => chr(0x33) ,
+                "build" => "range_of_integers"
+            ) ,
+            "textWithLanguage" => array(
+                "tag" => chr(0x35) ,
+                "build" => "string"
+            ) ,
+            "nameWithLanguage" => array(
+                "tag" => chr(0x36) ,
+                "build" => "string"
+            ) ,
+            /*
+            "text" => array ("tag" => chr(0x40),
+            "build" => "string"),
+            "text string" => array ("tag" => chr(0x40),
+            "build" => "string"),
+            */
+            "textWithoutLanguage" => array(
+                "tag" => chr(0x41) ,
+                "build" => "string"
+            ) ,
+            "nameWithoutLanguage" => array(
+                "tag" => chr(0x42) ,
+                "buid" => "string"
+            ) ,
+            "keyword" => array(
+                "tag" => chr(0x44) ,
+                "build" => "string"
+            ) ,
+            "uri" => array(
+                "tag" => chr(0x45) ,
+                "build" => "string"
+            ) ,
+            "uriScheme" => array(
+                "tag" => chr(0x46) ,
+                "build" => "string"
+            ) ,
+            "charset" => array(
+                "tag" => chr(0x47) ,
+                "build" => "string"
+            ) ,
+            "naturalLanguage" => array(
+                "tag" => chr(0x48) ,
+                "build" => "string"
+            ) ,
+            "mimeMediaType" => array(
+                "tag" => chr(0x49) ,
+                "build" => "string"
+            ) ,
+            "extendedAttributes" => array(
+                "tag" => chr(0x7F) ,
+                "build" => "extended"
+            ) ,
+        );
+        $this->operation_tags = array(
+            "compression" => array(
+                "tag" => "keyword"
+            ) ,
+            "document-natural-language" => array(
+                "tag" => "naturalLanguage"
+            ) ,
+            "job-k-octets" => array(
+                "tag" => "integer"
+            ) ,
+            "job-impressions" => array(
+                "tag" => "integer"
+            ) ,
+            "job-media-sheets" => array(
+                "tag" => "integer"
+            ) ,
+        );
+        $this->job_tags = array(
+            "job-priority" => array(
+                "tag" => "integer"
+            ) ,
+            "job-hold-until" => array(
+                "tag" => "keyword"
+            ) ,
+            "job-sheets" => array(
+                "tag" => "keyword"
+            ) , //banner page
+            "multiple-document-handling" => array(
+                "tag" => "keyword"
+            ) ,
+            //"copies" => array("tag" => "integer"),
+            "finishings" => array(
+                "tag" => "enum"
+            ) ,
+            //"page-ranges" => array("tag" => "rangeOfInteger"), // has its own function
+            //"sides" => array("tag" => "keyword"), // has its own function
+            "number-up" => array(
+                "tag" => "integer"
+            ) ,
+            "orientation-requested" => array(
+                "tag" => "enum"
+            ) ,
+            "media" => array(
+                "tag" => "keyword"
+            ) ,
+            "printer-resolution" => array(
+                "tag" => "resolution"
+            ) ,
+            "print-quality" => array(
+                "tag" => "enum"
+            ) ,
+            "job-message-from-operator" => array(
+                "tag" => "textWithoutLanguage"
+            ) ,
+        );
+        $this->printer_tags = array(
+            "requested-attributes" => array(
+                "tag" => "keyword"
+            )
+        );
+    }
 
-     case 'staple-top-right':
-      $value = chr(22);
-      break;
+    //
+    // SETUP
+    //
+    protected function _setOperationId() 
+    {
+        $prepend = '';
+        $this->operation_id+= 1;
+        $this->meta->operation_id = self::_integerBuild($this->operation_id);
+        self::_putDebug("operation id is: " . $this->operation_id, 2);
+    }
 
-     case 'staple-bottom-right':
-      $value = chr(23);
-      break;
+    protected function _setJobId() 
+    {
+        $this->meta->jobid+= 1;
+        $prepend = '';
+        $prepend_length = 4 - strlen($this->meta->jobid);
+        for ($i = 0; $i < $prepend_length; $i++) {
+            $prepend.= '0';
+        }
+        return $prepend . $this->meta->jobid;
+    }
 
-     case 'edge-stitch-left':
-      $value = chr(24);
-      break;
+    protected function _setJobUri($job_uri) 
+    {
+        $this->meta->job_uri = chr(0x45) // type uri
+            . chr(0x00) . chr(0x07) // name-length
+            . "job-uri"
+            //. chr(0x00).chr(strlen($job_uri))
+            . self::_giveMeStringLength($job_uri) . $job_uri;
+        self::_putDebug("job-uri is: " . $job_uri, 2);
+    }
 
-     case 'edge-stitch-top':
-      $value = chr(25);
-      break;
+    //
+    // RESPONSE PARSING
+    //
+    protected function _parseServerOutput() 
+    {
+        $this->serveroutput->response = array();
+        if (!self::_parseHttpHeaders()) {
+            return FALSE;
+        }
+        $this->_parsing->offset = 0;
+        self::_parseIppVersion();
+        self::_parseStatusCode();
+        self::_parseRequestID();
+        $this->_parseResponse();
+        //devel
+        self::_putDebug(
+            sprintf("***** IPP STATUS: %s ******", $this->serveroutput->status),
+            4);
+        self::_putDebug("****** END OF OPERATION ****");
+        return true;
+    }
 
-     case 'edge-stitch-right':
-      $value = chr(26);
-      break;
+    protected function _parseHttpHeaders() 
+    {
+        $response = "";
+        switch ($this->serveroutput->headers[0]) 
+        {
+            case "http/1.1 200 ok: ":
+                $this->serveroutput->httpstatus = "HTTP/1.1 200 OK";
+                $response = "OK";
+                break;
+
+            // primitive http/1.0 for Lexmark printers (from Rick Baril)
+            case "http/1.0 200 ok: ":
+                $this->serveroutput->httpstatus = "HTTP/1.0 200 OK";
+                $response = "OK";
+                break;
+
+            case "http/1.1 100 continue: ":
+                $this->serveroutput->httpstatus = "HTTP/1.1 100 CONTINUE";
+                $response = "OK";
+                break;
+
+            case "":
+                $this->serveroutput->httpstatus = "HTTP/1.1 000 No Response From Server";
+                $this->serveroutput->status = "HTTP-ERROR-000_NO_RESPONSE_FROM_SERVER";
+                trigger_error("No Response From Server", E_USER_WARNING);
+                self::_errorLog("No Response From Server", 1);
+                $this->disconnected = 1;
+                return FALSE;
+                break;
+
+            default:
+                $server_response = preg_replace("/: $/", '', $this->serveroutput->headers[0]);
+                #$strings = split(' ', $server_response, 3);
+                $strings = preg_split('# #', $server_response, 3);
+                $errno = $strings[1];
+                $string = strtoupper(str_replace(' ', '_', $strings[2]));
+                trigger_error(
+                    sprintf(_("server responds %s") , $server_response),
+                    E_USER_WARNING);
+                self::_errorLog("server responds " . $server_response, 1);
+                $this->serveroutput->httpstatus =
+                    strtoupper($strings[0])
+                        . " "
+                        . $errno
+                        . " "
+                        . ucfirst($strings[2]);
+
+                $this->serveroutput->status =
+                    "HTTP-ERROR-"
+                        . $errno
+                        . "-"
+                        . $string;
+                $this->disconnected = 1;
+                return FALSE;
+                break;
+        }
+        unset($this->serveroutput->headers);
+        return TRUE;
+    }
 
-     case 'edge-stitch-bottom':
-      $value = chr(27);
-      break;
+    protected function _parseIppVersion() 
+    {
+        $ippversion =
+            (ord($this->serveroutput->body[$this->_parsing->offset]) * 256)
+                + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+        switch ($ippversion) 
+        {
+            case 0x0101:
+                $this->serveroutput->ipp_version = "1.1";
+                break;
+
+            default:
+                $this->serveroutput->ipp_version =
+                    sprintf("%u.%u (Unknown)",
+                        ord($this->serveroutput->body[$this->_parsing->offset]) * 256,
+                        ord($this->serveroutput->body[$this->_parsing->offset + 1]));
+                break;
+        }
+        self::_putDebug("I P P    R E S P O N S E :\n\n");
+        self::_putDebug(
+            sprintf("IPP version %s%s: %s",
+                ord($this->serveroutput->body[$this->_parsing->offset]),
+                ord($this->serveroutput->body[$this->_parsing->offset + 1]),
+                $this->serveroutput->ipp_version));
+        $this->_parsing->offset+= 2;
+        return;
+    }
 
-     case 'staple-dual-left':
-      $value = chr(28);
-      break;
+    protected function _parseStatusCode() 
+    {
+        $status_code =
+            (ord($this->serveroutput->body[$this->_parsing->offset]) * 256)
+            + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+        $this->serveroutput->status = "NOT PARSED";
+        $this->_parsing->offset+= 2;
+        if (strlen($this->serveroutput->body) < $this->_parsing->offset)
+        {
+            return false;
+        }
+        if ($status_code < 0x00FF) 
+        {
+            $this->serveroutput->status = "successfull";
+        }
+        elseif ($status_code < 0x01FF) 
+        {
+            $this->serveroutput->status = "informational";
+        }
+        elseif ($status_code < 0x02FF) 
+        {
+            $this->serveroutput->status = "redirection";
+        }
+        elseif ($status_code < 0x04FF) 
+        {
+            $this->serveroutput->status = "client-error";
+        }
+        elseif ($status_code < 0x05FF) 
+        {
+            $this->serveroutput->status = "server-error";
+        }
+        switch ($status_code) 
+        {
+            case 0x0000:
+                $this->serveroutput->status = "successfull-ok";
+                break;
+
+            case 0x0001:
+                $this->serveroutput->status = "successful-ok-ignored-or-substituted-attributes";
+                break;
+
+            case 0x002:
+                $this->serveroutput->status = "successful-ok-conflicting-attributes";
+                break;
+
+            case 0x0400:
+                $this->serveroutput->status = "client-error-bad-request";
+                break;
+
+            case 0x0401:
+                $this->serveroutput->status = "client-error-forbidden";
+                break;
+
+            case 0x0402:
+                $this->serveroutput->status = "client-error-not-authenticated";
+                break;
+
+            case 0x0403:
+                $this->serveroutput->status = "client-error-not-authorized";
+                break;
+
+            case 0x0404:
+                $this->serveroutput->status = "client-error-not-possible";
+                break;
+
+            case 0x0405:
+                $this->serveroutput->status = "client-error-timeout";
+                break;
+
+            case 0x0406:
+                $this->serveroutput->status = "client-error-not-found";
+                break;
+
+            case 0x0407:
+                $this->serveroutput->status = "client-error-gone";
+                break;
+
+            case 0x0408:
+                $this->serveroutput->status = "client-error-request-entity-too-large";
+                break;
+
+            case 0x0409:
+                $this->serveroutput->status = "client-error-request-value-too-long";
+                break;
+
+            case 0x040A:
+                $this->serveroutput->status = "client-error-document-format-not-supported";
+                break;
+
+            case 0x040B:
+                $this->serveroutput->status = "client-error-attributes-or-values-not-supported";
+                break;
+
+            case 0x040C:
+                $this->serveroutput->status = "client-error-uri-scheme-not-supported";
+                break;
+
+            case 0x040D:
+                $this->serveroutput->status = "client-error-charset-not-supported";
+                break;
+
+            case 0x040E:
+                $this->serveroutput->status = "client-error-conflicting-attributes";
+                break;
+
+            case 0x040F:
+                $this->serveroutput->status = "client-error-compression-not-supported";
+                break;
+
+            case 0x0410:
+                $this->serveroutput->status = "client-error-compression-error";
+                break;
+
+            case 0x0411:
+                $this->serveroutput->status = "client-error-document-format-error";
+                break;
+
+            case 0x0412:
+                $this->serveroutput->status = "client-error-document-access-error";
+                break;
+
+            case 0x0413: // RFC3380
+                $this->serveroutput->status = "client-error-attributes-not-settable";
+                break;
+
+            case 0x0500:
+                $this->serveroutput->status = "server-error-internal-error";
+                break;
+
+            case 0x0501:
+                $this->serveroutput->status = "server-error-operation-not-supported";
+                break;
+
+            case 0x0502:
+                $this->serveroutput->status = "server-error-service-unavailable";
+                break;
+
+            case 0x0503:
+                $this->serveroutput->status = "server-error-version-not-supported";
+                break;
+
+            case 0x0504:
+                $this->serveroutput->status = "server-error-device-error";
+                break;
+
+            case 0x0505:
+                $this->serveroutput->status = "server-error-temporary-error";
+                break;
+
+            case 0x0506:
+                $this->serveroutput->status = "server-error-not-accepting-jobs";
+                break;
+
+            case 0x0507:
+                $this->serveroutput->status = "server-error-busy";
+                break;
+
+            case 0x0508:
+                $this->serveroutput->status = "server-error-job-canceled";
+                break;
+
+            case 0x0509:
+                $this->serveroutput->status = "server-error-multiple-document-jobs-not-supported";
+                break;
+
+            default:
+                break;
+        }
+        self::_putDebug(
+            sprintf(
+                "status-code: %s%s: %s ",
+                $this->serveroutput->body[$this->_parsing->offset],
+                $this->serveroutput->body[$this->_parsing->offset + 1],
+                $this->serveroutput->status),
+            4);
+        return;
+    }
 
-     case 'staple-dual-top':
-      $value = chr(29);
-      break;
+    protected function _parseRequestID() 
+    {
+        $this->serveroutput->request_id =
+            self::_interpretInteger(
+                substr($this->serveroutput->body, $this->_parsing->offset, 4)
+            );
+        self::_putDebug("request-id " . $this->serveroutput->request_id, 2);
+        $this->_parsing->offset+= 4;
+        return;
+    }
 
-     case 'staple-dual-right':
-      $value = chr(30);
-      break;
+    protected function _interpretInteger($value) 
+    {
+        // they are _signed_ integers
+        $value_parsed = 0;
+        for ($i = strlen($value); $i > 0; $i --)
+        {
+            $value_parsed +=
+                (
+                    (1 << (($i - 1) * 8)) 
+                        * 
+                        ord($value[strlen($value) - $i])
+                );
+        }
+        if ($value_parsed >= 2147483648)
+        {
+            $value_parsed -= 4294967296;
+        }
+        return $value_parsed;
+    }
 
-     case 'staple-dual-bottom':
-      $value = chr(31);
-      break;
+    protected function _parseResponse() 
+    {
     }
-   break;
-  }
-  $prepend = '';
-  while ((strlen($value) + strlen($prepend)) < 4)
-  {
-   $prepend .= chr(0);
-  }
-  return $prepend . $value;
- }
-
- protected function _integerBuild($value) 
- {
-  if ($value >= 2147483647 || $value < - 2147483648) 
-  {
-   trigger_error(
-     _("Values must be between -2147483648 and 2147483647: assuming '0'") , E_USER_WARNING);
-   return chr(0x00) . chr(0x00) . chr(0x00) . chr(0x00);
-  }
-  $initial_value = $value;
-  $int1 = $value & 0xFF;
-  $value -= $int1;
-  $value = $value >> 8;
-  $int2 = $value & 0xFF;
-  $value-= $int2;
-  $value = $value >> 8;
-  $int3 = $value & 0xFF;
-  $value-= $int3;
-  $value = $value >> 8;
-  $int4 = $value & 0xFF; //64bits
-  if ($initial_value < 0) $int4 = chr($int4) | chr(0x80);
-  else $int4 = chr($int4);
-  $value = $int4 . chr($int3) . chr($int2) . chr($int1);
-  return $value;
- }
-
- protected function _rangeOfIntegerBuild($integers) 
- {
-  #$integers = split(":", $integers);
-  $integers = preg_split("#:#", $integers);
-  for ($i = 0; $i < 2; $i++) $outvalue[$i] = self::_integerBuild($integers[$i]);
-  return $outvalue[0] . $outvalue[1];
- }
-
- protected function _setJobAttribute($attribute, $value) 
- {
-  //used by setAttribute
-  $tag_type = $this->job_tags[$attribute]['tag'];
-  switch ($tag_type) 
-  {
-   case 'integer':
-    $this->job_tags[$attribute]['value'][] = self::_integerBuild($value);
-    break;
-
-   case 'nameWithoutLanguage':
-   case 'nameWithLanguage':
-   case 'textWithoutLanguage':
-   case 'textWithLanguage':
-   case 'keyword':
-   case 'naturalLanguage':
-    $this->job_tags[$attribute]['value'][] = $value;
-    break;
-
-   case 'enum':
-    $value = $this->_enumBuild($attribute, $value); // may be overwritten by children
-    $this->job_tags[$attribute]['value'][] = $value;
-    break;
-
-   case 'rangeOfInteger':
-    // $value have to be: INT1:INT2 , eg 100:1000
-    $this->job_tags[$attribute]['value'][] = self::_rangeOfIntegerBuild($value);
-    break;
-
-   case 'resolution':
-    if (preg_match("#dpi#", $value)) $unit = chr(0x3);
-    if (preg_match("#dpc#", $value)) $unit = chr(0x4);
-    $search = array(
-      "#(dpi|dpc)#",
-      '#(x|-)#'
+
+    //
+    // REQUEST BUILDING
+    //
+    protected function _stringJob() 
+    {
+        if (!isset($this->setup->charset)) {
+            self::setCharset();
+        }
+        if (!isset($this->setup->datatype)) {
+            self::setBinary();
+        }
+        if (!isset($this->setup->uri)) 
+        {
+            $this->getPrinters();
+            unset($this->jobs[count($this->jobs) - 1]);
+            unset($this->jobs_uri[count($this->jobs_uri) - 1]);
+            unset($this->status[count($this->status) - 1]);
+            if (array_key_exists(0, $this->available_printers))
+            {
+                self::setPrinterURI($this->available_printers[0]);
+            }
+            else 
+            {
+                trigger_error(
+                    _("_stringJob: Printer URI is not set: die"),
+                    E_USER_WARNING);
+                self::_putDebug(_("_stringJob: Printer URI is not set: die") , 4);
+                self::_errorLog(" Printer URI is not set, die", 2);
+                return FALSE;
+            }
+        }
+        if (!isset($this->setup->copies)) {
+            self::setCopies(1);
+        }
+        if (!isset($this->setup->language)) {
+            self::setLanguage('en_us');
+        }
+        if (!isset($this->setup->mime_media_type)) {
+            self::setMimeMediaType();
+        }
+        if (!isset($this->setup->jobname)) {
+            self::setJobName();
+        }
+        unset($this->setup->jobname);
+        if (!isset($this->meta->username)) {
+            self::setUserName();
+        }
+        if (!isset($this->meta->fidelity)) {
+            $this->meta->fidelity = '';
+        }
+        if (!isset($this->meta->document_name)) {
+            $this->meta->document_name = '';
+        }
+        if (!isset($this->meta->sides)) {
+            $this->meta->sides = '';
+        }
+        if (!isset($this->meta->page_ranges)) {
+            $this->meta->page_ranges = '';
+        }
+        $jobattributes = '';
+        $operationattributes = '';
+        $printerattributes = '';
+        $this->_buildValues($operationattributes, $jobattributes, $printerattributes);
+        self::_setOperationId();
+        if (!isset($this->error_generation->request_body_malformed))
+        {
+            $this->error_generation->request_body_malformed = "";
+        }
+        $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
+            . chr(0x00) . chr(0x02) // Print-Job | operation-id
+            . $this->meta->operation_id //           request-id
+            . chr(0x01) // start operation-attributes | operation-attributes-tag
+            . $this->meta->charset
+            . $this->meta->language
+            . $this->meta->printer_uri
+            . $this->meta->username
+            . $this->meta->jobname
+            . $this->meta->fidelity
+            . $this->meta->document_name
+            . $this->meta->mime_media_type
+            . $operationattributes;
+        if ($this->meta->copies || $this->meta->sides || $this->meta->page_ranges || !empty($jobattributes)) 
+        {
+            $this->stringjob .=
+                chr(0x02) // start job-attributes | job-attributes-tag
+                    . $this->meta->copies
+                    . $this->meta->sides
+                    . $this->meta->page_ranges
+                    . $jobattributes;
+        }
+        $this->stringjob.= chr(0x03); // end-of-attributes | end-of-attributes-tag
+        self::_putDebug(
+            sprintf(_("String sent to the server is: %s"),
+                $this->stringjob)
             );
-    $replace = array(
-      "",
-      ":"
-      );
-    $value = self::_rangeOfIntegerBuild(preg_replace($search, $replace, $value)) . $unit;
-    $this->job_tags[$attribute]['value'][] = $value;
-    break;
-
-   default:
-    trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE);
-    self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
-    self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
-    return FALSE;
-    break;
-  }
-  $this->job_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag'];
- }
-
- protected function _setOperationAttribute($attribute, $value) 
- {
-  //used by setAttribute
-  $tag_type = $this->operation_tags[$attribute]['tag'];
-  switch ($tag_type) 
-  {
-   case 'integer':
-    $this->operation_tags[$attribute]['value'][] = self::_integerBuild($value);
-    break;
-
-   case 'keyword':
-   case 'naturalLanguage':
-    $this->operation_tags[$attribute]['value'][] = $value;
-    break;
-
-   default:
-    trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE);
-    self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
-    self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
-    return FALSE;
-    break;
-  }
-  $this->operation_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag'];
- }
-
- protected function _setPrinterAttribute($attribute, $value) 
- {
-  //used by setAttribute
-  $tag_type = $this->printer_tags[$attribute]['tag'];
-  switch ($tag_type) 
-  {
-   case 'integer':
-    $this->printer_tags[$attribute]['value'][] = self::_integerBuild($value);
-    break;
-
-   case 'keyword':
-   case 'naturalLanguage':
-    $this->printer_tags[$attribute]['value'][] = $value;
-    break;
-
-   default:
-    trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE);
-    self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
-    self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
-    return FALSE;
-    break;
-  }
-  $this->printer_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag'];
- }
-
- //
- // DEBUGGING
- //
- protected function _putDebug($string, $level = 1) 
- {
-  if ($level === false) return;
-  if ($level < $this->debug_level) return;
-  $this->debug[$this->debug_count] = substr($string, 0, 1024);
-  $this->debug_count++;
-  //$this->debug .= substr($string,0,1024);
-
- }
-
- //
- // LOGGING
- //
- protected function _errorLog($string_to_log, $level) 
- {
-  if ($level < $this->log_level) return;
-  $string = sprintf('%s : %s:%s user %s : %s', basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log);
-  if ($this->log_type == 0) 
-  {
-   error_log($string);
-   return;
-  }
-  $string = sprintf("%s %s Host %s:%s user %s : %s\n", date('M d H:i:s') , basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log);
-  error_log($string, $this->log_type, $this->log_destination);
-  return;
- }
-
-};
-/*
- * Local variables:
- * mode: php
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- */
-?>
+        return TRUE;
+    }
+
+    protected function _buildValues(&$operationattributes, &$jobattributes, &$printerattributes) 
+    {
+        $operationattributes = '';
+        foreach($this->operation_tags as $key => $values) 
+        {
+            $item = 0;
+            if (array_key_exists('value', $values))
+            {
+                foreach($values['value'] as $item_value) 
+                {
+                    if ($item == 0)
+                    {
+                        $operationattributes .=
+                            $values['systag'] 
+                                . self::_giveMeStringLength($key) 
+                                . $key 
+                                . self::_giveMeStringLength($item_value) 
+                                . $item_value;
+                    }
+                    else
+                    {
+                        $operationattributes .= 
+                            $values['systag'] 
+                                . self::_giveMeStringLength('') 
+                                . self::_giveMeStringLength($item_value) 
+                                . $item_value;
+                    }
+                    $item++;
+                }
+            }
+        }
+        $jobattributes = '';
+        foreach($this->job_tags as $key => $values) 
+        {
+            $item = 0;
+            if (array_key_exists('value', $values)) 
+            {
+                foreach($values['value'] as $item_value) 
+                {
+                    if ($item == 0)
+                    { 
+                        $jobattributes .=
+                            $values['systag'] 
+                                . self::_giveMeStringLength($key)
+                                . $key
+                                . self::_giveMeStringLength($item_value)
+                                . $item_value;
+                    }
+                    else
+                    {
+                        $jobattributes .=
+                            $values['systag']
+                                . self::_giveMeStringLength('')
+                                . self::_giveMeStringLength($item_value)
+                                . $item_value;
+                    }
+                    $item++;
+                }
+            }
+        }
+        $printerattributes = '';
+        foreach($this->printer_tags as $key => $values) 
+        {
+            $item = 0;
+            if (array_key_exists('value', $values))
+            {
+                foreach($values['value'] as $item_value) 
+                {
+                    if ($item == 0)
+                    {
+                        $printerattributes .=
+                            $values['systag']
+                                . self::_giveMeStringLength($key)
+                                . $key
+                                . self::_giveMeStringLength($item_value)
+                                . $item_value;
+                    }
+                    else
+                    {
+                        $printerattributes .=
+                            $values['systag']
+                                . self::_giveMeStringLength('')
+                                . self::_giveMeStringLength($item_value)
+                                . $item_value;
+                    }
+                    $item++;
+                }
+            }
+        }
+        reset($this->job_tags);
+        reset($this->operation_tags);
+        reset($this->printer_tags);
+        return true;
+    }
+
+    protected function _giveMeStringLength($string) 
+    {
+        $length = strlen($string);
+        if ($length > ((0xFF << 8) + 0xFF)  )
+        {
+            $errmsg = sprintf (
+                _('max string length for an ipp meta-information = %d, while here %d'),
+                ((0xFF << 8) + 0xFF), $length);
+
+            if ($this->with_exceptions)
+            {
+                throw new ippException($errmsg);
+            }
+            else
+            {
+                trigger_error ($errmsg, E_USER_ERROR);
+            }
+        }
+        $int1 = $length & 0xFF;
+        $length -= $int1;
+        $length = $length >> 8;
+        $int2 = $length & 0xFF;
+        return chr($int2) . chr($int1);
+    }
+
+    protected function _enumBuild($tag, $value) 
+    {
+        switch ($tag) 
+        {
+            case "orientation-requested":
+                switch ($value) 
+                {
+                    case 'portrait':
+                        $value = chr(3);
+                        break;
+
+                    case 'landscape':
+                        $value = chr(4);
+                        break;
+
+                    case 'reverse-landscape':
+                        $value = chr(5);
+                        break;
+
+                    case 'reverse-portrait':
+                        $value = chr(6);
+                        break;
+                }
+                break;
+
+            case "print-quality":
+                switch ($value) 
+                {
+                    case 'draft':
+                        $value = chr(3);
+                        break;
+
+                    case 'normal':
+                        $value = chr(4);
+                        break;
+
+                    case 'high':
+                        $value = chr(5);
+                        break;
+                }
+                break;
+
+            case "finishing":
+                switch ($value) 
+                {
+                    case 'none':
+                        $value = chr(3);
+                        break;
+
+                    case 'staple':
+                        $value = chr(4);
+                        break;
+
+                    case 'punch':
+                        $value = chr(5);
+                        break;
+
+                    case 'cover':
+                        $value = chr(6);
+                        break;
+
+                    case 'bind':
+                        $value = chr(7);
+                        break;
+
+                    case 'saddle-stitch':
+                        $value = chr(8);
+                        break;
+
+                    case 'edge-stitch':
+                        $value = chr(9);
+                        break;
+
+                    case 'staple-top-left':
+                        $value = chr(20);
+                        break;
+
+                    case 'staple-bottom-left':
+                        $value = chr(21);
+                        break;
+
+                    case 'staple-top-right':
+                        $value = chr(22);
+                        break;
+
+                    case 'staple-bottom-right':
+                        $value = chr(23);
+                        break;
+
+                    case 'edge-stitch-left':
+                        $value = chr(24);
+                        break;
+
+                    case 'edge-stitch-top':
+                        $value = chr(25);
+                        break;
+
+                    case 'edge-stitch-right':
+                        $value = chr(26);
+                        break;
+
+                    case 'edge-stitch-bottom':
+                        $value = chr(27);
+                        break;
+
+                    case 'staple-dual-left':
+                        $value = chr(28);
+                        break;
+
+                    case 'staple-dual-top':
+                        $value = chr(29);
+                        break;
+
+                    case 'staple-dual-right':
+                        $value = chr(30);
+                        break;
+
+                    case 'staple-dual-bottom':
+                        $value = chr(31);
+                        break;
+                }
+                break;
+        }
+        $prepend = '';
+        while ((strlen($value) + strlen($prepend)) < 4)
+        {
+            $prepend .= chr(0);
+        }
+        return $prepend . $value;
+    }
+
+    protected function _integerBuild($value) 
+    {
+        if ($value >= 2147483647 || $value < - 2147483648) 
+        {
+            trigger_error(
+                _("Values must be between -2147483648 and 2147483647: assuming '0'") , E_USER_WARNING);
+            return chr(0x00) . chr(0x00) . chr(0x00) . chr(0x00);
+        }
+        $initial_value = $value;
+        $int1 = $value & 0xFF;
+        $value -= $int1;
+        $value = $value >> 8;
+        $int2 = $value & 0xFF;
+        $value-= $int2;
+        $value = $value >> 8;
+        $int3 = $value & 0xFF;
+        $value-= $int3;
+        $value = $value >> 8;
+        $int4 = $value & 0xFF; //64bits
+        if ($initial_value < 0) {
+            $int4 = chr($int4) | chr(0x80);
+        }
+        else {
+            $int4 = chr($int4);
+        }
+        $value = $int4 . chr($int3) . chr($int2) . chr($int1);
+        return $value;
+    }
+
+    protected function _rangeOfIntegerBuild($integers) 
+    {
+        #$integers = split(":", $integers);
+        $integers = preg_split("#:#", $integers);
+        for ($i = 0; $i < 2; $i++) {
+            $outvalue[$i] = self::_integerBuild($integers[$i]);
+        }
+        return $outvalue[0] . $outvalue[1];
+    }
+
+    protected function _setJobAttribute($attribute, $value) 
+    {
+        //used by setAttribute
+        $tag_type = $this->job_tags[$attribute]['tag'];
+        switch ($tag_type) 
+        {
+            case 'integer':
+                $this->job_tags[$attribute]['value'][] = self::_integerBuild($value);
+                break;
+
+            case 'boolean':
+            case 'nameWithoutLanguage':
+            case 'nameWithLanguage':
+            case 'textWithoutLanguage':
+            case 'textWithLanguage':
+            case 'keyword':
+            case 'naturalLanguage':
+                $this->job_tags[$attribute]['value'][] = $value;
+                break;
+
+            case 'enum':
+                $value = $this->_enumBuild($attribute, $value); // may be overwritten by children
+                $this->job_tags[$attribute]['value'][] = $value;
+                break;
+
+            case 'rangeOfInteger':
+                // $value have to be: INT1:INT2 , eg 100:1000
+                $this->job_tags[$attribute]['value'][] = self::_rangeOfIntegerBuild($value);
+                break;
+
+            case 'resolution':
+                if (preg_match("#dpi#", $value)) {
+                    $unit = chr(0x3);
+                }
+                if (preg_match("#dpc#", $value)) {
+                    $unit = chr(0x4);
+                }
+                $search = array(
+                    "#(dpi|dpc)#",
+                    '#(x|-)#'
+                );
+                $replace = array(
+                    "",
+                    ":"
+                );
+                $value = self::_rangeOfIntegerBuild(preg_replace($search, $replace, $value)) . $unit;
+                $this->job_tags[$attribute]['value'][] = $value;
+                break;
+
+            default:
+                trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE);
+                self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
+                self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
+                return FALSE;
+                break;
+        }
+        $this->job_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag'];
+    }
+
+    protected function _setOperationAttribute($attribute, $value) 
+    {
+        //used by setAttribute
+        $tag_type = $this->operation_tags[$attribute]['tag'];
+        switch ($tag_type) 
+        {
+            case 'integer':
+                $this->operation_tags[$attribute]['value'][] = self::_integerBuild($value);
+                break;
+
+            case 'keyword':
+            case 'naturalLanguage':
+                $this->operation_tags[$attribute]['value'][] = $value;
+                break;
+
+            default:
+                trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE);
+                self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
+                self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
+                return FALSE;
+                break;
+        }
+        $this->operation_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag'];
+    }
+
+    protected function _setPrinterAttribute($attribute, $value) 
+    {
+        //used by setAttribute
+        $tag_type = $this->printer_tags[$attribute]['tag'];
+        switch ($tag_type) 
+        {
+            case 'integer':
+                $this->printer_tags[$attribute]['value'][] = self::_integerBuild($value);
+                break;
+
+            case 'keyword':
+            case 'naturalLanguage':
+                $this->printer_tags[$attribute]['value'][] = $value;
+                break;
+
+            default:
+                trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , E_USER_NOTICE);
+                self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
+                self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute') , $attribute) , 2);
+                return FALSE;
+                break;
+        }
+        $this->printer_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag'];
+    }
+
+    //
+    // DEBUGGING
+    //
+    protected function _putDebug($string, $level = 1) 
+    {
+        if ($level === false) {
+            return;
+        }
+
+        if ($level < $this->debug_level) {
+            return;
+        }
+
+        $this->debug[$this->debug_count] = substr($string, 0, 1024);
+        $this->debug_count++;
+        //$this->debug .= substr($string,0,1024);
+
+    }
+
+    //
+    // LOGGING
+    //
+    protected function _errorLog($string_to_log, $level) 
+    {
+        if ($level > $this->log_level) {
+            return;
+        }
+
+        $string = sprintf('%s : %s:%s user %s : %s', basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log);
+
+        if ($this->log_type == 0) 
+        {
+            error_log($string);
+            return;
+        }
+
+        $string = sprintf("%s %s Host %s:%s user %s : %s\n", date('M d H:i:s') , basename($_SERVER['PHP_SELF']) , $this->host, $this->port, $this->requesting_user, $string_to_log);
+        error_log($string, $this->log_type, $this->log_destination);
+        return;
+    }
+}
diff --git a/htdocs/includes/printipp/CupsPrintIPP.php b/htdocs/includes/printipp/CupsPrintIPP.php
index a7e5a305da55d72fe3d4f4e1019a6db6649ed35a..7808c64a7221088d0b8ee6fb5ab375f622f98399 100644
--- a/htdocs/includes/printipp/CupsPrintIPP.php
+++ b/htdocs/includes/printipp/CupsPrintIPP.php
@@ -1,5 +1,5 @@
 <?php
-/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+
 /* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/CupsPrintIPP.php,v 1.1 2008/06/21 00:30:56 harding Exp $
  *
  * Class PrintIPP - Send extended IPP requests.
@@ -22,11 +22,10 @@
  *
  *   mailto:thomas.harding@laposte.net
  *   Thomas Harding, 56 rue de la bourie rouge, 45 000 ORLEANS -- FRANCE
- *   
+ *
  */
-    
-/*
 
+/*
     This class is intended to implement Internet Printing Protocol on client side.
 
     References needed to debug / add functionnalities:
@@ -39,57 +38,64 @@
 
 require_once("ExtendedPrintIPP.php");
 
-class CupsPrintIPP extends ExtendedPrintIPP {
-
-    // {{{ variables declaration
-    
+class CupsPrintIPP extends ExtendedPrintIPP
+{
     public $printers_attributes;
     public $defaults_attributes;
-    
-    // }}}
 
-    // {{{ constructor
-    public function __construct() {
+    protected $parsed;
+    protected $output;
+
+    public function __construct()
+    {
         parent::__construct();
         self::_initTags();
     }
-    // }}}
 
 //
 // OPERATIONS
 //
+    public function cupsGetDefaults($attributes=array("all"))
+    {
+        //The CUPS-Get-Default operation returns the default printer URI and attributes
 
-    // {{{ cupsGetDefaults ($attributes="all")
-    public function cupsGetDefaults($attributes=array("all")) {
-    //The CUPS-Get-Default operation returns the default printer URI and attributes
-     
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
         $this->parsed = array();
         unset($this->printer_attributes);
-        
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-        
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en');
-            
+        }
+
         self::_setOperationId();
-        
+
         for($i = 0 ; $i < count($attributes) ; $i++)
+        {
             if ($i == 0)
+            {
                 $this->meta->attributes = chr(0x44) // Keyword
                                         . self::_giveMeStringLength('requested-attributes')
                                         . 'requested-attributes'
                                         . self::_giveMeStringLength($attributes[0])
                                         . $attributes[0];
+            }
             else
+            {
                 $this->meta->attributes .= chr(0x44) // Keyword
                                         .  chr(0x0).chr(0x0) // zero-length name
                                         .  self::_giveMeStringLength($attributes[$i])
                                         .  $attributes[$i];
-                                        
-        $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 
+            }
+        }
+
+        $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1
                          . chr(0x40). chr(0x01) // operation:  cups vendor extension: get defaults
                          . $this->meta->operation_id // request-id
                          . chr(0x01) // start operation-attributes | operation-attributes-tag
@@ -97,69 +103,83 @@ class CupsPrintIPP extends ExtendedPrintIPP {
                          . $this->meta->language
                          . $this->meta->attributes
                          . chr(0x03); // end operations attribute
-                        
+
         $this->output = $this->stringjob;
-        
+
         self::_putDebug("Request: ".$this->output);
-        
+
         $post_values = array( "Content-Type" => "application/ipp",
                               "Data" => $this->output);
-            
-        if (self::_sendHttp ($post_values,'/')) {
-            
+
+        if (self::_sendHttp ($post_values,'/'))
+        {
+
             if(self::_parseServerOutput())
+            {
                 self::_parsePrinterAttributes();
             }
-        
+        }
+
        $this->attributes = &$this->printer_attributes;
-        
-       if (isset($this->printer_attributes->printer_type)) {
+
+       if (isset($this->printer_attributes->printer_type))
+       {
                     $printer_type = $this->printer_attributes->printer_type->_value0;
                     $table = self::_interpretPrinterType($printer_type);
-        
-                    for($i = 0 ; $i < count($table) ; $i++ ) {
+
+                    for($i = 0 ; $i < count($table) ; $i++ )
+                    {
                         $index = '_value'.$i;
                         $this->printer_attributes->printer_type->$index = $table[$i];
                         }
-
                     }
 
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
+
             $this->status = array_merge($this->status,array($this->serveroutput->status));
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog("getting defaults: ".$this->serveroutput->status,3);
+            }
             else
+            {
                 self::_errorLog("getting defaults: ".$this->serveroutput->status,1);
-            
-            return $this->serveroutput->status; 
-            
-        } else {
+            }
+
+            return $this->serveroutput->status;
+        }
+        else
+        {
             $this->status = array_merge($this->status,array("OPERATION FAILED"));
             self::_errorLog("getting defaults : OPERATION FAILED",1);
             }
-    return false;   
+    return false;
     }
-    // }}}
-    
-    // {{{ cupsAcceptJobs ($printer_uri)
-    public function cupsAcceptJobs($printer_uri) {
+
+
+    public function cupsAcceptJobs($printer_uri)
+    {
     //The CUPS-Get-Default operation returns the default printer URI and attributes
-     
+
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
         $this->parsed = array();
         unset($this->printer_attributes);
-        
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-        
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en');
-            
+        }
+
         self::_setOperationId();
-       
-       $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 
+
+        $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1
                          . chr(0x40). chr(0x08) // operation:  cups vendor extension: Accept-Jobs
                          . $this->meta->operation_id // request-id
                          . chr(0x01) // start operation-attributes | operation-attributes-tag
@@ -171,65 +191,80 @@ class CupsPrintIPP extends ExtendedPrintIPP {
                          . self::_giveMeStringLength($printer_uri)
                          . $printer_uri
                          . chr(0x03); // end operations attribute
-                        
+
         $this->output = $this->stringjob;
-        
+
         self::_putDebug("Request: ".$this->output);
-        
+
         $post_values = array( "Content-Type" => "application/ipp",
                               "Data" => $this->output);
-            
-        if (self::_sendHttp ($post_values,'/admin/')) {
-            
+
+        if (self::_sendHttp ($post_values,'/admin/'))
+        {
+
             if(self::_parseServerOutput())
+            {
                 self::_parseAttributes();
             }
-                
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        }
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
+
             $this->status = array_merge($this->status,array($this->serveroutput->status));
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog("getting defaults: ".$this->serveroutput->status,3);
+            }
             else
+            {
                 self::_errorLog("getting defaults: ".$this->serveroutput->status,1);
-            
-            return $this->serveroutput->status; 
-            
-        } else {
+            }
+
+            return $this->serveroutput->status;
+        }
+        else
+        {
             $this->status = array_merge($this->status,array("OPERATION FAILED"));
             self::_errorLog("getting defaults : OPERATION FAILED",1);
             }
-    return false;   
+    return false;
     }
-    // }}}
 
-    // {{{ cupsRejectJobs ($printer_uri,$printer_state_message=false)
-    public function cupsRejectJobs($printer_uri,$printer_state_message) {
+
+    public function cupsRejectJobs($printer_uri,$printer_state_message)
+    {
     //The CUPS-Get-Default operation returns the default printer URI and attributes
-     
+
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
         $this->parsed = array();
         unset($this->attributes);
-        
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-        
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en');
-            
+        }
+
         self::_setOperationId();
-        
+
         $message = "";
         if ($printer_state_message)
+        {
             $message = chr(0x04) // start printer-attributes
                      . chr(0x41) // textWithoutLanguage
                      . self::_giveMeStringLength("printer-state-message")
                      . "printer-state-message"
                      . self::_giveMeStringLength($printer_state_message)
                      . $printer_state_message;
+        }
 
-       $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 
+       $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1
                          . chr(0x40). chr(0x09) // operation:  cups vendor extension: Reject-Jobs
                          . $this->meta->operation_id // request-id
                          . chr(0x01) // start operation-attributes | operation-attributes-tag
@@ -242,89 +277,111 @@ class CupsPrintIPP extends ExtendedPrintIPP {
                          . $printer_uri
                          . $message
                          . chr(0x03); // end operations attribute
-                        
+
         $this->output = $this->stringjob;
-        
+
         self::_putDebug("Request: ".$this->output);
-        
+
         $post_values = array( "Content-Type" => "application/ipp",
                               "Data" => $this->output);
-            
-        if (self::_sendHttp ($post_values,'/admin/')) {
-            
+
+        if (self::_sendHttp ($post_values,'/admin/'))
+        {
+
             if(self::_parseServerOutput())
+            {
                 self::_parseAttributes();
             }
-                
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        }
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
+
             $this->status = array_merge($this->status,array($this->serveroutput->status));
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog("getting defaults: ".$this->serveroutput->status,3);
+            }
             else
+            {
                 self::_errorLog("getting defaults: ".$this->serveroutput->status,1);
-            
-            return $this->serveroutput->status; 
-            
-        } else {
+            }
+
+            return $this->serveroutput->status;
+        }
+        else
+        {
             $this->status = array_merge($this->status,array("OPERATION FAILED"));
             self::_errorLog("getting defaults : OPERATION FAILED",1);
-            }
-    return false;   
+        }
+        return false;
     }
-    // }}}
 
-    // {{{ getPrinters()
-    public function getPrinters($printer_location=false,$printer_info=false,$attributes=array()) {
-        
+
+    public function getPrinters($printer_location=false,$printer_info=false,$attributes=array())
+    {
         if (count($attributes) == 0)
-        true;
-            $attributes=array('printer-uri-supported','printer-location','printer-info','printer-type','color-supported');
+        {
+            true;
+        }
+        $attributes=array('printer-uri-supported', 'printer-location', 'printer-info', 'printer-type', 'color-supported', 'printer-name');
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
-        
+
         unset ($this->printers_attributes);
-        
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-        
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en-us');
-            
+        }
+
         self::_setOperationId();
-        
+
         $this->meta->attributes='';
-        
+
         if ($printer_location)
+        {
             $this->meta->attributes .= chr(0x41) // textWithoutLanguage
                                     . self::_giveMeStringLength('printer-location')
                                     . 'printer-location'
                                     . self::_giveMeStringLength($printer_location)
                                     . $printer_location;
-        
-        
+        }
+
         if ($printer_info)
+        {
             $this->meta->attributes .= chr(0x41) // textWithoutLanguage
                                     . self::_giveMeStringLength('printer-info')
                                     . 'printer-info'
                                     . self::_giveMeStringLength($printer_info)
                                     . $printer_info;
-        
+        }
+
         for($i = 0 ; $i < count($attributes) ; $i++)
+        {
             if ($i == 0)
+            {
                 $this->meta->attributes .= chr(0x44) // Keyword
                                         . self::_giveMeStringLength('requested-attributes')
                                         . 'requested-attributes'
                                         . self::_giveMeStringLength($attributes[0])
                                         . $attributes[0];
+            }
             else
+            {
                 $this->meta->attributes .= chr(0x44) // Keyword
                                         .  chr(0x0).chr(0x0) // zero-length name
                                         .  self::_giveMeStringLength($attributes[$i])
                                         .  $attributes[$i];
+            }
+        }
 
-        
-        $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 
+        $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1
                          . chr(0x40). chr(0x02) // operation:  cups vendor extension: get printers
                          . $this->meta->operation_id //           request-id
                          . chr(0x01) // start operation-attributes | operation-attributes-tag
@@ -332,78 +389,89 @@ class CupsPrintIPP extends ExtendedPrintIPP {
                          . $this->meta->language
                          . $this->meta->attributes
                          . chr(0x03); // end operations attribute
-                        
+
         $this->output = $this->stringjob;
-           
+
         $post_values = array( "Content-Type" => "application/ipp",
                               "Data" => $this->output);
-            
-        if (self::_sendHttp ($post_values,'/')) {
-            
+
+        if (self::_sendHttp ($post_values,'/'))
+        {
+
             if(self::_parseServerOutput())
+            {
                 $this->_getAvailablePrinters();
-
             }
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        }
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
+
             $this->status = array_merge($this->status,array($this->serveroutput->status));
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog("getting printers: ".$this->serveroutput->status,3);
+            }
             else
+            {
                 self::_errorLog("getting printers: ".$this->serveroutput->status,1);
-            return $this->serveroutput->status; 
-            
-        } else {
+            }
+            return $this->serveroutput->status;
+        }
+        else
+        {
             $this->status = array_merge($this->status,array("OPERATION FAILED"));
             self::_errorLog("getting printers : OPERATION FAILED",1);
-            }
-    return false;   
+        }
+        return false;
     }
-    // }}}
 
-    // {{{ cupsGetPrinters ()
-    public function cupsGetPrinters () {
-    // alias for getPrinters();
+
+    public function cupsGetPrinters ()
+    {
+        // alias for getPrinters();
         self::getPrinters();
     }
-    // }}}
 
-    // {{{ getPrinterAttributes()
-    public function getPrinterAttributes() {
-    // complete informations from parent with Cups-specific stuff
-    
+
+    public function getPrinterAttributes()
+    {
+        // complete informations from parent with Cups-specific stuff
+
         if(!$result = parent::getPrinterAttributes())
+        {
             return FALSE;
+        }
         if(!isset($this->printer_attributes))
+        {
             return FALSE;
-        
-        if (isset ($this->printer_attributes->printer_type)) {
+        }
+
+        if (isset ($this->printer_attributes->printer_type))
+        {
             $printer_type = $this->printer_attributes->printer_type->_value0;
             $table = self::_interpretPrinterType($printer_type);
-        
-            for($i = 0 ; $i < count($table) ; $i++ ) {
+
+            for($i = 0 ; $i < count($table) ; $i++ )
+            {
                 $index = '_value'.$i;
                 $this->printer_attributes->printer_type->$index = $table[$i];
-                }
             }
+        }
 
-    return $result;
+        return $result;
     }
-    // }}}
 
 //
 // SETUP
 //
-
-    // {{{ _initTags ()
-    protected function _initTags () {
-        
+    protected function _initTags ()
+    {
         // override parent with specific cups attributes
-        
-        $operation_tags = array (); 
+
+        $operation_tags = array ();
         $this->operation_tags = array_merge ($this->operation_tags, $operation_tags);
-               
+
         $job_tags = array ( "job-billing" => array("tag" => "textWithoutLanguage"),
                             "blackplot" => array("tag" => "boolean"),
                             "brightness" => array("tag" => "integer"),
@@ -430,25 +498,23 @@ class CupsPrintIPP extends ExtendedPrintIPP {
                             "saturation" => array("tag" => "integer"),
                             "scaling" => array("tag" => "integer"),
                             "wrap" => array("tag","boolean"),
-                            
+
                             );
         $this->job_tags = array_merge ($this->job_tags, $job_tags);
     }
-    // }}}
 
-//
-// REQUEST BUILDING
-//
-
-    // {{{ _enumBuild ($tag,$value)
-    protected function _enumBuild ($tag,$value) {
-        
+    //
+    // REQUEST BUILDING
+    //
+    protected function _enumBuild ($tag,$value)
+    {
         $value_built = parent::_enumBuild($tag,$value);
-       
 
-        switch ($tag) {
-           case "cpi":     
-                switch ($value) {
+        switch ($tag)
+        {
+           case "cpi":
+                switch ($value)
+                {
                     case '10':
                         $value_built = chr(10);
                         break;
@@ -463,7 +529,8 @@ class CupsPrintIPP extends ExtendedPrintIPP {
                 }
             break;
             case "lpi":
-                switch ($value) {
+                switch ($value)
+                {
                     case '6':
                         $value_built = chr(6);
                         break;
@@ -479,60 +546,66 @@ class CupsPrintIPP extends ExtendedPrintIPP {
         $prepend = '';
         while ((strlen($value_built) + strlen($prepend)) < 4)
             $prepend .= chr(0);
-    return $prepend.$value_built;
+        return $prepend.$value_built;
     }
-    // }}}
-    
-//
-// RESPONSE PARSING
-//
 
-    // {{{ _getAvailablePrinters ()
-    private function _getAvailablePrinters () {
-      
+    //
+    // RESPONSE PARSING
+    //
+    private function _getAvailablePrinters ()
+    {
         $this->available_printers = array();
+        $this->printer_map = array();
         $k = 0;
-        $this->printers_attributes = new stdClass();
+        $this->printers_attributes = new \stdClass();
 
         for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++)
-            if (($this->serveroutput->response[$i]['attributes']) == "printer-attributes") {
+        {
+            if (($this->serveroutput->response[$i]['attributes']) == "printer-attributes")
+            {
                 $phpname = "_printer".$k;
-                $this->printers_attributes->$phpname = new stdClass();
-                for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) {
-                
+                $this->printers_attributes->$phpname = new \stdClass();
+                for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++)
+                {
+
                     $value = $this->serveroutput->response[$i][$j]['value'];
                     $name = str_replace("-","_",$this->serveroutput->response[$i][$j]['name']);
-                    
-                    switch ($name) {
+
+                    switch ($name)
+                    {
                         case "printer_uri_supported":
                             $this->available_printers = array_merge($this->available_printers,array($value));
                             break;
                         case "printer_type":
                             $table = self::_interpretPrinterType($value);
-                            $this->printers_attributes->$phpname->$name = new stdClass();
-        
-                            for($l = 0 ; $l < count($table) ; $l++ ) {
+                            $this->printers_attributes->$phpname->$name = new \stdClass();
+
+                            for($l = 0 ; $l < count($table) ; $l++ )
+                            {
                                 $index = '_value'.$l;
                                 $this->printers_attributes->$phpname->$name->$index = $table[$l];
                             }
-                            
+
                             break;
                         case '':
                             break;
+                        case 'printer_name':
+                            $this->printer_map[$value] = $k;
+                            break;
                         default:
                             $this->printers_attributes->$phpname->$name = $value;
                             break;
-                        }
-
-                    }    
-                $k ++;
+                    }
                 }
+                $k ++;
+            }
+        }
     }
-    // }}}
-    
-    // {{{ _getEnumVendorExtensions
-    protected function _getEnumVendorExtensions ($value_parsed) {
-        switch ($value_parsed) {
+
+    protected function _getEnumVendorExtensions ($value_parsed)
+    {
+        switch ($value_parsed)
+        {
             case 0x4002:
                 $value = 'Get-Availables-Printers';
                 break;
@@ -541,110 +614,152 @@ class CupsPrintIPP extends ExtendedPrintIPP {
                 break;
         }
 
-    if (isset($value))
-        return ($value);
-  
-    return sprintf('Unknown: 0x%x',$value_parsed);
+        if (isset($value))
+        {
+            return ($value);
+        }
+
+        return sprintf('Unknown: 0x%x',$value_parsed);
     }
-    // }}}
 
-    // {{{ _interpretPrinterType($type)
-    private function _interpretPrinterType($value) {
+
+    private function _interpretPrinterType($value)
+    {
         $value_parsed = 0;
         for ($i = strlen($value) ; $i > 0 ; $i --)
+        {
             $value_parsed += pow(256,($i - 1)) * ord($value[strlen($value) - $i]);
-       
+        }
+
         $type[0] = $type[1] = $type[2] = $type[3] = $type[4] = $type[5] = '';
         $type[6] = $type[7] = $type[8] = $type[9] = $type[10] = '';
         $type[11] = $type[12] = $type[13] = $type[14] = $type[15] = '';
         $type[16] = $type[17] = $type[18] = $type[19] = '';
-        
-        if ($value_parsed %2 == 1) {
+
+        if ($value_parsed %2 == 1)
+        {
             $type[0] = 'printer-class';
             $value_parsed -= 1;
-            }
-        if ($value_parsed %4 == 2 )  {
+        }
+
+        if ($value_parsed %4 == 2 )
+        {
             $type[1] = 'remote-destination';
             $value_parsed -= 2;
-            }
-        if ($value_parsed %8 == 4 )  {
+        }
+
+        if ($value_parsed %8 == 4 )
+        {
             $type[2] = 'print-black';
             $value_parsed -= 4;
-            }
-        if ($value_parsed %16 == 8 )  {
+        }
+
+        if ($value_parsed %16 == 8 )
+        {
             $type[3] = 'print-color';
             $value_parsed -= 8;
-            }
-        if ($value_parsed %32 == 16) {
+        }
+
+        if ($value_parsed %32 == 16)
+        {
             $type[4] = 'hardware-print-on-both-sides';
             $value_parsed -= 16;
-            }
-        if ($value_parsed %64 == 32) {
+        }
+
+        if ($value_parsed %64 == 32)
+        {
             $type[5] = 'hardware-staple-output';
             $value_parsed -= 32;
-            }
-        if ($value_parsed %128 == 64) {
+        }
+
+        if ($value_parsed %128 == 64)
+        {
             $type[6] = 'hardware-fast-copies';
             $value_parsed -= 64;
-            }
-        if ($value_parsed %256 == 128) {
+        }
+
+        if ($value_parsed %256 == 128)
+        {
             $type[7] = 'hardware-fast-copy-collation';
             $value_parsed -= 128;
-            }
-        if ($value_parsed %512 == 256) {
+        }
+
+        if ($value_parsed %512 == 256)
+        {
             $type[8] = 'punch-output';
             $value_parsed -= 256;
-            }
-        if ($value_parsed %1024 == 512) {
+        }
+
+        if ($value_parsed %1024 == 512)
+        {
             $type[9] = 'cover-output';
             $value_parsed -= 512;
-            }
-        if ($value_parsed %2048 == 1024) {
+        }
+
+        if ($value_parsed %2048 == 1024)
+        {
             $type[10] = 'bind-output';
             $value_parsed -= 1024;
-            }
-        if ($value_parsed %4096 == 2048) {
+        }
+
+        if ($value_parsed %4096 == 2048)
+        {
             $type[11] = 'sort-output';
             $value_parsed -= 2048;
-            }
-        if ($value_parsed %8192 == 4096) {
+        }
+
+        if ($value_parsed %8192 == 4096)
+        {
             $type[12] = 'handle-media-up-to-US-Legal-A4';
             $value_parsed -= 4096;
-            }
-        if ($value_parsed %16384 == 8192) {
+        }
+
+        if ($value_parsed %16384 == 8192)
+        {
             $type[13] = 'handle-media-between-US-Legal-A4-and-ISO_C-A2';
             $value_parsed -= 8192;
-            }
-        if ($value_parsed %32768 == 16384) {
+        }
+
+        if ($value_parsed %32768 == 16384)
+        {
             $type[14] = 'handle-media-larger-than-ISO_C-A2';
             $value_parsed -= 16384;
-            }
-        if ($value_parsed %65536 == 32768) {
+        }
+
+        if ($value_parsed %65536 == 32768)
+        {
             $type[15] = 'handle-user-defined-media-sizes';
             $value_parsed -= 32768;
-            }
-        if ($value_parsed %131072 == 65536) {
+        }
+
+        if ($value_parsed %131072 == 65536)
+        {
             $type[16] = 'implicit-server-generated-class';
             $value_parsed -= 65536;
-            }
-        if ($value_parsed %262144 == 131072) {
+        }
+
+        if ($value_parsed %262144 == 131072)
+        {
             $type[17] = 'network-default-printer';
             $value_parsed -= 131072;
-            }
-        if ($value_parsed %524288 == 262144) {
+        }
+
+        if ($value_parsed %524288 == 262144)
+        {
             $type[18] = 'fax-device';
             $value_parsed -= 262144;
-            }
-    return $type;   
+        }
+
+        return $type;
     }
-    // }}}
 
-    // {{{ _interpretEnum()
-    protected function _interpretEnum($attribute_name,$value) {
-       
+
+    protected function _interpretEnum($attribute_name,$value)
+    {
         $value_parsed = self::_interpretInteger($value);
-        
-        switch ($attribute_name) {
+
+        switch ($attribute_name)
+        {
             case 'cpi':
             case 'lpi':
                 $value = $value_parsed;
@@ -652,20 +767,8 @@ class CupsPrintIPP extends ExtendedPrintIPP {
             default:
                 $value = parent::_interpretEnum($attribute_name,$value);
                 break;
-            }
-        
-    
-    return $value;
-    }
-    // }}}
-    
-};
+        }
 
-/*
- * Local variables:
- * mode: php
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- */
-?>
+        return $value;
+    }
+}
\ No newline at end of file
diff --git a/htdocs/includes/printipp/ExtendedPrintIPP.php b/htdocs/includes/printipp/ExtendedPrintIPP.php
index e736f4bd972ad47f15157518a265cd46dd8400d1..3effacb828fada4dd11db1791939bc4be5f9fe4c 100644
--- a/htdocs/includes/printipp/ExtendedPrintIPP.php
+++ b/htdocs/includes/printipp/ExtendedPrintIPP.php
@@ -1,5 +1,5 @@
 <?php
-/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+
 /* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/ExtendedPrintIPP.php,v 1.1 2008/06/21 00:30:57 harding Exp $
  *
  * Class PrintIPP - Send extended IPP requests.
@@ -43,113 +43,118 @@
 
 require_once("PrintIPP.php");
 
-class ExtendedPrintIPP extends PrintIPP {
-
-
-    // {{{ constructor
-    public function __construct() {
+class ExtendedPrintIPP extends PrintIPP
+{
+    public function __construct()
+    {
         parent::__construct();
     }
-    // }}}
-
-
-/******************
-*
-* PUBLIC FUNCTIONS
-*
-*******************/
-
 
-// OPERATIONS
 
-    // {{{ printURI ($uri)
-    public function printURI ($uri) {
+    // OPERATIONS
+    public function printURI ($uri)
+    {
 
         self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
 
-        if (!empty($uri)) {
+        if (!empty($uri))
+        {
             $this->document_uri = $uri;
             $this->setup->uri = 1;
         }
-        
+
         if(!$this->_stringUri())
+        {
             return FALSE;
-                       
+        }
+
         $this->output = $this->stringjob;
-           
+
         $post_values = array( "Content-Type" => "application/ipp",
                               "Data" => $this->output);
-            
-            
-        if (self::_sendHttp ($post_values,$this->paths['printers'])) {
-            
-            if(self::_parseServerOutput()) {
+
+        if (self::_sendHttp ($post_values,$this->paths['printers']))
+        {
+            if(self::_parseServerOutput())
+            {
                 $this->_parseJobAttributes();
                 $this->_getJobId();
                 //$this->_getPrinterUri();
                 $this->_getJobUri();
                 }
             }
-        
+
         $this->attributes = &$this->job_attributes;
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf("printing uri %s, job %s: ",$uri,$this->last_job)
                             .$this->serveroutput->status,3);
-            else {    
+            }
+            else
+            {
                 $this->jobs = array_merge($this->jobs,array(""));
                 $this->jobs_uri = array_merge($this->jobs_uri,array(""));
                 self::_errorLog(sprintf("printing uri %s: ",$uri,$this->last_job)
                             .$this->serveroutput->status,1);
-                }
-            return $this->serveroutput->status; 
             }
-            
+            return $this->serveroutput->status; 
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog("printing uri $uri : OPERATION FAILED",1);
-            
-    return false;
+
+        return false;
     }
-    // }}}
 
-    // {{{ purgeJobs()
-    public function purgeJobs() {
-        
+
+    public function purgeJobs()
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
 
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-        
-        if (!isset($this->setup->uri)) {
+
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("purgeJobs: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("purgeJobs: Printer URI is not set: die\n"));
                 self::_errorLog("purgeJobs: Printer URI is not set, die",2);
                 return FALSE;
                 }
             }
-            
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-       
+        }
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x12) // purge-Jobs | operation-id
                          . $this->meta->operation_id //           request-id
@@ -164,116 +169,141 @@ class ExtendedPrintIPP extends PrintIPP {
                          . self::_giveMeStringLength(chr(0x01))
                          . chr(0x01)
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("purging jobs of %s\n"),$this->printer_uri)); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
-        if (self::_sendHttp ($post_values,$this->paths['admin'])) {
+
+        if (self::_sendHttp ($post_values,$this->paths['admin']))
+        {
             self::_parseServerOutput();
             self::_parseAttributes();
             }
 
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("purging jobs of %s: "),$this->printer_uri)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("purging jobs of %s: "),$this->printer_uri)
                                              .$this->serveroutput->status,1);
-                                             
+            }
+
             return $this->serveroutput->status; 
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("purging jobs of %s : OPERATION FAILED"),
                                      $this->printer_uri),3);
-            
-    return false;
-    }
 
-    // }}}
-
-    // {{{ createJob()
-    public function createJob() {
-        
+        return false;
+    }
 
+    public function createJob()
+    {
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-        
-        if (!isset($this->setup->uri)) {
+
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("createJob: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("createJob: Printer URI is not set: die\n"));
                 self::_errorLog("createJob: Printer URI is not set, die",2);
                 return FALSE;
                 }
             }
-            
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-        
+        }
+
         if (!isset($this->setup->copies))
+        {
             self::setCopies(1);
+        }
 
         if (!isset($this->meta->fidelity))
+        {
             $this->meta->fidelity = '';
+        }
  
         if (!isset($this->meta->sides))
+        {
             $this->meta->sides = '';
-        
+        }
+
         if (!isset($this->meta->page_ranges))
+        {
             $this->meta->page_ranges = '';
-                    
+        }
+
         if (!isset($this->setup->jobname))
+        {
             if (is_readable($this->data))
+            {
                 self::setJobName(basename($this->data),true);
+            }
             else
+            {
                 self::setJobName();
+            }
+        }
         unset($this->setup->jobname);
 
         if (!isset($this->timeout))
+        {
             $this->timeout = 60;
-        
+        }
+
         $timeout = self::_integerBuild($this->timeout);
         
-
         $this->meta->timeout = chr(0x21) // integer
                              . self::_giveMeStringLength("multiple-operation-time-out")
                              . "multiple-operation-time-out"
                              . self::_giveMeStringLength($timeout)
                              . $timeout;
-                             
+
         $jobattributes = '';
         $operationattributes = '';
         $printerattributes = '';
         self::_buildValues($operationattributes,$jobattributes,$printerattributes);
-        
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x05) // Create-Job | operation-id
                          . $this->meta->operation_id //           request-id
@@ -292,40 +322,44 @@ class ExtendedPrintIPP extends PrintIPP {
                          . $this->meta->page_ranges
                          . $jobattributes
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         unset ($this->meta->copies,$this->meta->sides,$this->meta->page_ranges);
 
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("creating job %s, printer %s\n"),$this->last_job,$this->printer_uri)); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
+
         if (self::_sendHttp ($post_values,$this->paths['printers']))
-            if(self::_parseServerOutput()) {
+        {
+            if(self::_parseServerOutput())
+            {
                 $this->_getJobId();
                 $this->_getJobUri();
                 $this->_parseJobAttributes();
-            } else {
+            }
+            else
+            {
                 $this->jobs = array_merge($this->jobs,array(''));
                 $this->jobs_uri = array_merge($this->jobs_uri,array(''));
-                }
-
-
-        
+            }
+        }
 
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("Create job: job %s"),$this->last_job)
                             .$this->serveroutput->status,3);
-            else {
+            }
+            else
+            {
 
                 $this->jobs = array_merge($this->jobs,array(""));
                 $this->jobs_uri = array_merge($this->jobs_uri,array(""));
@@ -333,186 +367,207 @@ class ExtendedPrintIPP extends PrintIPP {
                 }                             
             return $this->serveroutput->status; 
             }    
-            
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("Creating job on %s : OPERATION FAILED"),
                                      $this->printer_uri),3);
-            
+
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
-    return false;
+        return false;
     }
 
-    // }}}
-    
-    // {{{ sendDocument($job)
-    public function sendDocument($job,$is_last=false){
-        
+    public function sendDocument($job,$is_last=false)
+    {
         self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
 
         if (!$this->_stringDocument($job,$is_last))
+        {
             return FALSE;
-                       
-        if (is_readable($this->data)){
+        }
+
+        if (is_readable($this->data))
+        {
             self::_putDebug( _("sending Document\n")); 
-                
+
             $this->output = $this->stringjob;
-           
+
             if ($this->setup->datatype == "TEXT")
-                $this->output .= chr(0x16); // ASCII "SYN"
-            
-             
+            {
+                $this->output .= chr(0x16);
+            } // ASCII "SYN"
+
             $post_values = array( "Content-Type" => "application/ipp",
                                   "Data" => $this->output,
                                   "File" => $this->data);
-            
+
             if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed))
+            {
                 $post_values = array_merge($post_values,array("Filetype"=>"TEXT"));
-            
-        } else {                      
+            }
+        }
+        else
+        {
             self::_putDebug( _("sending DATA as document\n")); 
-            
+
             $this->output = $this->stringjob;
             $this->output .= $this->datahead;    
             $this->output .= $this->data;
             $this->output .= $this->datatail;
-            
+
             $post_values = array( "Content-Type" => "application/ipp",
                                   "Data" => $this->output);
-             
-            
-            }
-            
-        if (self::_sendHttp ($post_values,$this->paths['printers'])) {
-        
-            if(self::_parseServerOutput()) {
+        }
+
+        if (self::_sendHttp ($post_values,$this->paths['printers']))
+        {
+
+            if(self::_parseServerOutput())
+            {
                 $this->_getJobId();
                 //$this->_getPrinterUri();
                 $this->_getJobUri();
                 $this->_parseJobAttributes();
-            } else {
+            }
+            else
+            {
                 $this->jobs = array_merge($this->jobs,array($job));
                 $this->jobs_uri = array_merge($this->jobs_uri,array($job));
                 }
-
             }
         
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
 
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf("sending document, job %s: %s",$job,$this->serveroutput->status),3);
-            else {
+            }
+            else
+            {
                 $this->jobs = array_merge($this->jobs,array(""));
                 $this->jobs_uri = array_merge($this->jobs_uri,array(""));
                 self::_errorLog(sprintf("sending document, job %s: %s",$job,$this->serveroutput->status),1);
-                }
-            return $this->serveroutput->status; 
-            
             }
+            return $this->serveroutput->status; 
+        }
 
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         $this->jobs = array_merge($this->jobs,array($job));
         $this->jobs_uri = array_merge($this->jobs_uri,array($job));
         self::_errorLog(sprintf("sending document, job %s : OPERATION FAILED",$job),1);
-    
-    return false;
+
+        return false;
     }
-    // }}}
 
-    // {{{ sendURI ($uri,$job,$is_last=false) 
-    public function sendURI ($uri,$job,$is_last=false){     
 
+    public function sendURI ($uri,$job,$is_last=false)
+    {
         self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
 
         if (!$this->_stringSendUri($uri,$job,$is_last))
+        {
             return FALSE;
-                       
+        }
+
             self::_putDebug( _("sending URI $uri\n")); 
-                
+
             $this->output = $this->stringjob;
-             
+
             $post_values = array( "Content-Type" => "application/ipp",
                                   "Data" => $this->output);
-            
-        if (self::_sendHttp ($post_values,$this->paths['printers'])) {
-        
-            if(self::_parseServerOutput()) {
+
+        if (self::_sendHttp ($post_values,$this->paths['printers']))
+        {
+            if(self::_parseServerOutput())
+            {
                 $this->_getJobId();
                 //$this->_getPrinterUri();
                 $this->_getJobUri();
                 $this->_parseJobAttributes();
-            } else {
+            }
+            else
+            {
                 $this->jobs = array_merge($this->jobs,array($job));
                 $this->jobs_uri = array_merge($this->jobs_uri,array($job));
                 }
-
             }
-        
+
         $this->attributes = &$this->job_attributes;
 
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
 
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf("sending uri %s, job %s: %s",$uri,$job,$this->serveroutput->status),3);
-            else {
+            }
+            else
+            {
                 $this->jobs = array_merge($this->jobs,array(""));
                 $this->jobs_uri = array_merge($this->jobs_uri,array(""));
                 self::_errorLog(sprintf("sending uri, job %s: %s",$uri,$job,$this->serveroutput->status),1);
-                }
-            return $this->serveroutput->status; 
-            
             }
+            return $this->serveroutput->status; 
+        }
 
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         $this->jobs = array_merge($this->jobs,array($job));
         $this->jobs_uri = array_merge($this->jobs_uri,array($job));
         self::_errorLog(sprintf("sending uri %s, job %s : OPERATION FAILED",$uri,$job),1);
-    
-    return false;
+
+        return false;
     }
-    // }}}
 
-    // {{{ pausePrinter ()
-     public function pausePrinter() {
-        
+
+    public function pausePrinter()
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
 
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-        
-        if (!isset($this->setup->uri)) {
+
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("pausePrinter: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("pausePrinter: Printer URI is not set: die\n"));
                 self::_errorLog("pausePrinter: Printer URI is not set, die",2);
                 return FALSE;
-                }
             }
-            
+        }
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-       
+        }
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x10) // Pause-Printer | operation-id
                          . $this->meta->operation_id //           request-id
@@ -527,81 +582,94 @@ class ExtendedPrintIPP extends PrintIPP {
                          . self::_giveMeStringLength(chr(0x01))
                          . chr(0x01) */
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("pause printer %s\n"),$this->printer_uri)); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
-        if (self::_sendHttp ($post_values,$this->paths['admin'])) {
+
+        if (self::_sendHttp ($post_values,$this->paths['admin']))
+        {
             self::_parseServerOutput();
             self::_parseAttributes();
-            }
+        }
 
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("Pause printer %s: "),$this->printer_uri)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("pause printer %s: "),$this->printer_uri)
                                              .$this->serveroutput->status,1);
-                                             
+            }
+
             return $this->serveroutput->status; 
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("pause printer %s : OPERATION FAILED"),
                                      $this->printer_uri),3);
-            
-    return false;
+
+        return false;
     }
-    // }}}
 
-    // {{{ resumePrinter ()
-     public function resumePrinter() {
-        
+
+    public function resumePrinter()
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
 
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-        
-        if (!isset($this->setup->uri)) {
+
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("resumePrinter: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("resumePrinter: Printer URI is not set: die\n"));
                 self::_errorLog(" Printer URI is not set, die",2);
                 return FALSE;
-                }
             }
-            
+        }
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-       
+        }
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x11) // suse-Printer | operation-id
                          . $this->meta->operation_id //           request-id
@@ -611,82 +679,97 @@ class ExtendedPrintIPP extends PrintIPP {
                          . $this->meta->printer_uri
                          . $this->meta->username
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("resume printer %s\n"),$this->printer_uri)); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
-        if (self::_sendHttp ($post_values,$this->paths['admin'])) {
+
+        if (self::_sendHttp ($post_values,$this->paths['admin']))
+        {
             self::_parseServerOutput();
             self::_parseAttributes();
-            }
+        }
 
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("resume printer %s: "),$this->printer_uri)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("resume printer %s: "),$this->printer_uri)
                                              .$this->serveroutput->status,1);
-                                             
+            }
+
             return $this->serveroutput->status; 
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("resume printer %s : OPERATION FAILED"),
                                      $this->printer_uri),3);
-            
-    return false;
+
+        return false;
     }
-    // }}}
 
-    // {{{ holdJob ($job_uri)
-    public function holdJob ($job_uri,$until='indefinite') {
-    
+
+    public function holdJob ($job_uri,$until='indefinite')
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri)));
 
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-           
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-        
+        }
+
         if (!isset($this->meta->message))
+        {
             $this->meta->message = '';
+        }
 
         self::_setJobUri($job_uri);
         
         $until_strings = array('no-hold','day-time','evening','night','weekend','second-shift','third-shift');
         if (in_array($until,$until_strings))
+        {
             true;
+        }
         else 
+        {
             $until = 'indefinite';
+        }
 
         $this->meta->job_hold_until = chr(0x42) // keyword
                                     . self::_giveMeStringLength('job-hold-until')
                                     . 'job-hold-until'
                                     . self::_giveMeStringLength($until)
                                     . $until;
-        
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x0C) // Hold-Job | operation-id
                          . $this->meta->operation_id //           request-id
@@ -698,68 +781,81 @@ class ExtendedPrintIPP extends PrintIPP {
                          . $this->meta->message
                          . $this->meta->job_hold_until
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("hold job %s until %s\n"),$job_uri,$until)); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
-        if (self::_sendHttp ($post_values,$this->paths['jobs'])) {
+
+        if (self::_sendHttp ($post_values,$this->paths['jobs']))
+        {
             self::_parseServerOutput();
             self::_parseAttributes();
             }
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             
             $this->status = array_merge($this->status,array($this->serveroutput->status));
             
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("hold job %s until %s: "),$job_uri,$until)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("hold job %s until %s: "),$job_uri,$until)
                                              .$this->serveroutput->status,1);
-                                             
+            }
+
             return $this->serveroutput->status; 
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("hold job %s until %s : OPERATION FAILED"),
                                      $job_uri,$until),3);
-            
-    return false;
+
+        return false;
     }
-    // }}}
-    
-    // {{{ releaseJob ($job_uri)
-    public function releaseJob ($job_uri) {
     
+
+    public function releaseJob ($job_uri)
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri)));
 
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-           
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-        
+        }
+
         if (!isset($this->meta->message))
+        {
             $this->meta->message = '';
+        }
 
         self::_setJobUri($job_uri);
-        
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x0D) // Hold-Job | operation-id
                          . $this->meta->operation_id //           request-id
@@ -770,75 +866,85 @@ class ExtendedPrintIPP extends PrintIPP {
                          . $this->meta->username
                          . $this->meta->message
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("release job %s\n"),$job_uri)); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
-        if (self::_sendHttp ($post_values,$this->paths['jobs'])) {
+
+        if (self::_sendHttp ($post_values,$this->paths['jobs']))
+        {
             self::_parseServerOutput();
             self::_parseAttributes();
-            }
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        }
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
             
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("release job %s: "),$job_uri)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("release job %s: "),$job_uri)
                                              .$this->serveroutput->status,1);
-                                             
+            }
+
             return $this->serveroutput->status; 
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("release job %s: OPERATION FAILED"),
                                      $job_uri),3);
-            
-    return false;
+
+        return false;
     }
-    // }}}
-    
-    // {{{ restartJob ($job_uri)
-    public function restartJob ($job_uri) {
-    
+
+
+    public function restartJob ($job_uri)
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri)));
 
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-           
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-        
+        }
+
         if (!isset($this->meta->message))
+        {
             $this->meta->message = '';
+        }
 
         self::_setJobUri($job_uri);
-        
-       
+
         $jobattributes = '';
         $operationattributes = '';
         $printerattributes = '';
         self::_buildValues ($operationattributes,$jobattributes,$printerattributes); 
  
-        
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x0E) // Hold-Job | operation-id
                          . $this->meta->operation_id //           request-id
@@ -850,92 +956,110 @@ class ExtendedPrintIPP extends PrintIPP {
                          . $this->meta->message
                          . $jobattributes // job-hold-until is set by setAttribute($attribute,$value)
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("release job %s\n"),$job_uri)); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
-        if (self::_sendHttp ($post_values,$this->paths['jobs'])) {
+
+        if (self::_sendHttp ($post_values,$this->paths['jobs']))
+        {
             self::_parseServerOutput();
             self::_parseAttributes();
-            }
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        }
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("release job %s: "),$job_uri)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("release job %s: "),$job_uri)
                                              .$this->serveroutput->status,1);
-                                             
+            }
+
             return $this->serveroutput->status; 
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("release job %s: OPERATION FAILED"),
                                      $job_uri),3);
-            
-    return false;
+
+        return false;
     }
-    // }}}
-    
-    // {{{ setJobAttributes ($job_uri,$deleted_attributes=array())
-    public function setJobAttributes ($job_uri,$deleted_attributes=array()) {
-    
+
+
+    public function setJobAttributes ($job_uri,$deleted_attributes=array())
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri)));
 
         self::_setOperationId();
         $this->parsed = array();
         unset ($this->attributes);
-           
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-        
+        }
+
         if (!isset($this->meta->message))
+        {
             $this->meta->message = '';
+        }
 
-            
         if (!isset($this->meta->copies))
+        {
             $this->meta->copies = '';
+        }
 
         if (!isset($this->meta->sides))
+        {
             $this->meta->sides = '';
-        
+        }
+
         if (!isset($this->meta->page_ranges))
+        {
             $this->meta->page_ranges = '';
+        }
   
         self::_setJobUri($job_uri);
-        
+
         $operationattributes = '';
         $jobattributes = '';
         $printerattributes = '';
         self::_buildValues ($operationattributes,$jobattributes,$printerattributes); 
-        
+
         $this->meta->deleted_attributes = "";
         for ($i = 0 ; $i < count($deleted_attributes) ; $i++)
-                $this->meta->deleted_attributes .= chr(0x16) // out-of-band value
-                                                . self::_giveMeStringLength($deleted_attributes[$i])
-                                                . $deleted_attributes[$i]
-                                                . chr(0x0).chr(0x0); // value-length = 0;
-                
-        
+        {
+            $this->meta->deleted_attributes .= chr(0x16) // out-of-band value
+                . self::_giveMeStringLength($deleted_attributes[$i])
+                . $deleted_attributes[$i]
+                . chr(0x0).chr(0x0);
+        } // value-length = 0;
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x14) // Set-Job-Attributes | operation-id
                          . $this->meta->operation_id //           request-id
@@ -952,47 +1076,52 @@ class ExtendedPrintIPP extends PrintIPP {
                          . $this->meta->page_ranges
                          . $this->meta->deleted_attributes
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("set job attributes for job %s\n"),$job_uri)); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
-        if (self::_sendHttp ($post_values,$this->paths['jobs'])) {
+
+        if (self::_sendHttp ($post_values,$this->paths['jobs']))
+        {
             self::_parseServerOutput();
             self::_parseAttributes();
-            }
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        }
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("set job attributes for job %s: "),$job_uri)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("set job attributes for job %s: "),$job_uri)
                                              .$this->serveroutput->status,1);
+            }
             $this->last_job = $job_uri;
             $this->jobs_uri[count($this->jobs_uri) - 1] = $job_uri;
             return $this->serveroutput->status; 
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("set job attributes for job %s: OPERATION FAILED"),
                                      $job_uri),3);
-            
-    return false;
+
+        return false;
     }
-    // }}}
-    
-    // {{{ setPrinterAttributes ()
-    public function setPrinterAttributes ($document_format='',$deleted_attributes=array()) {
+
+
+    public function setPrinterAttributes ($document_format='',$deleted_attributes=array())
+    {
         /* $document_format (RFC 3380)
          If the client includes this attribute, the Printer MUST change
          the supplied attributes for the document format specified by
@@ -1010,55 +1139,72 @@ class ExtendedPrintIPP extends PrintIPP {
          supplied attributes for all document formats, whether or not
          they vary by document-format.
          */
- 
+
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
         unset ($this->attributes);
-        
+
         self::_setOperationId();
         $this->parsed = array();
-           
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-        
+        }
+
         if (!isset($this->meta->message))
+        {
             $this->meta->message = '';
-            
+        }
+
         if (!isset($this->meta->copies))
+        {
             $this->meta->copies = '';
+        }
 
         if (!isset($this->meta->sides))
+        {
             $this->meta->sides = '';
-        
+        }
+
         if (!isset($this->meta->page_ranges))
+        {
             $this->meta->page_ranges = '';
-  
+        }
+
         if ($document_format)
+        {
         $document_format = chr(0x49) // document-format tag
-                                . self::_giveMeStringLength('document-format')
-                                . 'document-format' // 
-                                . self::_giveMeStringLength($document_format)
-                                . $document_format; // value
+            . self::_giveMeStringLength('document-format')
+            . 'document-format' // 
+            . self::_giveMeStringLength($document_format)
+            . $document_format;
+        } // value
 
         $operationattributes = '';
         $jobattributes = '';
         $printerattributes = '';
         self::_buildValues ($operationattributes,$jobattributes,$printerattributes); 
-        
+
         $this->meta->deleted_attributes = "";
         for ($i = 0 ; $i < count($deleted_attributes) ; $i++)
+        {
                 $this->meta->deleted_attributes .= chr(0x16) // out-of-band "deleted" value
                                                 . self::_giveMeStringLength($deleted_attributes[$i])
                                                 . $deleted_attributes[$i]
-                                                . chr(0x0).chr(0x0); // value-length = 0;
-                
-        
+                                                . chr(0x0).chr(0x0);
+        } // value-length = 0;
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x13) // Set-Printer-Attributes | operation-id
                          . $this->meta->operation_id //           request-id
@@ -1076,144 +1222,176 @@ class ExtendedPrintIPP extends PrintIPP {
                          . $this->meta->page_ranges
                          . $this->meta->deleted_attributes
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("set printer attributes for job %s\n"),$this->printer_uri)); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
-        if (self::_sendHttp ($post_values,$this->paths['printers'])) {
+
+        if (self::_sendHttp ($post_values,$this->paths['printers']))
+        {
             self::_parseServerOutput();
             self::_parseAttributes();
-            }
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        }
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("set printer attributes for printer %s: "),$this->printer_uri)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("set printer attributes for printer %s: "),$this->printer_uri)
                                              .$this->serveroutput->status,1);
-            
+            }
+
             return $this->serveroutput->status; 
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("set printer attributes for printer %s: OPERATION FAILED"),
                                      $this->printer_uri),1);
-            
-    return false;
- 
-    }
-    // }}}
 
-// REQUEST BUILDING
+        return false;
+    }
 
-    // {{{ _setDocumentUri ($job_uri) 
-    protected function _setDocumentUri () {
-       
+    // REQUEST BUILDING
+    protected function _setDocumentUri ()
+    {
         $this->meta->document_uri = chr(0x45) // type uri
                                 . chr(0x00).chr(0x0c) // name-length
                                 . "document-uri"
                                 . self::_giveMeStringLength($this->document_uri)
                                 . $this->document_uri;
-        
+
         self::_putDebug( "document uri is: ".$this->document_uri."\n");
         $this->setup->document_uri = 1;
-
     }
-    // }}}
 
-    // {{{ _stringUri ()
-    protected function _stringUri () {
-    
+
+    protected function _stringUri ()
+    {
         self::_setDocumentUri();
-        
-        if (!isset($this->setup->document_uri)) {
+
+        if (!isset($this->setup->document_uri))
+        {
             trigger_error(_("_stringUri: Document URI is not set: die"),E_USER_WARNING);
             self::_putDebug( _("_stringUri: Document URI is not set: die\n"));
             self::_errorLog("Document URI is not set, die",2);
             return FALSE;
         }
         unset ($this->setup->document_uri);
-               
-        if (!isset($this->setup->uri)) {
+
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("_stringUri: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("_stringUri: Printer URI is not set: die\n"));
                 self::_errorLog("_stringUri: Printer URI is not set, die",2);
                 return FALSE;
-                }
             }
+        }
   
         if (!isset($this->setup->charset))
+        {
             $this->meta->charset = "";
-        //    self::setCharset('us-ascii');
+        }
         if (!isset($this->setup->datatype))
+        {
             self::setBinary();
-        if (!isset($this->setup->uri)) {
+        }
+        if (!isset($this->setup->uri))
+        {
             trigger_error(_("_stringUri: Printer URI is not set: die"),E_USER_WARNING);
             self::_putDebug( _("_stringUri: Printer URI is not set: die\n"));
             self::_errorLog("Printer URI is not set, die",2);
             return FALSE;
-            }
+        }
         if (!isset($this->setup->copies))
+        {
             self::setCopies(1);
-        
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->setup->mime_media_type))
+        {
             self::setMimeMediaType();
+        }
         unset ($this->setup->mime_media_type);
-            
+
         if (!isset($this->setup->jobname))
+        {
             if (is_readable($this->data))
+            {
                 self::setJobName(basename($this->data),true);
+            }
             else
+            {
                 self::setJobName();
+            }
+        }
         unset($this->setup->jobname);
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
+        }
 
         if (!isset($this->meta->fidelity))
+        {
             $this->meta->fidelity = '';
-        
+        }
+
         if (!isset($this->meta->document_name))
+        {
             $this->meta->document_name = '';
+        }
 
         if (!isset($this->meta->sides))
+        {
             $this->meta->sides = '';
-        
+        }
+
         if (!isset($this->meta->page_ranges))
+        {
             $this->meta->page_ranges = '';
-         
+        }
+
         $jobattributes = '';
         $operationattributes = '';
         $printerattributes = '';
         self::_buildValues($operationattributes,$jobattributes,$printerattributes);
-         
+
         self::_setOperationId();
-       
+
         if (!isset($this->error_generation->request_body_malformed))
+        {
             $this->error_generation->request_body_malformed = "";
-       
+        }
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x03) // Print-URI | operation-id
                          . $this->meta->operation_id //           request-id
@@ -1234,72 +1412,98 @@ class ExtendedPrintIPP extends PrintIPP {
                          . $this->meta->page_ranges
                          . $jobattributes
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
         return TRUE;
     }
-    // }}}
-    
-    // {{{ _stringDocument ($job,$is_last)
-    protected function _stringDocument ($job,$is_last) {
-    
+
+
+    protected function _stringDocument ($job,$is_last)
+    {
         if ($is_last == false)
+        {
             $is_last = chr(0x00);
+        }
         else
+        {
             $is_last = chr(0x01);
-    
+        }
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
+        {
+            self::setCharset();
+        }
         if (!isset($this->setup->datatype))
+        {
             self::setBinary();
+        }
 
-        if (!isset($this->setup->uri)) {
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("_stringJob: Printer URI is not set: die\n"));
                 self::_errorLog(" Printer URI is not set, die",2);
                 return FALSE;
                 }
             }
-            
+
         if (!isset($this->setup->copies))
+        {
             $this->meta->copies = "";
-        
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->setup->mime_media_type))
+        {
             $this->meta->mime_media_type = "";
+        }
         if ($this->setup->datatype != "TEXT")
+        {
         unset ($this->setup->mime_media_type);
-            
+        }
+
         if (!isset($this->meta->fidelity))
+        {
             $this->meta->fidelity = '';
-        
+        }
+
         if (!isset($this->meta->document_name))
+        {
             $this->meta->document_name = '';
+        }
 
         if (!isset($this->meta->sides))
+        {
             $this->meta->sides = '';
-        
+        }
+
         if (!isset($this->meta->page_ranges))
+        {
             $this->meta->page_ranges = '';
-       
+        }
+
         $operationattributes = '';
         $jobattributes = '';
         $printerattributes = '';
         self::_buildValues($operationattributes,$jobattributes,$printerattributes);
-        
+
         self::_setOperationId();
 
-       
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x06) // Send-Document | operation-id
                          . $this->meta->operation_id //           request-id
@@ -1322,84 +1526,107 @@ class ExtendedPrintIPP extends PrintIPP {
                          . self::_giveMeStringLength($is_last)
                          . $is_last
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-        
 
         self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
         return TRUE;
     }
-    // }}}
 
-    // {{{ _stringSendUri ($uri,$job,$is_last)
-    protected function _stringSendUri ($uri,$job,$is_last) {
-        
+
+    protected function _stringSendUri ($uri,$job,$is_last)
+    {
         $this->document_uri = $uri;
         self::_setDocumentUri();
-        
-        if (!isset($this->setup->document_uri)) {
+
+        if (!isset($this->setup->document_uri))
+        {
             trigger_error(_("_stringUri: Document URI is not set: die"),E_USER_WARNING);
             self::_putDebug( _("_stringUri: Document URI is not set: die\n"));
             self::_errorLog("Document URI is not set, die",2);
             return FALSE;
         }
         unset ($this->setup->document_uri);
-         
-        
+
         if ($is_last == false)
+        {
             $is_last = chr(0x00);
+        }
         else
+        {
             $is_last = chr(0x01);
-    
+        }
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
+        {
+            self::setCharset();
+        }
         if (!isset($this->setup->datatype))
+        {
             self::setBinary();
+        }
 
-        if (!isset($this->setup->uri)) {
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            } 
+            else
+            {
                 trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("_stringJob: Printer URI is not set: die\n"));
                 self::_errorLog(" Printer URI is not set, die",2);
                 return FALSE;
                 }
             }
-            
+
         if (!isset($this->setup->copies))
+        {
             $this->meta->copies = "";
-        
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->setup->mime_media_type))
+        {
             $this->meta->mime_media_type = "";
+        }
         unset ($this->setup->mime_media_type);
-            
+
         if (!isset($this->meta->fidelity))
+        {
             $this->meta->fidelity = '';
-        
+        }
+
         if (!isset($this->meta->document_name))
+        {
             $this->meta->document_name = '';
+        }
 
         if (!isset($this->meta->sides))
+        {
             $this->meta->sides = '';
-        
+        }
+
         if (!isset($this->meta->page_ranges))
+        {
             $this->meta->page_ranges = '';
-       
+        }
+
         $operationattributes = '';
         $jobattributes = '';
         $printerattributes = '';
         self::_buildValues($operationattributes,$jobattributes,$printerattributes);
-        
+
         self::_setOperationId();
 
-       
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x07) // Send-Uri | operation-id
                          . $this->meta->operation_id //           request-id
@@ -1422,20 +1649,8 @@ class ExtendedPrintIPP extends PrintIPP {
                          . self::_giveMeStringLength($is_last)
                          . $is_last
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-        
 
         self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
         return TRUE;
     }
-    // }}}
-    
-};
-
-/*
- * Local variables:
- * mode: php
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- */
-?>
+}
\ No newline at end of file
diff --git a/htdocs/includes/printipp/PrintIPP.php b/htdocs/includes/printipp/PrintIPP.php
index 9ed502c2d112e27e175fb368762a50c66735826c..ffda9e8f1f71291ae4d2b1806ea30771c530628c 100644
--- a/htdocs/includes/printipp/PrintIPP.php
+++ b/htdocs/includes/printipp/PrintIPP.php
@@ -1,5 +1,5 @@
 <?php
-/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+
  /* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/PrintIPP.php,v 1.3 2010/09/06 22:41:41 harding Exp $
  *
  * Class PrintIPP - Send IPP requests, Get and parses IPP Responses.
@@ -40,58 +40,49 @@
     TODO: beta tests on other servers than Cups
 */
 
+require_once("BasicIPP.php");
 
-    // {{{ required and included files
-            
-            require_once("BasicIPP.php");
-            
-    // }}}
-
-
-class PrintIPP extends BasicIPP {
-
-    // {{{ constructor
-    public function __construct() {
+class PrintIPP extends BasicIPP
+{
+    public function __construct()
+    {
         parent::__construct();
     }
-    // }}}
-
-/*****************
-*
-* PUBLIC FUNCTIONS
-*
-*******************/
-// SETTINGS
 
 // OPERATIONS
-
-    // {{{ printJob()
-    public function printJob(){
-        
+    public function printJob()
+    {
         self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
 
         if (!$this->_stringJob())
+        {
             return FALSE;
-                       
-        if (is_readable($this->data)){
+        }
+
+        if (is_readable($this->data))
+        {
             self::_putDebug( _("Printing a FILE\n"),3); 
-                
+
             $this->output = $this->stringjob;
-           
+
             if ($this->setup->datatype == "TEXT")
+            {
                 $this->output .= chr(0x16);
-            
-             
+            }
+
             $post_values = array( "Content-Type" => "application/ipp",
                                   "Data" => $this->output,
                                   "File" => $this->data);
-            
+
             if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed))
+            {
                 $post_values = array_merge($post_values,array("Filetype"=>"TEXT"));
-            
-        } else {                      
+            }
+        }
+        else
+        {
             self::_putDebug( _("Printing DATA\n"),3); 
-            
+
             $this->output = $this->stringjob;
             $this->output .= $this->datahead;    
             $this->output .= $this->data;
@@ -99,25 +90,25 @@ class PrintIPP extends BasicIPP {
             
             $post_values = array( "Content-Type" => "application/ipp",
                                   "Data" => $this->output);
-             
-            
-            }
-            
-        if (self::_sendHttp ($post_values,$this->paths['printers'])) {
-        
-            if(self::_parseServerOutput()) {
+        }
+
+        if (self::_sendHttp ($post_values,$this->paths['printers']))
+        {
+            if(self::_parseServerOutput())
+            {
                 $this->_getJobId();
                 $this->_getJobUri();
                 $this->_parseJobAttributes();
-            } else {
+            }
+            else
+            {
                 $this->jobs = array_merge($this->jobs,array(''));
                 $this->jobs_uri = array_merge($this->jobs_uri,array(''));
                 }
-
             }
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
 
             if ($this->serveroutput->status == "successfull-ok")
@@ -131,138 +122,174 @@ class PrintIPP extends BasicIPP {
                 self::_errorLog(sprintf("printing job: ",$this->last_job) .$this->serveroutput->status,1);
                 if ($this->with_exceptions)
                 {
-                   throw new ippException(sprintf("job status: %s",
+                    throw new ippException(sprintf("job status: %s",
                     $this->serveroutput->status));
                 }
             }
             return $this->serveroutput->status; 
-            
-            }
+        }
 
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
         self::_errorLog("printing job : OPERATION FAILED",1);
-    
-    return false;
+
+        return false;
     }
-    // }}}
 
-    // {{{ cancelJob ($job_uri)
-    public function cancelJob ($job_uri) {
-        
+    public function cancelJob ($job_uri)
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
-        
+
         self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
-        
+
         if (!$this->_stringCancel($job_uri))
-        return FALSE;
-                       
+        {
+            return FALSE;
+        }
+
         self::_putDebug( _("Cancelling Job $job_uri\n"),3); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
+
         if (self::_sendHttp ($post_values,$this->paths['jobs']))
+        {
             self::_parseServerOutput();
-          
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        }
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
 
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,3);
-            else            
+            }
+            else
+            {
                 self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,1);
+            }
             return $this->serveroutput->status; 
+        }
 
-            }
+        $this->status = array_merge($this->status,array("OPERATION FAILED"));
+        self::_errorLog("cancelling job : OPERATION FAILED",3);
 
-            $this->status = array_merge($this->status,array("OPERATION FAILED"));
-            self::_errorLog("cancelling job : OPERATION FAILED",3);
-            
-    return false;
+        return false;
     }
-    // }}}
 
-    // {{{  validateJob ()
-    public function validateJob () {
-        
+    public function validateJob ()
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
-        
+
         $this->serveroutput->response = '';
 
         self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
-        
-                       
+
         self::_putDebug( _("Validate Job\n"),2); 
-                
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
+        {
+            self::setCharset();
+        }
         if (!isset($this->setup->datatype))
+        {
             self::setBinary();
+        }
 
-        if (!isset($this->setup->uri)) {
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
                 self::_errorLog(" Printer URI is not set, die",2);
                 return FALSE;
                 }
             }
-        
+
         if (!isset($this->meta->copies))
+        {
             self::setCopies(1);
+        }
+
         if (!isset($this->setup->copies))
+        {
             self::setCopies(1);
-        
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->setup->mime_media_type))
+        {
             self::setMimeMediaType();
+        }
+
         if ($this->setup->datatype != "TEXT")
-        unset ($this->setup->mime_media_type);
-            
+        {
+            unset ($this->setup->mime_media_type);
+        }
+
         if (!isset($this->setup->jobname))
+        {
             if (is_readable($this->data))
+            {
                 self::setJobName(basename($this->data),true);
+            }
             else
+            {
                 self::setJobName();
+            }
+        }
         unset($this->setup->jobname);
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
+        }
 
         if (!isset($this->meta->fidelity))
+        {
             $this->meta->fidelity = '';
-        
+        }
+
         if (!isset($this->meta->document_name))
+        {
             $this->meta->document_name = '';
+        }
 
         if (!isset($this->meta->sides))
+        {
             $this->meta->sides = '';
-        
+        }
+
         if (!isset($this->meta->page_ranges))
+        {
             $this->meta->page_ranges = '';
-       
+        }
+
         $jobattributes = '';
         $operationattributes = '';
         $printerattributes = '';
         self::_buildValues ($operationattributes,$jobattributes,$printerattributes);
-       
+
         self::_setOperationId();
 
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
@@ -284,43 +311,45 @@ class PrintIPP extends BasicIPP {
                          . $this->meta->page_ranges
                          . $jobattributes
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-        
 
         self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
- 
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
+
         if (self::_sendHttp ($post_values,$this->paths['printers']))
-                if(self::_parseServerOutput())
-                    self::_parseAttributes();
-          
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        {
+            if(self::_parseServerOutput())
+            {
+                self::_parseAttributes();
+            }
+        }
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
 
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog("validate job: ".$this->serveroutput->status,3);
-            else            
+            }
+            else
+            {
                 self::_errorLog("validate job: ".$this->serveroutput->status,1);
-            
+            }
             return $this->serveroutput->status; 
+        }
 
-            }
+        $this->status = array_merge($this->status,array("OPERATION FAILED"));
+        self::_errorLog("validate job : OPERATION FAILED",3);
 
-            $this->status = array_merge($this->status,array("OPERATION FAILED"));
-            self::_errorLog("validate job : OPERATION FAILED",3);
-            
-    return false;
+        return false;
     }
-    // }}}
 
-    // {{{ getPrinterAttributes()
-    public function getPrinterAttributes() {
-        
+    public function getPrinterAttributes()
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
 
@@ -330,32 +359,42 @@ class PrintIPP extends BasicIPP {
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-        
-        if (!isset($this->setup->uri)) {
+
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
                 self::_errorLog(" Printer URI is not set, die",2);
                 return FALSE;
                 }
             }
-            
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
-       
+        }
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x0b) // Print-URI | operation-id
                          . $this->meta->operation_id //           request-id
@@ -366,109 +405,137 @@ class PrintIPP extends BasicIPP {
                          . $this->meta->username
                          . $printerattributes
                          . chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("Getting printer attributes of %s\n"),$this->printer_uri),2); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
+
         if (self::_sendHttp ($post_values,$this->paths['root']))
+        {
             if (self::_parseServerOutput())
+            {
                 self::_parsePrinterAttributes(); 
-        
+            }
+        }
+
         $this->attributes = &$this->printer_attributes;
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if  ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("getting printer attributes of %s: %s"),$this->printer_uri,
                                                                         $this->serveroutput->status),3);
+            }
             else 
+            {
                 self::_errorLog(sprintf(_("getting printer attributes of %s: %s"),$this->printer_uri,
                                                                         $this->serveroutput->status),1);
+            }
 
             return $this->serveroutput->status;
-            }
+        }
 
-            $this->status = array_merge($this->status,array("OPERATION FAILED"));
-            self::_errorLog(date("Y-m-d H:i:s : ")
-                        .basename($_SERVER['PHP_SELF'])
-                        .sprintf(_("getting printer's attributes of %s : OPERATION FAILED"),
-                                     $this->printer_uri),3);
-    
-    return false;
+        $this->status = array_merge($this->status,array("OPERATION FAILED"));
+        self::_errorLog(date("Y-m-d H:i:s : ")
+            .basename($_SERVER['PHP_SELF'])
+            .sprintf(_("getting printer's attributes of %s : OPERATION FAILED"),
+                $this->printer_uri),3);
+
+        return false;
     }
-    // }}}
 
-    // {{{ getJobs ($my_jobs=true,$limit=0,$which_jobs="");
-    public function getJobs($my_jobs=true,$limit=0,$which_jobs="not-completed",$subset=false) {
-        
+    public function getJobs($my_jobs=true,$limit=0,$which_jobs="not-completed",$subset=false)
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
 
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-        
-        if (!isset($this->setup->uri)) {
+
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("getJobs: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
                 self::_errorLog("getJobs: Printer URI is not set, die",2);
                 return FALSE;
                 }
             }
-            
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
+        }
 
-        if ($limit) {
+        if ($limit)
+        {
             $limit = self::_integerBuild($limit);
             $this->meta->limit = chr(0x21) // integer
                                . self::_giveMeStringLength('limit')
                                . 'limit'
                                . self::_giveMeStringLength($limit)
                                . $limit;
-        } else
+        }
+        else
+        {
             $this->meta->limit = '';
-        
+        }
+
         if ($which_jobs == 'completed')
+        {
                 $this->meta->which_jobs = chr(0x44) // keyword
                                         . self::_giveMeStringLength('which-jobs')
                                         . 'which-jobs'
                                         . self::_giveMeStringLength($which_jobs)
                                         . $which_jobs;
+        }
         else
+        {
             $this->meta->which_jobs = "";
+        }
 
         if ($my_jobs)
+        {
             $this->meta->my_jobs = chr(0x22) // boolean
                                  . self::_giveMeStringLength('my-jobs')
                                  . 'my-jobs'
                                  . self::_giveMeStringLength(chr(0x01))
                                  . chr(0x01);
+        }
         else
+        {
             $this->meta->my_jobs = '';
-            
+        }
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x0A) // Get-Jobs | operation-id
                          . $this->meta->operation_id //           request-id
@@ -479,9 +546,9 @@ class PrintIPP extends BasicIPP {
                          . $this->meta->username
                          . $this->meta->limit
                          . $this->meta->which_jobs 
-                         . $this->meta->my_jobs
-                         ;
-       if ($subset) {
+                         . $this->meta->my_jobs;
+       if ($subset)
+       {
            $this->stringjob .=
                           chr(0x44) // keyword
                          . self::_giveMeStringLength('requested-attributes')
@@ -502,106 +569,122 @@ class PrintIPP extends BasicIPP {
                          . self::_giveMeStringLength('')
                          . ''
                          . self::_giveMeStringLength('job-state-reason')
-                         . 'job-state-reason'
-                         ;
+                         . 'job-state-reason';
         }
-        else { # cups 1.4.4 doesn't return much of anything without this
+        else
+        { # cups 1.4.4 doesn't return much of anything without this
             $this->stringjob .=
                           chr(0x44) // keyword
                          . self::_giveMeStringLength('requested-attributes')
                          . 'requested-attributes'
                          . self::_giveMeStringLength('all')
-                         . 'all'
-                         ;
+                         . 'all';
         }
         $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
+
         if (self::_sendHttp ($post_values,$this->paths['jobs']))
+        {
             if (self::_parseServerOutput())
+            {
                 self::_parseJobsAttributes();
-                
+            }
+        }
+
         $this->attributes = &$this->jobs_attributes;
 
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("getting jobs of printer %s: "),$this->printer_uri)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("getting jobs of printer %s: "),$this->printer_uri)
                                              .$this->serveroutput->status,1);
-                                             
+            }
+
             return $this->serveroutput->status;
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("getting jobs of %s : OPERATION FAILED"),
                                      $this->printer_uri),3);
-            
+
     return false;
     }
-    // }}}
 
-    // {{{ getJobAttributes ($job_uri,subset="false",$attributes_group="all");
-    public function getJobAttributes($job_uri,$subset=false,$attributes_group="all") {
-       
+
+    public function getJobAttributes($job_uri,$subset=false,$attributes_group="all")
+    {
         $this->jobs = array_merge($this->jobs,array(""));
         $this->jobs_uri = array_merge($this->jobs_uri,array(""));
-        
-        if (!$job_uri) {
+
+        if (!$job_uri)
+        {
             trigger_error(_("getJobAttributes: Job URI is not set, die."));
             return FALSE;
             }
- 
+
         self::_setOperationId();
         $this->parsed = array();
         unset($this->printer_attributes);
-        
-        if (!isset($this->setup->uri)) {
+
+        if (!isset($this->setup->uri))
+        {
             $this->getPrinters();
             unset($this->jobs[count($this->jobs) - 1]);
             unset($this->jobs_uri[count($this->jobs_uri) - 1]);
             unset($this->status[count($this->status) - 1]);
-            
+
             if (array_key_exists(0,$this->available_printers))
+            {
                self::setPrinterURI($this->available_printers[0]);
-            else {
+            }
+            else
+            {
                 trigger_error(_("getJobs: Printer URI is not set: die"),E_USER_WARNING);
                 self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
                 self::_errorLog("getJobs: Printer URI is not set, die",2);
                 return FALSE;
-                }
             }
-            
+        }
+
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
-            
+        {
+            self::setCharset();
+        }
+
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
 
         if (!isset($this->meta->username))
+        {
             self::setUserName();
+        }
 
         $this->meta->job_uri = chr(0x45) // URI
                              . self::_giveMeStringLength('job-uri')
                              . 'job-uri'
                              . self::_giveMeStringLength($job_uri)
                              . $job_uri;
-           
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x09) // Get-Job-Attributes | operation-id
                          . $this->meta->operation_id //           request-id
@@ -609,10 +692,10 @@ class PrintIPP extends BasicIPP {
                          . $this->meta->charset
                          . $this->meta->language
                          . $this->meta->job_uri
-                         . $this->meta->username
-                         ;
-       if ($subset)
-           $this->stringjob .=
+                         . $this->meta->username;
+        if ($subset)
+        {
+            $this->stringjob .=
                           chr(0x44) // keyword
                          . self::_giveMeStringLength('requested-attributes')
                          . 'requested-attributes'
@@ -632,10 +715,12 @@ class PrintIPP extends BasicIPP {
                          . self::_giveMeStringLength('')
                          . ''
                          . self::_giveMeStringLength('job-state-reason')
-                         . 'job-state-reason'
-                         ;
-        elseif($attributes_group) {
-            switch($attributes_group) {
+                         . 'job-state-reason';
+        }
+        elseif($attributes_group)
+        {
+            switch($attributes_group)
+            {
                 case 'job-template':
                     break;
                 case 'job-description':
@@ -646,127 +731,116 @@ class PrintIPP extends BasicIPP {
                     trigger_error(_('not a valid attribute group: ').$attributes_group,E_USER_NOTICE);
                     $attributes_group = '';
                     break;
-                }
+            }
             $this->stringjob .=
                           chr(0x44) // keyword
                          . self::_giveMeStringLength('requested-attributes')
                          . 'requested-attributes'
                          . self::_giveMeStringLength($attributes_group)
                          . $attributes_group;
-            }
+        }
         $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag
-                         
+
         self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
-        
+
         self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2); 
-            
+
         $this->output = $this->stringjob;
-          
+
         $post_values = array( "Content-Type"=>"application/ipp",
                               "Data"=>$this->output);
-            
+
         if (self::_sendHttp ($post_values,$this->paths['jobs']))
+        {
             if (self::_parseServerOutput())
+            {
                 self::_parseJobAttributes();
-        
+            }
+        }
+
         $this->attributes = &$this->job_attributes;
-        
-        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
-            
+
+        if (isset($this->serveroutput) && isset($this->serveroutput->status))
+        {
             $this->status = array_merge($this->status,array($this->serveroutput->status));
-            
+
             if ($this->serveroutput->status == "successfull-ok")
+            {
                 self::_errorLog(sprintf(_("getting job attributes for %s: "),$job_uri)
                             .$this->serveroutput->status,3);
+            }
             else
+            {
                  self::_errorLog(sprintf(_("getting job attributes for %s: "),$job_uri)
                                              .$this->serveroutput->status,1);
-                                             
+            }
+
             return $this->serveroutput->status;
-            }    
-            
+        }
+
         $this->status = array_merge($this->status,array("OPERATION FAILED"));
         self::_errorLog(date("Y-m-d H:i:s : ")
                         .basename($_SERVER['PHP_SELF'])
                         .sprintf(_("getting jobs attributes of %s : OPERATION FAILED"),
                                      $job_uri),3);
-            
-    return false;
-    }
-
-    // }}}
 
-    // {{{ getPrinters();
-    public function getPrinters() {
+        return false;
+    }
 
+    public function getPrinters()
+    {
         // placeholder for vendor extension operation (getAvailablePrinters for CUPS)
         $this->jobs = array_merge($this->jobs,array(''));
         $this->jobs_uri = array_merge($this->jobs_uri,array(''));
         $this->status = array_merge($this->status,array(''));    
     }
-    // }}}    
 
-/******************
-*
-* DEVELOPPEMENT FUNCTIONS
-*
-*******************/
- 
-    // {{{ generateError($error)
-    public function generateError ($error) {
-        switch ($error) {
+    public function generateError ($error)
+    {
+        switch ($error)
+        {
             case "request_body_malformed":
                 $this->error_generation->request_body_malformed = chr(0xFF);
                 break;
             default:
                 true;
                 break;
-            }
-    // }}}
+        }
 
-    // {{{ resetError ($error)
         trigger_error(sprintf(_('Setting Error %s'),$error),E_USER_NOTICE);
     }
     
-    public function resetError ($error) {
+    public function resetError ($error)
+    {
         unset ($this->error_generation->$error);
         trigger_error(sprintf(_('Reset Error %s'),$error),E_USER_NOTICE);
     }
-    // }}}
 
-/******************
-*
-* PROTECTED FUNCTIONS
-*
-*******************/
-
-// SETUP
-
-    // {{{ _setOperationId ()
-    protected function _setOperationId () {
+    // SETUP
+    protected function _setOperationId ()
+    {
             $prepend = '';
             $this->operation_id += 1;
             $this->meta->operation_id = self::_integerBuild($this->operation_id);
             self::_putDebug( "operation id is: ".$this->operation_id."\n",2);
     }
-    // }}}
     
-    // {{{ _setJobId()
-    protected function _setJobId() {
+    protected function _setJobId()
+    {
 
         $this->meta->jobid +=1;
         $prepend = '';
         $prepend_length = 4 - strlen($this->meta->jobid);
         for ($i = 0; $i < $prepend_length ; $i++ )
+        {
             $prepend .= '0';
+        }
 
     return $prepend.$this->meta->jobid;
     }
-    // }}}
     
-    // {{{ _setJobUri ($job_uri) 
-    protected function _setJobUri ($job_uri) {
-       
+    protected function _setJobUri ($job_uri)
+    {
         $this->meta->job_uri = chr(0x45) // type uri
                              . chr(0x00).chr(0x07) // name-length
                              . "job-uri"
@@ -776,441 +850,490 @@ class PrintIPP extends BasicIPP {
         
         self::_putDebug( "job-uri is: ".$job_uri."\n",2);
     }
-    // }}}
-    
-// RESPONSE PARSING
-
-    // {{{ _parsePrinterAttributes()
-    protected function _parsePrinterAttributes() {
 
+    // RESPONSE PARSING
+    protected function _parsePrinterAttributes()
+    {
         //if (!preg_match('#successful#',$this->serveroutput->status))
         //   return false;
 
         $k = -1;
+        $l = 0;
         for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
+        {
             for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
-                if (!empty($this->serveroutput->response[$i][$j]['name'])) {
+            {
+                if (!empty($this->serveroutput->response[$i][$j]['name']))
+                {
                     $k++;
                     $l = 0;
                     $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes'];
                     $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
                     $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
                     $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
-                } else {
+                }
+                else
+                {
                     $l ++;
                     $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
                     }
+            }
+        }
         $this->serveroutput->response = array();
-        
-        $this->printer_attributes = new stdClass();
-        for ($i = 0 ; $i < count($this->parsed) ; $i ++) {
+
+        $this->printer_attributes = new \stdClass();
+        for ($i = 0 ; $i < count($this->parsed) ; $i ++)
+        {
                     $name = $this->parsed[$i]['name'];
                     $php_name = str_replace('-','_',$name);
                     $type = $this->parsed[$i]['type'];
                     $range = $this->parsed[$i]['range'];
-                    $this->printer_attributes->$php_name = new stdClass();
+                    $this->printer_attributes->$php_name = new \stdClass();
                     $this->printer_attributes->$php_name->_type = $type;
                     $this->printer_attributes->$php_name->_range = $range;
-                    for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) {
+                    for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++)
+                    {
                         $value = $this->parsed[$i][$j];
                         $index = '_value'.$j;
                         $this->printer_attributes->$php_name->$index = $value;
                         }
                     }
-                    
+
         $this->parsed = array();
-                
-         
     }
-    // }}}
-
-    // {{{ _parseJobsAttributes()
-    protected function _parseJobsAttributes() {
 
+    protected function _parseJobsAttributes()
+    {
         //if ($this->serveroutput->status != "successfull-ok")
         //    return false;
-        
+
         $job = -1;
-        for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) {
+        $l = 0;
+        for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
+        {
             if ($this->serveroutput->response[$i]['attributes'] == "job-attributes")
+            {
                 $job ++;
+            }
             $k = -1; 
             for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
-                if (!empty($this->serveroutput->response[$i][$j]['name'])) {
+            {
+                if (!empty($this->serveroutput->response[$i][$j]['name']))
+                {
                     $k++;
                     $l = 0;
                     $this->parsed[$job][$k]['range'] = $this->serveroutput->response[$i]['attributes'];
                     $this->parsed[$job][$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
                     $this->parsed[$job][$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
                     $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value'];
-                } else {
+                }
+                else
+                {
                     $l ++;
                     $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value'];
-                    }
+                }
             }
-        
+        }
+
         $this->serveroutput->response = array();
-        $this->jobs_attributes = new stdClass();
-        for ($job_nbr = 0 ; $job_nbr <= $job ; $job_nbr ++) {
+        $this->jobs_attributes = new \stdClass();
+        for ($job_nbr = 0 ; $job_nbr <= $job ; $job_nbr ++)
+        {
             $job_index = "job_".$job_nbr;
-            $this->jobs_attributes->$job_index = new stdClass();
-            for ($i = 0 ; $i < count($this->parsed[$job_nbr]) ; $i ++) {
-                    $name = $this->parsed[$job_nbr][$i]['name'];
-                    $php_name = str_replace('-','_',$name);
-                    $type = $this->parsed[$job_nbr][$i]['type'];
-                    $range = $this->parsed[$job_nbr][$i]['range'];
-                    $this->jobs_attributes->$job_index->$php_name = new stdClass();
-                    $this->jobs_attributes->$job_index->$php_name->_type = $type;
-                    $this->jobs_attributes->$job_index->$php_name->_range = $range;
-                    for ($j = 0 ; $j < (count($this->parsed[$job_nbr][$i]) - 3) ; $j ++) {
-                        # This causes incorrect parsing of integer job attributes.
-                        # 2010-08-16
-                        # bpkroth
-                        #$value = self::_interpretAttribute($name,$type,$this->parsed[$job_nbr][$i][$j]);
-                        $value = $this->parsed[$job_nbr][$i][$j];
-                        $index = '_value'.$j;
-                        $this->jobs_attributes->$job_index->$php_name->$index = $value;
-                        }
-                    }
+            $this->jobs_attributes->$job_index = new \stdClass();
+            for ($i = 0 ; $i < count($this->parsed[$job_nbr]) ; $i ++)
+            {
+                $name = $this->parsed[$job_nbr][$i]['name'];
+                $php_name = str_replace('-','_',$name);
+                $type = $this->parsed[$job_nbr][$i]['type'];
+                $range = $this->parsed[$job_nbr][$i]['range'];
+                $this->jobs_attributes->$job_index->$php_name = new \stdClass();
+                $this->jobs_attributes->$job_index->$php_name->_type = $type;
+                $this->jobs_attributes->$job_index->$php_name->_range = $range;
+                for ($j = 0 ; $j < (count($this->parsed[$job_nbr][$i]) - 3) ; $j ++)
+                {
+                    # This causes incorrect parsing of integer job attributes.
+                    # 2010-08-16
+                    # bpkroth
+                    #$value = self::_interpretAttribute($name,$type,$this->parsed[$job_nbr][$i][$j]);
+                    $value = $this->parsed[$job_nbr][$i][$j];
+                    $index = '_value'.$j;
+                    $this->jobs_attributes->$job_index->$php_name->$index = $value;
+                }
             }
-            
+        }
+
         $this->parsed = array();
-                
-         
     }
-    // }}}
-    
-    // {{{ _readAttribute($attributes_type,$ji,&$collection=false)
-    protected function _readAttribute($attributes_type) {
-        
-            $tag = ord($this->serveroutput->body[$this->_parsing->offset]);
-            
-            $this->_parsing->offset += 1;
-            $j = $this->index;
-            
-            $tag = self::_readTag($tag);
-
-            switch ($tag) {
-                 case "begCollection": //RFC3382 (BLIND CODE)
-                    if ($this->end_collection)
-                        $this->index --;
-                    $this->end_collection = false;
-                    $this->serveroutput->response[$attributes_type][$j]['type'] = "collection";
-                    self::_putDebug( "tag is: begCollection\n");
-                    self::_readAttributeName ($attributes_type,$j);
-                    if (!$this->serveroutput->response[$attributes_type][$j]['name']) { // it is a multi-valued collection
-                        $this->collection_depth ++;
-                        $this->index --;
+
+    protected function _readAttribute($attributes_type)
+    {
+        $tag = ord($this->serveroutput->body[$this->_parsing->offset]);
+
+        $this->_parsing->offset += 1;
+        $j = $this->index;
+
+        $tag = self::_readTag($tag);
+
+        switch ($tag)
+        {
+            case "begCollection": //RFC3382 (BLIND CODE)
+                if ($this->end_collection)
+                {
+                    $this->index --;
+                }
+                $this->end_collection = false;
+                $this->serveroutput->response[$attributes_type][$j]['type'] = "collection";
+                self::_putDebug( "tag is: begCollection\n");
+                self::_readAttributeName ($attributes_type,$j);
+                if (!$this->serveroutput->response[$attributes_type][$j]['name'])
+                { // it is a multi-valued collection
+                    $this->collection_depth ++;
+                    $this->index --;
+                    $this->collection_nbr[$this->collection_depth] ++;
+                }
+                else
+                {
+                    $this->collection_depth ++;
+                    if ($this->collection_depth == 0)
+                    {
+                        $this->collection = (object) 'collection';
+                    }
+                    if (array_key_exists($this->collection_depth,$this->collection_nbr))
+                    {
                         $this->collection_nbr[$this->collection_depth] ++;
-                    } else {
-                        $this->collection_depth ++;
-                        if ($this->collection_depth == 0)
-                            $this->collection = (object) 'collection';
-                        if (array_key_exists($this->collection_depth,$this->collection_nbr))
-                            $this->collection_nbr[$this->collection_depth] ++;
-                        else
-                            $this->collection_nbr[$this->collection_depth] = 0;
-                        unset($this->end_collection);
-                        
-                        }
-                    self::_readValue ("begCollection",$attributes_type,$j);
-                    break;
-                 case "endCollection": //RFC3382 (BLIND CODE)
-                    $this->serveroutput->response[$attributes_type][$j]['type'] = "collection";
-                    self::_putDebug( "tag is: endCollection\n");
-                    self::_readAttributeName ($attributes_type,$j,0);
-                    self::_readValue ('name',$attributes_type,$j,0);
-                    $this->collection_depth --;
-                    $this->collection_key[$this->collection_depth] = 0;
-                    $this->end_collection = true;
-                    break;
-                 case "memberAttrName": // RFC3382 (BLIND CODE)
-                    $this->serveroutput->response[$attributes_type][$j]['type'] = "memberAttrName";
-                    $this->index -- ;
-                    self::_putDebug( "tag is: memberAttrName\n");
-                    self::_readCollection ($attributes_type,$j);
-                    break;
- 
-                default:
-                    $this->collection_depth = -1;
-                    $this->collection_key = array();
-                    $this->collection_nbr = array();
-                    $this->serveroutput->response[$attributes_type][$j]['type'] = $tag;
-                    self::_putDebug( "tag is: $tag\n");
-                    $attribute_name = self::_readAttributeName ($attributes_type,$j);
-                    if (!$attribute_name)
-                        $attribute_name = $this->attribute_name;
+                    }
                     else
-                        $this->attribute_name = $attribute_name;
-                    $value = self::_readValue ($tag,$attributes_type,$j);
-                    $this->serveroutput->response[$attributes_type][$j]['value'] = 
-                        self::_interpretAttribute($attribute_name,$tag,$this->serveroutput->response[$attributes_type][$j]['value']);
-                    break;
-                
-            }
-    return;
-    }
-    // }}}
+                    {
+                        $this->collection_nbr[$this->collection_depth] = 0;
+                    }
+                    unset($this->end_collection);
+                }
+                self::_readValue ("begCollection",$attributes_type,$j);
+                break;
+            case "endCollection": //RFC3382 (BLIND CODE)
+                $this->serveroutput->response[$attributes_type][$j]['type'] = "collection";
+                self::_putDebug( "tag is: endCollection\n");
+                self::_readAttributeName ($attributes_type,$j,0);
+                self::_readValue ('name',$attributes_type,$j,0);
+                $this->collection_depth --;
+                $this->collection_key[$this->collection_depth] = 0;
+                $this->end_collection = true;
+                break;
+            case "memberAttrName": // RFC3382 (BLIND CODE)
+                $this->serveroutput->response[$attributes_type][$j]['type'] = "memberAttrName";
+                $this->index -- ;
+                self::_putDebug( "tag is: memberAttrName\n");
+                self::_readCollection ($attributes_type,$j);
+                break;
 
-    // {{{  _readTag($tag)
-    protected function _readTag($tag) {
+            default:
+                $this->collection_depth = -1;
+                $this->collection_key = array();
+                $this->collection_nbr = array();
+                $this->serveroutput->response[$attributes_type][$j]['type'] = $tag;
+                self::_putDebug( "tag is: $tag\n");
+                $attribute_name = self::_readAttributeName ($attributes_type,$j);
+                if (!$attribute_name)
+                {
+                    $attribute_name = $this->attribute_name;
+                }
+                else
+                {
+                    $this->attribute_name = $attribute_name;
+                }
+                $value = self::_readValue ($tag,$attributes_type,$j);
+                $this->serveroutput->response[$attributes_type][$j]['value'] = 
+                self::_interpretAttribute($attribute_name,$tag,$this->serveroutput->response[$attributes_type][$j]['value']);
+                break;
+        }
+        return;
+    }
 
-            switch ($tag) {
-                case 0x10:
-                    $tag = "unsupported";
-                    break;
-                case 0x11:
-                    $tag = "reserved for 'default'";
-                    break;
-                case 0x12:
-                    $tag = "unknown";
-                    break;
-                case 0x13:
-                    $tag = "no-value";
-                    break;
-                case 0x15: // RFC 3380
-                    $tag = "not-settable";
-                    break;
-                case 0x16: // RFC 3380
-                    $tag = "delete-attribute";
-                    break;
-                case 0x17: // RFC 3380
-                    $tag = "admin-define";
-                    break;
-                case 0x20:
-                    $tag = "IETF reserved (generic integer)";
-                    break;
-                case 0x21:
-                    $tag = "integer";
-                    break;
-                case 0x22:
-                    $tag = "boolean";
-                    break;
-                case 0x23:
-                    $tag = "enum";
-                    break;
-                case 0x30:
-                    $tag = "octetString";
-                    break;
-                case 0x31:
-                    $tag = "datetime";
-                    break;
-                 case 0x32:
-                    $tag = "resolution";
-                    break;
-                 case 0x33:
-                    $tag = "rangeOfInteger";
-                    break;
-                 case 0x34: //RFC3382 (BLIND CODE)
-                    $tag = "begCollection";
-                    break;
-                 case 0x35:
-                    $tag = "textWithLanguage";
-                    break;
-                 case 0x36:
-                    $tag = "nameWithLanguage";
-                    break;
-                 case 0x37: //RFC3382 (BLIND CODE)
-                    $tag = "endCollection";
-                    break;
-                 case 0x40:
-                    $tag = "IETF reserved text string";
-                    break;
-                 case 0x41:
-                    $tag = "textWithoutLanguage";
-                    break;
-                 case 0x42:
-                    $tag = "nameWithoutLanguage";
-                    break;
-                 case 0x43:
+    protected function _readTag($tag)
+    {
+        switch ($tag)
+        {
+            case 0x10:
+                $tag = "unsupported";
+                break;
+            case 0x11:
+                $tag = "reserved for 'default'";
+                break;
+            case 0x12:
+                $tag = "unknown";
+                break;
+            case 0x13:
+                $tag = "no-value";
+                break;
+            case 0x15: // RFC 3380
+                $tag = "not-settable";
+                break;
+            case 0x16: // RFC 3380
+                $tag = "delete-attribute";
+                break;
+            case 0x17: // RFC 3380
+                $tag = "admin-define";
+                break;
+            case 0x20:
+                $tag = "IETF reserved (generic integer)";
+                break;
+            case 0x21:
+                $tag = "integer";
+                break;
+            case 0x22:
+                $tag = "boolean";
+                break;
+            case 0x23:
+                $tag = "enum";
+                break;
+            case 0x30:
+                $tag = "octetString";
+                break;
+            case 0x31:
+                $tag = "datetime";
+                break;
+            case 0x32:
+                $tag = "resolution";
+                break;
+            case 0x33:
+                $tag = "rangeOfInteger";
+                break;
+            case 0x34: //RFC3382 (BLIND CODE)
+                $tag = "begCollection";
+                break;
+            case 0x35:
+                $tag = "textWithLanguage";
+                break;
+            case 0x36:
+                $tag = "nameWithLanguage";
+                break;
+            case 0x37: //RFC3382 (BLIND CODE)
+                $tag = "endCollection";
+                break;
+            case 0x40:
+                $tag = "IETF reserved text string";
+                break;
+            case 0x41:
+                $tag = "textWithoutLanguage";
+                break;
+            case 0x42:
+                $tag = "nameWithoutLanguage";
+                break;
+            case 0x43:
+                $tag = "IETF reserved for future";
+                break;
+            case 0x44:
+                $tag = "keyword";
+                break;
+            case 0x45:
+                $tag = "uri";
+                break;
+            case 0x46:
+                $tag = "uriScheme";
+                break;
+            case 0x47:
+                $tag = "charset";
+                break;
+            case 0x48:
+                $tag = "naturalLanguage";
+                break;
+            case 0x49:
+                $tag = "mimeMediaType";
+                break;
+            case 0x4A: // RFC3382 (BLIND CODE)
+                $tag = "memberAttrName";
+                break;
+            case 0x7F:
+                $tag = "extended type";
+                break;
+            default:
+                if ($tag >= 0x14 && $tag < 0x15 && $tag > 0x17 && $tag <= 0x1f) 
+                {
+                    $tag = "out-of-band";
+                }
+                elseif (0x24 <= $tag && $tag <= 0x2f) 
+                {
+                    $tag = "new integer type";
+                }
+                elseif (0x38 <= $tag && $tag <= 0x3F) 
+                {
+                    $tag = "new octet-stream type";
+                }
+                elseif (0x4B <= $tag && $tag <= 0x5F) 
+                {
+                    $tag = "new character string type";
+                }
+                elseif ((0x60 <= $tag && $tag < 0x7f) || $tag >= 0x80 )
+                {
                     $tag = "IETF reserved for future";
-                    break;
-                 case 0x44:
-                    $tag = "keyword";
-                    break;
-                 case 0x45:
-                    $tag = "uri";
-                    break;
-                 case 0x46:
-                    $tag = "uriScheme";
-                    break;
-                 case 0x47:
-                    $tag = "charset";
-                    break;
-                 case 0x48:
-                    $tag = "naturalLanguage";
-                    break;
-                 case 0x49:
-                    $tag = "mimeMediaType";
-                    break;
-                 case 0x4A: // RFC3382 (BLIND CODE)
-                    $tag = "memberAttrName";
-                    break;
-                  case 0x7F:
-                    $tag = "extended type";
-                    break;
-                 default:
-                 
-                    if ($tag >= 0x14 && $tag < 0x15 && $tag > 0x17 && $tag <= 0x1f) 
-                        $tag = "out-of-band";
-                    elseif (0x24 <= $tag && $tag <= 0x2f) 
-                        $tag = "new integer type";
-                    elseif (0x38 <= $tag && $tag <= 0x3F) 
-                        $tag = "new octet-stream type";
-                    elseif (0x4B <= $tag && $tag <= 0x5F) 
-                        $tag = "new character string type";
-                    elseif ((0x60 <= $tag && $tag < 0x7f) || $tag >= 0x80 )
-                        $tag = "IETF reserved for future";
-                    else
-                        $tag = sprintf("UNKNOWN: 0x%x (%u)",$tag,$tag);
-                        
-                    break;                                                            
                 }
-    return $tag; 
+                else
+                {
+                    $tag = sprintf("UNKNOWN: 0x%x (%u)",$tag,$tag);
+                }
+                break;                                                            
+        }
+
+        return $tag; 
     }
-    // }}}
 
-    // {{{ _readCollection($attributes_type,$j,&$collection)
-    protected function _readCollection($attributes_type,$j) {
-       
+    protected function _readCollection($attributes_type,$j)
+    {
         $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) *  256
                      +  ord($this->serveroutput->body[$this->_parsing->offset + 1]);
-        
+
         $this->_parsing->offset += 2;
-        
+
         self::_putDebug( "Collection name_length ". $name_length ."\n");
-        
+
         $name = '';
-        for ($i = 0; $i < $name_length; $i++) {
+        for ($i = 0; $i < $name_length; $i++)
+        {
             $name .= $this->serveroutput->body[$this->_parsing->offset];
             $this->_parsing->offset += 1;
             if ($this->_parsing->offset > strlen($this->serveroutput->body))
+            {
                 return;
             }
-        
+        }
+
         $collection_name = $name;
-        
+
         $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) *  256
                      +  ord($this->serveroutput->body[$this->_parsing->offset + 1]);
         $this->_parsing->offset += 2;
-        
+
         self::_putDebug( "Attribute name_length ". $name_length ."\n");
-        
+
         $name = '';
-        for ($i = 0; $i < $name_length; $i++) {
+        for ($i = 0; $i < $name_length; $i++)
+        {
             $name .= $this->serveroutput->body[$this->_parsing->offset];
             $this->_parsing->offset += 1;
             if ($this->_parsing->offset > strlen($this->serveroutput->body))
+            {
                 return;
             }
-        
+        }
+
         $attribute_name = $name;
-        if ($attribute_name == "") {
+        if ($attribute_name == "")
+        {
             $attribute_name = $this->last_attribute_name;
             $this->collection_key[$this->collection_depth] ++;
-        } else {
+        }
+        else
+        {
             $this->collection_key[$this->collection_depth] = 0;
         }
         $this->last_attribute_name = $attribute_name;
-        
+
         self::_putDebug( "Attribute name ".$name."\n");
-        
+
         $tag = self::_readTag(ord($this->serveroutput->body[$this->_parsing->offset]));
         $this->_parsing->offset ++;
-        
+
         $type = $tag;
-        
+
         $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) *  256
                      +  ord($this->serveroutput->body[$this->_parsing->offset + 1]);
         $this->_parsing->offset += 2;
-        
+
         self::_putDebug( "Collection2 name_length ". $name_length ."\n");
-        
+
         $name = '';
-        for ($i = 0; $i < $name_length; $i++) {
+        for ($i = 0; $i < $name_length; $i++)
+        {
             $name .= $this->serveroutput->body[$this->_parsing->offset];
             $this->_parsing->offset += 1;
             if ($this->_parsing->offset > strlen($this->serveroutput->body))
+            {
                 return;
             }
-        
+        }
+
         $collection_value = $name;
         $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) *  256
                       +  ord($this->serveroutput->body[$this->_parsing->offset + 1]);
-        
+
         self::_putDebug( "Collection value_length ".$this->serveroutput->body[ $this->_parsing->offset]
                                        . $this->serveroutput->body[$this->_parsing->offset + 1]
                                        .": "
                                        . $value_length
                                        . " ");
-        
+
         $this->_parsing->offset += 2;
-        
+
         $value = '';
-        for ($i = 0; $i < $value_length; $i++) {
-            
+        for ($i = 0; $i < $value_length; $i++)
+        {
             if ($this->_parsing->offset >= strlen($this->serveroutput->body))
+            {
                 return;
+            }
             $value .= $this->serveroutput->body[$this->_parsing->offset];
             $this->_parsing->offset += 1;
-            
-            }
-        
+        }
+
         $object = &$this->collection;
-        for ($i = 0 ; $i <= $this->collection_depth ; $i ++) {
+        for ($i = 0 ; $i <= $this->collection_depth ; $i ++)
+        {
             $indice = "_indice".$this->collection_nbr[$i];
             if (!isset($object->$indice))
+            {
                 $object->$indice = (object) 'indice';
-            $object = &$object->$indice;
             }
-         
+            $object = &$object->$indice;
+        }
+
         $value_key = "_value".$this->collection_key[$this->collection_depth];
         $col_name_key = "_collection_name".$this->collection_key[$this->collection_depth];
         $col_val_key = "_collection_value".$this->collection_key[$this->collection_depth];
-        
+
         $attribute_value = self::_interpretAttribute($attribute_name,$tag,$value);
         $attribute_name = str_replace('-','_',$attribute_name);
-        
-        
+
         self::_putDebug( sprintf("Value: %s\n",$value));
         $object->$attribute_name->_type = $type;
         $object->$attribute_name->$value_key = $attribute_value;
         $object->$attribute_name->$col_name_key = $collection_name;
         $object->$attribute_name->$col_val_key = $collection_value;
-        
-    $this->serveroutput->response[$attributes_type][$j]['value'] = $this->collection;
+
+        $this->serveroutput->response[$attributes_type][$j]['value'] = $this->collection;
     }
-    // }}}
-    
-    // {{{ _readAttributeName ($attributes_type,$j)
-    protected function _readAttributeName ($attributes_type,$j,$write=1) {
 
+    protected function _readAttributeName ($attributes_type,$j,$write=1)
+    {
         $name_length = ord($this->serveroutput->body[ $this->_parsing->offset]) *  256
                      +  ord($this->serveroutput->body[$this->_parsing->offset + 1]);
         $this->_parsing->offset += 2;
-        
+
         self::_putDebug( "name_length ". $name_length ."\n");
-        
+
         $name = '';
-        for ($i = 0; $i < $name_length; $i++) {
+        for ($i = 0; $i < $name_length; $i++)
+        {
             if ($this->_parsing->offset >= strlen($this->serveroutput->body))
+            {
                 return;
+            }
             $name .= $this->serveroutput->body[$this->_parsing->offset];
             $this->_parsing->offset += 1;
-            }
-        
+        }
+
         if($write)
-        $this->serveroutput->response[$attributes_type][$j]['name'] = $name;
+        {
+            $this->serveroutput->response[$attributes_type][$j]['name'] = $name;
+        }
 
         self::_putDebug( "name " . $name . "\n");
-    
-    return $name;   
-    }
-    // }}}
 
-    // {{{ _readValue ($type,$attributes_type,$j)
-    protected function _readValue ($type,$attributes_type,$j,$write=1) {
+        return $name;   
+    }
 
+    protected function _readValue ($type,$attributes_type,$j,$write=1)
+    {
         $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) *  256
                       +  ord($this->serveroutput->body[$this->_parsing->offset + 1]);
         
@@ -1219,116 +1342,130 @@ class PrintIPP extends BasicIPP {
                                        .": "
                                        . $value_length
                                        . " ");
-        
+
         $this->_parsing->offset += 2;
-        
+
         $value = '';
-        for ($i = 0; $i < $value_length; $i++) {
-            
+        for ($i = 0; $i < $value_length; $i++)
+        {
             if ($this->_parsing->offset >= strlen($this->serveroutput->body))
+            {
                 return;
+            }
             $value .= $this->serveroutput->body[$this->_parsing->offset];
             $this->_parsing->offset += 1;
-            
             }
-            
+
         self::_putDebug( sprintf("Value: %s\n",$value));
-        
+
         if ($write)
-        $this->serveroutput->response[$attributes_type][$j]['value'] = $value;
+        {
+            $this->serveroutput->response[$attributes_type][$j]['value'] = $value;
+        }
 
-    return $value;
+        return $value;
     }
-    // }}}
 
-    // {{{ _parseAttributes()
-    protected function _parseAttributes() {
- 
+    protected function _parseAttributes()
+    {
         $k = -1;
+        $l = 0;
         for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
+        {
             for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
-                if (!empty($this->serveroutput->response[$i][$j]['name'])) {
+            {
+                if (!empty($this->serveroutput->response[$i][$j]['name']))
+                {
                     $k++;
                     $l = 0;
                     $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes'];
                     $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
                     $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
                     $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
-                } else {
+                }
+                else
+                {
                     $l ++;
                     $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
-                    }
+                }
+            }
+        }
         $this->serveroutput->response = array();
-        $this->attributes  = new stdClass();
-        for ($i = 0 ; $i < count($this->parsed) ; $i ++) {
+        $this->attributes  = new \stdClass();
+        for ($i = 0 ; $i < count($this->parsed) ; $i ++)
+        {
                     $name = $this->parsed[$i]['name'];
                     $php_name = str_replace('-','_',$name);
                     $type = $this->parsed[$i]['type'];
                     $range = $this->parsed[$i]['range'];
-                    $this->attributes->$php_name = new stdClass();
+                    $this->attributes->$php_name = new \stdClass();
                     $this->attributes->$php_name->_type = $type;
                     $this->attributes->$php_name->_range = $range;
-                    for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) {
+                    for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++)
+                    {
                         $value = $this->parsed[$i][$j];
                         $index = '_value'.$j;
                         $this->attributes->$php_name->$index = $value;
                         }
                     }
-                    
+
         $this->parsed = array();
-    
     }
-    // }}}
-
-    // {{{ _parseJobAttributes()
-    protected function _parseJobAttributes() {
 
+    protected function _parseJobAttributes()
+    {
         //if (!preg_match('#successful#',$this->serveroutput->status))
         //    return false;
-        
         $k = -1;
+        $l = 0;
         for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
+        {
             for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
-                if (!empty($this->serveroutput->response[$i][$j]['name'])) {
+            {
+                if (!empty($this->serveroutput->response[$i][$j]['name']))
+                {
                     $k++;
                     $l = 0;
                     $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes'];
                     $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
                     $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
                     $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
-                } else {
+                }
+                else
+                {
                     $l ++;
                     $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
-                    }
-        
+                }
+            }
+        }
+
         $this->serveroutput->response = array();
-        
-        $this->job_attributes = new stdClass();
-        for ($i = 0 ; $i < count($this->parsed) ; $i ++) {
+
+        $this->job_attributes = new \stdClass();
+        for ($i = 0 ; $i < count($this->parsed) ; $i ++)
+        {
                     $name = $this->parsed[$i]['name'];
                     $php_name = str_replace('-','_',$name);
                     $type = $this->parsed[$i]['type'];
                     $range = $this->parsed[$i]['range'];
-                    $this->job_attributes->$php_name = new stdClass();
+                    $this->job_attributes->$php_name = new \stdClass();
                     $this->job_attributes->$php_name->_type = $type;
                     $this->job_attributes->$php_name->_range = $range;
-                    for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) {
+                    for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++)
+                    {
                         $value = $this->parsed[$i][$j];
                         $index = '_value'.$j;
                         $this->job_attributes->$php_name->$index = $value;
                         }
                     }
-                    
+
         $this->parsed = array();
-                
-         
     }
-    // }}}
 
-    // {{{ _interpretAttribute($attribute_name,$type,$value)
-    protected function _interpretAttribute($attribute_name,$type,$value) {
-        
-        switch ($type) {
+    protected function _interpretAttribute($attribute_name,$type,$value)
+    {
+        switch ($type)
+        {
             case "integer":
                 $value = self::_interpretInteger($value);
                 break;
@@ -1338,9 +1475,13 @@ class PrintIPP extends BasicIPP {
             case 'boolean':
                 $value = ord($value);
                 if ($value == 0x00)
+                {
                     $value = 'false';
+                }
                 else
+                {
                     $value = 'true';
+                }
                 break;
             case 'datetime':
                 $value = self::_interpretDateTime($value);
@@ -1351,7 +1492,8 @@ class PrintIPP extends BasicIPP {
             case 'resolution':
                 $unit = $value[8];
                 $value = self::_interpretRangeOfInteger(substr($value,0,8));
-                switch($unit) {
+                switch($unit)
+                {
                     case chr(0x03):
                         $unit = "dpi";
                         break;
@@ -1363,31 +1505,27 @@ class PrintIPP extends BasicIPP {
                 break;
             default:
                 break;
-                }
-    return $value;
+        }
+        return $value;
     }
-    // }}}
-    
-    // {{{ _interpretRangeOfInteger($value)
-    protected function _interpretRangeOfInteger($value) {
-        
+
+    protected function _interpretRangeOfInteger($value)
+    {
         $value_parsed = 0;
         $integer1 = $integer2 = 0;
-        
+
         $halfsize = strlen($value) / 2;
-       
+
         $integer1 = self::_interpretInteger(substr($value,0,$halfsize));
         $integer2 = self::_interpretInteger(substr($value,$halfsize,$halfsize));
-         
+
         $value_parsed = sprintf('%s-%s',$integer1,$integer2);
-        
-        
-    return $value_parsed;
+
+        return $value_parsed;
     }
-    // }}}
- 
-    // {{{ _interpretDateTime($date) {
-    protected function _interpretDateTime($date) {
+
+    protected function _interpretDateTime($date)
+    {
         $year = self::_interpretInteger(substr($date,0,2));
         $month =  self::_interpretInteger(substr($date,2,1));
         $day =  self::_interpretInteger(substr($date,3,1));
@@ -1397,21 +1535,21 @@ class PrintIPP extends BasicIPP {
         $direction = substr($date,8,1);
         $hours_from_utc = self::_interpretInteger(substr($date,9,1));
         $minutes_from_utc = self::_interpretInteger(substr($date,10,1));
-        
+
         $date = sprintf('%s-%s-%s %s:%s:%s %s%s:%s',$year,$month,$day,$hour,$minute,$second,$direction,$hours_from_utc,$minutes_from_utc);
 
-    return $date;
-    }   
-    // }}}
-    
-    // {{{ _interpretEnum()
-    protected function _interpretEnum($attribute_name,$value) {
-        
+        return $date;
+    }
+
+    protected function _interpretEnum($attribute_name,$value)
+    {
         $value_parsed = self::_interpretInteger($value);
-        
-        switch ($attribute_name) {
+
+        switch ($attribute_name)
+        {
             case 'job-state':
-                switch ($value_parsed) {
+                switch ($value_parsed)
+                {
                     case 0x03:
                         $value = 'pending';
                         break;
@@ -1433,14 +1571,17 @@ class PrintIPP extends BasicIPP {
                     case 0x09:
                         $value = 'completed';
                         break;
-                    }
+                }
                 if ($value_parsed > 0x09)
+                {
                     $value = sprintf('Unknown(IETF standards track "job-state" reserved): 0x%x',$value_parsed);
+                }
                 break;
             case 'print-quality':
             case 'print-quality-supported':
             case 'print-quality-default':
-                switch ($value_parsed) {
+                switch ($value_parsed)
+                {
                     case 0x03:
                         $value = 'draft';
                         break;
@@ -1453,7 +1594,8 @@ class PrintIPP extends BasicIPP {
                     }
                 break;
             case 'printer-state':
-                switch ($value_parsed) {
+                switch ($value_parsed)
+                {
                     case 0x03:
                         $value = 'idle';
                         break;
@@ -1463,13 +1605,16 @@ class PrintIPP extends BasicIPP {
                     case 0x05:
                         $value = 'stopped';
                         break;
-                    }
+                }
                 if ($value_parsed > 0x05)
+                {
                     $value = sprintf('Unknown(IETF standards track "printer-state" reserved): 0x%x',$value_parsed);
+                }
                 break;
-            
+
             case 'operations-supported':
-                switch($value_parsed) {
+                switch($value_parsed)
+                {
                     case 0x0000:
                     case 0x0001:
                         $value = sprintf('Unknown(reserved) : %s',ord($value));
@@ -1602,20 +1747,31 @@ class PrintIPP extends BasicIPP {
                         break;
                 }
                 if ($value_parsed > 0x002B && $value_parsed <= 0x3FFF)
+                {
                     $value = sprintf('Unknown(IETF standards track operations reserved): 0x%x',$value_parsed);
-                elseif ($value_parsed >= 0x4000 && $value_parsed <= 0x8FFF) {
-                    if (method_exists($this,'_getEnumVendorExtensions')) {
+                }
+                elseif ($value_parsed >= 0x4000 && $value_parsed <= 0x8FFF)
+                {
+                    if (method_exists($this,'_getEnumVendorExtensions'))
+                    {
                         $value = $this->_getEnumVendorExtensions($value_parsed);
-                    } else
+                    }
+                    else
+                    {
                         $value = sprintf('Unknown(Vendor extension for operations): 0x%x',$value_parsed);
-                } elseif ($value_parsed > 0x8FFF)
+                    }
+                }
+                elseif ($value_parsed > 0x8FFF)
+                {
                     $value = sprintf('Unknown operation (should not exists): 0x%x',$value_parsed);
-                
+                }
+
                 break;
             case 'finishings':
             case 'finishings-default':
             case 'finishings-supported':
-                switch ($value_parsed) {
+                switch ($value_parsed)
+                {
                     case 3:
                         $value = 'none';
                         break;
@@ -1673,15 +1829,18 @@ class PrintIPP extends BasicIPP {
                     case 31:
                         $value = 'staple-dual-bottom';
                         break;
-                    }
+                }
                 if ($value_parsed > 31)
+                {
                     $value = sprintf('Unknown(IETF standards track "finishing" reserved): 0x%x',$value_parsed);
+                }
                 break;
-            
+
             case 'orientation-requested':
             case 'orientation-requested-supported':
             case 'orientation-requested-default':
-                switch ($value_parsed) {
+                switch ($value_parsed)
+                {
                     case 0x03:
                         $value = 'portrait';
                         break;
@@ -1694,77 +1853,87 @@ class PrintIPP extends BasicIPP {
                     case 0x06:
                         $value = 'reverse-portrait';
                         break;
-                    }
+                }
                 if ($value_parsed > 0x06)
+                {
                     $value = sprintf('Unknown(IETF standards track "orientation" reserved): 0x%x',$value_parsed);
+                }
                 break;
-                
+
             default:
                 break;
-            }
-    return $value;
+        }
+        return $value;
     }
-    // }}}
- 
-    // {{{ _getJobId ()
-    protected function _getJobId () {
-        
+
+    protected function _getJobId ()
+    {
         if (!isset($this->serveroutput->response))
+        {
             $this->jobs = array_merge($this->jobs,array('NO JOB'));
-        
+        }
+
         $jobfinded = false;
         for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++)
+        {
             if (($this->serveroutput->response[$i]['attributes']) == "job-attributes")
+            {
                 for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++)
-                    if ($this->serveroutput->response[$i][$j]['name'] == "job-id") {
+                {
+                    if ($this->serveroutput->response[$i][$j]['name'] == "job-id")
+                    {
                         $this->last_job = $this->serveroutput->response[$i][$j]['value'];
                         $this->jobs = array_merge($this->jobs,array($this->serveroutput->response[$i][$j]['value']));
                         return;
-                        
-                        }
-                        
+                    }
+                }
+            }
+        }
     }
-    // }}}
- 
-    // {{{ _getJobUri ()
-    protected function _getJobUri () {
 
+    protected function _getJobUri ()
+    {
         if (!isset($this->jobs_uri))
+        {
             $this->jobs_uri = array();
-            
+        }
+
         $jobfinded = false;
         for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++)
+        {
             if (($this->serveroutput->response[$i]['attributes']) == "job-attributes")
+            {
                 for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++)
-                    if ($this->serveroutput->response[$i][$j]['name'] == "job-uri") {
+                {
+                    if ($this->serveroutput->response[$i][$j]['name'] == "job-uri")
+                    {
                         $this->last_job = $this->serveroutput->response[$i][$j]['value'];
                         $this->jobs_uri = array_merge($this->jobs_uri,array($this->last_job));
                         return;
-                        
-                        }
+                    }
+                }
+            }
+        }
         $this->last_job = '';
-        
     }
-    // }}}
- 
-   // {{{ _parseResponse ()
-   protected function _parseResponse () {
+
+    protected function _parseResponse ()
+   {
         $j = -1;
         $this->index = 0;
-        for ($i = $this->_parsing->offset; $i < strlen($this->serveroutput->body) ; $i = $this->_parsing->offset) {
-        
-        
+        for ($i = $this->_parsing->offset; $i < strlen($this->serveroutput->body) ; $i = $this->_parsing->offset)
+        {
             $tag = ord($this->serveroutput->body[$this->_parsing->offset]);
-            
-            
-            if ($tag > 0x0F) {
-                
+
+            if ($tag > 0x0F)
+            {
                 self::_readAttribute($j);
                 $this->index ++;
                 continue;
-                }
+            }
 
-            switch ($tag) {
+            switch ($tag)
+            {
                 case 0x01:
                     $j += 1;
                     $this->serveroutput->response[$j]['attributes'] = "operation-attributes";
@@ -1782,7 +1951,9 @@ class PrintIPP extends BasicIPP {
                     $this->serveroutput->response[$j]['attributes'] = "end-of-attributes";
                     self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n");
                     if ($this->alert_on_end_tag === 1)
+                    {
                         echo "END tag OK<br />";
+                    }
                     $this->response_completed[(count($this->response_completed) -1)] = "completed";
                     return;
                 case 0x04:
@@ -1803,21 +1974,16 @@ class PrintIPP extends BasicIPP {
                     $this->index = 0;
                     $this->_parsing->offset += 1;
                     break;
-                }
-        
-         self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n\n\n");
-    
-        }  
-    return;        
-    }
-    // }}}
-
-   
+            }
 
+            self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n\n\n");
+        }
+        return;
+    }
 
     /*
     // NOTICE : HAVE TO READ AGAIN RFC 2911 TO SEE IF IT IS PART OF SERVER'S RESPONSE (CUPS DO NOT)
-    // {{{ _getPrinterUri ()
+
     protected function _getPrinterUri () {
 
         for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++)
@@ -1833,32 +1999,43 @@ class PrintIPP extends BasicIPP {
         $this->printers_uri = array_merge($this->printers_uri,array(''));
  
     }
-    // }}}
+
     */
 
-// REQUEST BUILDING
-   
-    // {{{ _stringCancel ()
-    protected function _stringCancel ($job_uri) {
+    // REQUEST BUILDING
+    protected function _stringCancel ($job_uri)
+    {
     
         if (!isset($this->setup->charset))
-            self::setCharset('us-ascii');
+        {
+            self::setCharset();
+        }
         if (!isset($this->setup->datatype))
+        {
             self::setBinary();
+        }
         if (!isset($this->setup->language))
+        {
             self::setLanguage('en_us');
+        }
         if (!$this->requesting_user)   
+        {
             self::setUserName();
+        }
         if (!isset($this->meta->message))
+        {
             $this->meta->message = '';
+        }
 
         self::_setOperationId();
-     
+
         self::_setJobUri($job_uri);
-        
+
         if (!isset($this->error_generation->request_body_malformed))
+        {
             $this->error_generation->request_body_malformed = "";
-       
+        }
+
         $this->stringjob = chr(0x01) . chr(0x01) // 1.1  | version-number
                          . chr(0x00) . chr (0x08) // cancel-Job | operation-id
                          . $this->meta->operation_id //           request-id
@@ -1874,16 +2051,4 @@ class PrintIPP extends BasicIPP {
         self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
         return TRUE;
     }
-    // }}}
-
-
-};
-
-/*
- * Local variables:
- * mode: php
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- */
-?>
+}
diff --git a/htdocs/includes/printipp/http_class.php b/htdocs/includes/printipp/http_class.php
index 569d4f6648ff9c938bb3959dcaeb2d9ff34d7849..30bb33d663babb791410d142bc1288e9ce087f34 100644
--- a/htdocs/includes/printipp/http_class.php
+++ b/htdocs/includes/printipp/http_class.php
@@ -29,7 +29,7 @@
  */
 /**
  *  This class is intended to implement a subset of Hyper Text Transfer Protocol
- *  (HTTP/1.1) on client side  (currently: POST operation), with file streaming
+ *  (HTTP/1.1) on client side  (currently: POST operation), with file streaming
  *  capability.
  *  
  *  It can perform Basic and Digest authentication.
@@ -66,48 +66,58 @@
  ************************/
 class httpException extends Exception
 {
- protected $errno;
- public function __construct ($msg, $errno = null)
- {
-  parent::__construct ($msg);
-  $this->errno = $errno;
- }
- public function getErrorFormatted ()
- {
-  return sprintf ("[http_class]: %s -- "._(" file %s, line %s"),
-    $this->getMessage (), $this->getFile (), $this->getLine ());
- }
- public function getErrno ()
- {
-  return $this->errno;
- }
+    protected $errno;
+
+    public function __construct ($msg, $errno = null)
+    {
+        parent::__construct ($msg);
+        $this->errno = $errno;
+    }
+
+    public function getErrorFormatted ()
+    {
+        return sprintf ("[http_class]: %s -- "._(" file %s, line %s"),
+            $this->getMessage (), $this->getFile (), $this->getLine ());
+    }
+
+    public function getErrno ()
+    {
+        return $this->errno;
+    }
 }
 
 function error2string($value)
 {
- $level_names = array(
-   E_ERROR => 'E_ERROR',
-   E_WARNING => 'E_WARNING',
-   E_PARSE => 'E_PARSE',
-   E_NOTICE => 'E_NOTICE',
-   E_CORE_ERROR => 'E_CORE_ERROR',
-   E_CORE_WARNING => 'E_CORE_WARNING',
-   E_COMPILE_ERROR => 'E_COMPILE_ERROR',
-   E_COMPILE_WARNING => 'E_COMPILE_WARNING',
-   E_USER_ERROR => 'E_USER_ERROR',
-   E_USER_WARNING => 'E_USER_WARNING',
-   E_USER_NOTICE => 'E_USER_NOTICE'
-   );
- if(defined('E_STRICT')) $level_names[E_STRICT]='E_STRICT';
- $levels=array();
- if(($value&E_ALL)==E_ALL)
- {
-  $levels[]='E_ALL';
-  $value&=~E_ALL;
- }
- foreach($level_names as $level=>$name)
-  if(($value&$level)==$level) $levels[]=$name;
- return implode(' | ',$levels);
+    $level_names = array(
+        E_ERROR => 'E_ERROR',
+        E_WARNING => 'E_WARNING',
+        E_PARSE => 'E_PARSE',
+        E_NOTICE => 'E_NOTICE',
+        E_CORE_ERROR => 'E_CORE_ERROR',
+        E_CORE_WARNING => 'E_CORE_WARNING',
+        E_COMPILE_ERROR => 'E_COMPILE_ERROR',
+        E_COMPILE_WARNING => 'E_COMPILE_WARNING',
+        E_USER_ERROR => 'E_USER_ERROR',
+        E_USER_WARNING => 'E_USER_WARNING',
+        E_USER_NOTICE => 'E_USER_NOTICE'
+    );
+    if(defined('E_STRICT')) {
+        $level_names[E_STRICT]='E_STRICT';
+    }
+    $levels=array();
+    if(($value&E_ALL)==E_ALL)
+    {
+        $levels[]='E_ALL';
+        $value&=~E_ALL;
+    }
+    foreach($level_names as $level=>$name)
+    {
+        if(($value&$level)==$level)
+        {
+            $levels[]=$name;
+        }
+    }
+    return implode(' | ',$levels);
 }
 
 /***********************
@@ -117,499 +127,486 @@ function error2string($value)
  ************************/
 class http_class
 {
- // variables declaration
- public $debug;
- public $html_debug;
- public $timeout = 30;  // time waiting for connection, seconds
- public $data_timeout = 30; // time waiting for data, milliseconds
- public $data_chunk_timeout = 1; // time waiting between data chunks, millisecond
- public $force_multipart_form_post;
- public $username;
- public $password;
- public $request_headers = array ();
- public $request_body = "Not a useful information";
- public $status;
- public $window_size = 1024; // chunk size of data
- public $with_exceptions = 0; // compatibility mode for old scripts
- public $port;
- public $host;
- private $default_port = 631;
- private $headers;
- private $reply_headers = array ();
- private $reply_body = array ();
- private $connection;
- private $arguments;
- private $bodystream = array ();
- private $last_limit;
- private $connected;
- private $nc = 1;
- private $user_agent = "PRINTIPP/0.81+CVS";
- private $readed_bytes = 0;
-
- public function __construct ()
- {
-  true;
- }
-
- /*********************
-  *
-  * Public functions
-  *
-  **********************/
-
- public function GetRequestArguments ($url, &$arguments)
- {
-  $this->arguments = array ();
-  $arguments["URL"] = $this->arguments["URL"] = $url;
-  $arguments["RequestMethod"] = $this->arguments["RequestMethod"] = "POST";
-  $this->headers["Content-Length"] = 0;
-  $this->headers["Content-Type"] = "application/octet-stream";
-  $this->headers["Host"] = $this->host;
-  $this->headers["User-Agent"] = $this->user_agent;
-  //$this->headers["Expect"] = "100-continue";
+    // variables declaration
+    public $debug;
+    public $html_debug;
+    public $timeout = 30;  // time waiting for connection, seconds
+    public $data_timeout = 30; // time waiting for data, milliseconds
+    public $data_chunk_timeout = 1; // time waiting between data chunks, millisecond
+    public $force_multipart_form_post;
+    public $username;
+    public $password;
+    public $request_headers = array ();
+    public $request_body = "Not a useful information";
+    public $status;
+    public $window_size = 1024; // chunk size of data
+    public $with_exceptions = 0; // compatibility mode for old scripts
+    public $port;
+    public $host;
+    private $default_port = 631;
+    private $headers;
+    private $reply_headers = array ();
+    private $reply_body = array ();
+    private $connection;
+    private $arguments;
+    private $bodystream = array ();
+    private $last_limit;
+    private $connected;
+    private $nc = 1;
+    private $user_agent = "PRINTIPP/0.81+CVS";
+    private $readed_bytes = 0;
 
- }
+    public function __construct ()
+    {
+        true;
+    }
 
- public function Open ($arguments)
- {
-  $this->connected = false;
-  $url = $arguments["URL"];
-  $port = $this->default_port;
-  #$url = split (':', $url, 2);
-  $url = preg_split ('#:#', $url, 2);
-  $transport_type = $url[0];
-  $unix = false;
-  switch ($transport_type)
-  {
-   case 'http':
-    $transport_type = 'tcp://';
-    break;
+    /*********************
+     *
+     * Public functions
+     *
+     **********************/
 
-   case 'https':
-    $transport_type = 'tls://';
-    break;
+    public function GetRequestArguments ($url, &$arguments)
+    {
+        $this->arguments = array ();
+        $this->arguments["URL"] = $arguments["URL"] = $url;
+        $this->arguments["RequestMethod"] = $arguments["RequestMethod"] = "POST";
+        $this->headers["Content-Length"] = 0;
+        $this->headers["Content-Type"] = "application/octet-stream";
+        $this->headers["Host"] = $this->host;
+        $this->headers["User-Agent"] = $this->user_agent;
+        //$this->headers["Expect"] = "100-continue";
+    }
 
-   case 'unix':
-    $transport_type = 'unix://';
-    $port = 0;
-    $unix = true;
-    break;
+    public function Open ($arguments)
+    {
+        $this->connected = false;
+        $url = $arguments["URL"];
+        $port = $this->default_port;
+        #$url = split (':', $url, 2);
+        $url = preg_split ('#:#', $url, 2);
+        $transport_type = $url[0];
+        $unix = false;
+        switch ($transport_type)
+        {
+            case 'http':
+                $transport_type = 'tcp://';
+                break;
 
-   default:
-    $transport_type = 'tcp://';
-    break;
-  }
-  $url = $url[1];
-  if (!$unix)
-  {
-   #$url = split ("/", preg_replace ("#^/{1,}#", '', $url), 2);
-   $url = preg_split ("#/#", preg_replace ("#^/{1,}#", '', $url), 2);
-   $url = $url[0];
-   $port = $this->port;
-   $error = sprintf (_("Cannot resolve url: %s"), $url);
-   $ip = gethostbyname ($url);
-   $ip = @gethostbyaddr ($ip);
-   if (!$ip)
-   {
-    return $this->_HttpError ($error, E_USER_WARNING);
-   }
-   if (strstr ($url, ":")) // we got an ipv6 address
-    if (!strstr ($url, "[")) // it is not escaped
-     $url = sprintf ("[%s]", $url);
-  }
-  $this->connection = @fsockopen ($transport_type.$url, $port, $errno, $errstr, $this->timeout);
-  $error =
-   sprintf (_('Unable to connect to "%s%s port %s": %s'), $transport_type,
-     $url, $port, $errstr);
-  if (!$this->connection)
-  {
-   return $this->_HttpError ($error, E_USER_WARNING);
-  }
-  $this->connected = true;
-  return array (true, "success");
- }
+            case 'https':
+                $transport_type = 'tls://';
+                break;
 
- public function SendRequest ($arguments)
- {
-  $error =
-   sprintf (_('Streaming request failed to %s'), $arguments['RequestURI']);
-  $result = self::_StreamRequest ($arguments);
-  if (!$result[0])
-  {
-   return $this->_HttpError ($error." ".$result[1], E_USER_WARNING);
-  }
-  self::_ReadReply ();
-  if (!preg_match ('#http/1.1 401 unauthorized#', $this->status))
-  {
-   return array (true, "success");
-  }
-  $headers = array_keys ($this->reply_headers);
-  $error = _("need authentication but no mechanism provided");
-  if (!in_array ("www-authenticate", $headers))
-  {
-   return $this->_HttpError ($error, E_USER_WARNING);
-  }
-  #$authtype = split (' ', $this->reply_headers["www-authenticate"]);
-  $authtype = preg_split ('# #', $this->reply_headers["www-authenticate"]);
-  $authtype = strtolower ($authtype[0]);
-  switch ($authtype)
-  {
-   case 'basic':
-    $pass = base64_encode ($this->user.":".$this->password);
-    $arguments["Headers"]["Authorization"] = "Basic ".$pass;
-    break;
+            case 'unix':
+                $transport_type = 'unix://';
+                $port = 0;
+                $unix = true;
+                break;
 
-   case 'digest':
-    $arguments["Headers"]["Authorization"] = self::_BuildDigest ();
-    break;
+            default:
+                $transport_type = 'tcp://';
+                break;
+        }
+        $url = $url[1];
+        if (!$unix)
+        {
+            #$url = split ("/", preg_replace ("#^/{1,}#", '', $url), 2);
+            $url = preg_split ("#/#", preg_replace ("#^/{1,}#", '', $url), 2);
+            $url = $url[0];
+            $port = $this->port;
+            $error = sprintf (_("Cannot resolve url: %s"), $url);
+            $ip = gethostbyname ($url);
+            $ip = @gethostbyaddr ($ip);
+            if (!$ip)
+            {
+                return $this->_HttpError ($error, E_USER_WARNING);
+            }
+            if (strstr ($url, ":")) // we got an ipv6 address
+            {
+                if (!strstr ($url, "[")) // it is not escaped
+                {
+                    $url = sprintf ("[%s]", $url);
+                }
+            }
+        }
+        $this->connection = @fsockopen ($transport_type.$url, $port, $errno, $errstr, $this->timeout);
+        $error =
+            sprintf (_('Unable to connect to "%s%s port %s": %s'), $transport_type,
+                $url, $port, $errstr);
+        if (!$this->connection)
+        {
+            return $this->_HttpError ($error, E_USER_WARNING);
+        }
+        $this->connected = true;
+        return array (true, "success");
+    }
 
-   default:
-    $error =
-     sprintf (_("need '%s' authentication mechanism, but have not"),
-       $authtype[0]);
-    return $this->_HttpError ($error, E_USER_WARNING);
-    break;
+    public function SendRequest ($arguments)
+    {
+        $error =
+            sprintf (_('Streaming request failed to %s'), $arguments['RequestURI']);
+        $result = self::_StreamRequest ($arguments);
+        if (!$result[0])
+        {
+            return $this->_HttpError ($error." ".$result[1], E_USER_WARNING);
+        }
+        self::_ReadReply ();
+        if (!preg_match ('#http/1.1 401 unauthorized#', $this->status))
+        {
+            return array (true, "success");
+        }
+        $headers = array_keys ($this->reply_headers);
+        $error = _("need authentication but no mechanism provided");
+        if (!in_array ("www-authenticate", $headers))
+        {
+            return $this->_HttpError ($error, E_USER_WARNING);
+        }
+        #$authtype = split (' ', $this->reply_headers["www-authenticate"]);
+        $authtype = preg_split ('# #', $this->reply_headers["www-authenticate"]);
+        $authtype = strtolower ($authtype[0]);
+        switch ($authtype)
+        {
+            case 'basic':
+                $pass = base64_encode ($this->user.":".$this->password);
+                $arguments["Headers"]["Authorization"] = "Basic ".$pass;
+                break;
 
-  }
-  self::Close ();
-  self::Open ($arguments);
-  $error =
-   sprintf (_
-     ('Streaming request failed to %s after a try to authenticate'),
-     $url);
-  $result = self::_StreamRequest ($arguments);
-  if (!$result[0])
-  {
-   return $this->_HttpError ($error.": ".$result[1], E_USER_WARNING);
-  }
-  self::_ReadReply ();
-  return array (true, "success");
- }
+            case 'digest':
+                $arguments["Headers"]["Authorization"] = self::_BuildDigest ();
+                break;
 
- public function ReadReplyHeaders (&$headers)
- {
-  $headers = $this->reply_headers;
- }
+            default:
+                $error =
+                    sprintf (_("need '%s' authentication mechanism, but have not"),
+                        $authtype[0]);
+                return $this->_HttpError ($error, E_USER_WARNING);
+                break;
+        }
+        self::Close ();
+        self::Open ($arguments);
 
- public function ReadReplyBody (&$body, $chunk_size)
- {
-  $body = substr ($this->reply_body, $this->last_limit, $chunk_size);
-  $this->last_limit += $chunk_size;
- }
+        $error = sprintf(_('Streaming request failed to %s after a try to authenticate'), $arguments['RequestURI']);
+        $result = self::_StreamRequest ($arguments);
+        if (!$result[0])
+        {
+            return $this->_HttpError ($error.": ".$result[1], E_USER_WARNING);
+        }
+        self::_ReadReply ();
+        return array (true, "success");
+    }
 
- public function Close ()
- {
-  if (!$this->connected)
-   return;
-  fclose ($this->connection);
- }
+    public function ReadReplyHeaders (&$headers)
+    {
+        $headers = $this->reply_headers;
+    }
 
- /*********************
-  *
-  *  Private functions
-  *
-  *********************/
+    public function ReadReplyBody (&$body, $chunk_size)
+    {
+        $body = substr ($this->reply_body, $this->last_limit, $chunk_size);
+        $this->last_limit += $chunk_size;
+    }
 
- private function _HttpError ($msg, $level, $errno = null)
- {
-  $trace = '';
-  $backtrace = debug_backtrace;
-  foreach ($backtrace as $trace)
-  {
-   $trace .= sprintf ("in [file: '%s'][function: '%s'][line: %s];\n", $trace['file'], $trace['function'],$trace['line']);
-  }
-  $msg = sprintf ( '%s\n%s: [errno: %s]: %s',
-    $trace, error2string ($level), $errno, $msg);
-  if ($this->with_exceptions)
-  {
-   throw new httpException ($msg, $errno);
-  }
-  else
-  {
-   trigger_error ($msg, $level);
-   return array (false, $msg);
-  }
- }
+    public function Close ()
+    {
+        if (!$this->connected)
+        {
+            return;
+        }
+        fclose ($this->connection);
+    }
 
- private function _streamString ($string)
- {
-  $success = fwrite ($this->connection, $string);
-  if (!$success)
-  {
-   return false;
-  }
-  return true;
- }
+    /*********************
+     *
+     *  Private functions
+     *
+     *********************/
 
- private function _StreamRequest ($arguments)
- {
-  $this->status = false;
-  $this->reply_headers = array ();
-  $this->reply_body = "";
-  if (!$this->connected)
-  {
-   return _HttpError (_("not connected"), E_USER_WARNING);
-  }
-  $this->arguments = $arguments;
-  $content_length = 0;
-  foreach ($this->arguments["BodyStream"] as $argument)
-  {
-   list ($type, $value) = each ($argument);
-   reset ($argument);
-   if ($type == "Data")
-   {
-    $length = strlen ($value);
-   }
-   elseif ($type == "File")
-   {
-    if (is_readable ($value))
+    private function _HttpError ($msg, $level, $errno = null)
     {
-     $length = filesize ($value);
+        $trace = '';
+        $backtrace = debug_backtrace();
+        foreach ($backtrace as $trace)
+        {
+            $trace .= sprintf ("in [file: '%s'][function: '%s'][line: %s];\n", $trace['file'], $trace['function'],$trace['line']);
+        }
+        $msg = sprintf ( '%s\n%s: [errno: %s]: %s',
+            $trace, error2string ($level), $errno, $msg);
+        if ($this->with_exceptions)
+        {
+            throw new httpException ($msg, $errno);
+        }
+        else
+        {
+            trigger_error ($msg, $level);
+            return array (false, $msg);
+        }
     }
-    else
+
+    private function _streamString ($string)
     {
-     $length = 0;
-     return
-      _HttpError (sprintf (_("%s: file is not readable"), $value),
-        E_USER_WARNING);
+        $success = fwrite ($this->connection, $string);
+        if (!$success)
+        {
+            return false;
+        }
+        return true;
     }
-   }
-   else
-   {
-    $length = 0;
-    return
-     _HttpError (sprintf
-       (_("%s: not a valid argument for content"), $type),
-       E_USER_WARNING);
-   }
-   $content_length += $length;
-  }
-  $this->request_body = sprintf (_("%s Bytes"), $content_length);
-  $this->headers["Content-Length"] = $content_length;
-  $this->arguments["Headers"] =
-   array_merge ($this->headers, $this->arguments["Headers"]);
-  if ($this->arguments["RequestMethod"] != "POST")
-  {
-   return
-    _HttpError (sprintf
-      (_("%s: method not implemented"),
-       $arguments["RequestMethod"]), E_USER_WARNING);
-  }
-  $string =
-   sprintf ("POST %s HTTP/1.1\r\n", $this->arguments["RequestURI"]);
-  $this->request_headers[$string] = '';
-  if (!$this->_streamString ($string))
-  {
-   return _HttpError (_("Error while puts POST operation"),
-     E_USER_WARNING);
-  }
-  foreach ($this->arguments["Headers"] as $header => $value)
-  {
-   $string = sprintf ("%s: %s\r\n", $header, $value);
-   $this->request_headers[$header] = $value;
-   if (!$this->_streamString ($string))
-   {
-    return _HttpError (_("Error while puts HTTP headers"),
-      E_USER_WARNING);
-   }
-  }
-  $string = "\r\n";
-  if (!$this->_streamString ($string))
-  {
-   return _HttpError (_("Error while ends HTTP headers"),
-     E_USER_WARNING);
-  }
-  foreach ($this->arguments["BodyStream"] as $argument)
-  {
-   list ($type, $value) = each ($argument);
-   reset ($argument);
-   if ($type == "Data")
-   {
-    $streamed_length = 0;
-    while ($streamed_length < strlen ($value))
+
+    private function _StreamRequest ($arguments)
     {
-     $string = substr ($value, $streamed_length, $this->window_size);
-     if (!$this->_streamString ($string))
-     {
-      return _HttpError (_("error while sending body data"),
-        E_USER_WARNING);
-     }
-     $streamed_length += $this->window_size;
+        $this->status = false;
+        $this->reply_headers = array ();
+        $this->reply_body = "";
+        if (!$this->connected)
+        {
+            return $this->_HttpError (_("not connected"), E_USER_WARNING);
+        }
+        $this->arguments = $arguments;
+        $content_length = 0;
+        foreach ($this->arguments["BodyStream"] as $argument)
+        {
+            list ($type, $value) = each ($argument);
+            reset ($argument);
+            if ($type == "Data")
+            {
+                $length = strlen ($value);
+            }
+            elseif ($type == "File")
+            {
+                if (is_readable ($value))
+                {
+                    $length = filesize ($value);
+                }
+                else
+                {
+                    $length = 0;
+                    return $this->_HttpError (sprintf (_("%s: file is not readable"), $value), E_USER_WARNING);
+                }
+            }
+            else
+            {
+                $length = 0;
+                return $this->_HttpError (sprintf(_("%s: not a valid argument for content"), $type), E_USER_WARNING);
+            }
+            $content_length += $length;
+        }
+        $this->request_body = sprintf (_("%s Bytes"), $content_length);
+        $this->headers["Content-Length"] = $content_length;
+        $this->arguments["Headers"] = array_merge ($this->headers, $this->arguments["Headers"]);
+        if ($this->arguments["RequestMethod"] != "POST")
+        {
+            return $this->_HttpError (sprintf(_("%s: method not implemented"), $arguments["RequestMethod"]), E_USER_WARNING);
+        }
+        $string = sprintf ("POST %s HTTP/1.1\r\n", $this->arguments["RequestURI"]);
+        $this->request_headers[$string] = '';
+        if (!$this->_streamString ($string))
+        {
+            return $this->_HttpError (_("Error while puts POST operation"), E_USER_WARNING);
+        }
+        foreach ($this->arguments["Headers"] as $header => $value)
+        {
+            $string = sprintf ("%s: %s\r\n", $header, $value);
+            $this->request_headers[$header] = $value;
+            if (!$this->_streamString ($string))
+            {
+                return $this->_HttpError (_("Error while puts HTTP headers"), E_USER_WARNING);
+            }
+        }
+        $string = "\r\n";
+        if (!$this->_streamString ($string))
+        {
+            return $this->_HttpError (_("Error while ends HTTP headers"), E_USER_WARNING);
+        }
+        foreach ($this->arguments["BodyStream"] as $argument)
+        {
+            list ($type, $value) = each ($argument);
+            reset ($argument);
+            if ($type == "Data")
+            {
+                $streamed_length = 0;
+                while ($streamed_length < strlen ($value))
+                {
+                    $string = substr ($value, $streamed_length, $this->window_size);
+                    if (!$this->_streamString ($string))
+                    {
+                        return $this->_HttpError (_("error while sending body data"), E_USER_WARNING);
+                    }
+                    $streamed_length += $this->window_size;
+                }
+            }
+            elseif ($type == "File")
+            {
+                if (is_readable ($value))
+                {
+                    $file = fopen ($value, 'rb');
+                    while (!feof ($file))
+                    {
+                        if (gettype ($block = @fread ($file, $this->window_size)) != "string")
+                        {
+                            return $this->_HttpError (_("cannot read file to upload"), E_USER_WARNING);
+                        }
+                        if (!$this->_streamString ($block))
+                        {
+                            return $this->_HttpError (_("error while sending body data"), E_USER_WARNING);
+                        }
+                    }
+                }
+            }
+        }
+        return array (true, "success");
     }
-   }
-   elseif ($type == "File")
-   {
-    if (is_readable ($value))
+
+    private function _ReadReply ()
     {
-     $file = fopen ($value, 'rb');
-     while (!feof ($file))
-     {
-      if (gettype ($block = @fread ($file, $this->window_size)) !=
-        "string")
-      {
-       return _HttpError (_("cannot read file to upload"),
-         E_USER_WARNING);
-      }
-      if (!$this->_streamString ($block))
-      {
-       return _HttpError (_("error while sending body data"),
-         E_USER_WARNING);
-      }
-     }
+        if (!$this->connected)
+        {
+            return array (false, _("not connected"));
+        }
+        $this->reply_headers = array ();
+        $this->reply_body = "";
+        $headers = array ();
+        $body = "";
+        while (!feof ($this->connection))
+        {
+            $line = fgets ($this->connection, 1024);
+            if (strlen (trim($line)) == 0)
+            {
+                break;
+            } // \r\n => end of headers
+            if (preg_match ('#^[[:space:]]#', $line))
+            {
+                $headers[-1] .= sprintf(' %s', trim ($line));
+                continue;
+            }
+            $headers[] = trim ($line);
+        }
+        $this->status = isset ($headers[0]) ? strtolower ($headers[0]) : false;
+        foreach ($headers as $header)
+        {
+            $header = preg_split ("#: #", $header);
+            $header[0] = strtolower ($header[0]);
+            if ($header[0] !== "www-authenticate")
+            {
+                $header[1] = isset ($header[1]) ? strtolower ($header[1]) : "";
+            }
+            if (!isset ($this->reply_headers[$header[0]]))
+            {
+                $this->reply_headers[$header[0]] = $header[1];
+            }
+        }
+        self::_ReadStream ();
+        return true;
     }
-   }
-  }
-  return array (true, "success");
- }
-
- private function _ReadReply ()
- {
-  if (!$this->connected)
-  {
-   return array (false, _("not connected"));
-  }
-  $this->reply_headers = array ();
-  $this->reply_body = "";
-  $headers = array ();
-  $body = "";
-  while (!feof ($this->connection))
-  {
-   $line = fgets ($this->connection, 1024);
-   if (strlen (trim($line)) == 0)
-    break;  // \r\n => end of headers
-   if (preg_match ('#^[[:space:]]#', $line))
-   {
-    $headers[-1] .= sprintf(' %s', trim ($line));
-    continue;
-   }
-   $headers[] = trim ($line);
-  }
-  $this->status = isset ($headers[0]) ? strtolower ($headers[0]) : false;
-  foreach ($headers as $header)
-  {
-   $header = preg_split ("#: #", $header);
-   $header[0] = strtolower ($header[0]);
-   if ($header[0] !== "www-authenticate")
-   {
-    $header[1] = isset ($header[1]) ? strtolower ($header[1]) : "";
-   }
-   if (!isset ($this->reply_headers[$header[0]]))
-   {
-    $this->reply_headers[$header[0]] = $header[1];
-   }
-  }
-  self::_ReadStream ();
-  return true;
- }
-
- private function _ReadStream ()
- {
-  if (! array_key_exists ("content-length", $this->reply_headers))
-  {
-   stream_set_blocking($this->connection, 0);
-   $this->reply_body = stream_get_contents($this->connection);
-   return true;
-  }
-  stream_set_blocking($this->connection, 1);
-  $content_length = $this->reply_headers["content-length"];
-  $this->reply_body = stream_get_contents($this->connection,$content_length);
-  return true;
- }
 
- private function _BuildDigest ()
- {
-  $auth = $this->reply_headers["www-authenticate"];
-  #list ($head, $auth) = split (" ", $auth, 2);
-  list ($head, $auth) = preg_split ("# #", $auth, 2);
-  #$auth = split (", ", $auth);
-  $auth = preg_split ("#, #", $auth);
-  foreach ($auth as $sheme)
-  {
-   #list ($sheme, $value) = split ('=', $sheme);
-   list ($sheme, $value) = preg_split ('#=#', $sheme);
-   $fields[$sheme] = trim (trim ($value), '"');
-  }
-  $nc = sprintf ('%x', $this->nc);
-  $prepend = "";
-  while ((strlen ($nc) + strlen ($prepend)) < 8)
-   $prependi .= "0";
-  $nc = $prepend.$nc;
-  $cnonce = "printipp";
-  $username = $this->user;
-  $password = $this->password;
-  $A1 = $username.":".$fields["realm"].":".$password;
-  if (array_key_exists ("algorithm", $fields))
-  {
-   $algorithm = strtolower ($fields["algorithm"]);
-   switch ($algorithm)
-   {
-    case "md5":
-     break;
-
-    case "md5-sess":
-     $A1 =
-     $username.":".$fields["realm"].":".$password.":".
-     $fields['nonce'].":".$cnonce;
-    break;
+    private function _ReadStream ()
+    {
+        if (! array_key_exists ("content-length", $this->reply_headers))
+        {
+            stream_set_blocking($this->connection, 0);
+            $this->reply_body = stream_get_contents($this->connection);
+            return true;
+        }
+        stream_set_blocking($this->connection, 1);
+        $content_length = $this->reply_headers["content-length"];
+        $this->reply_body = stream_get_contents($this->connection,$content_length);
+        return true;
+    }
 
-    default:
-    return _HttpError(
-      sprintf (_("digest Authorization: algorithm '%s' not implemented"),
-       $algorithm),
-      E_USER_WARNING);
-    return false;
-    break;
-   }
-  }
-  $A2 = "POST:".$this->arguments["RequestURI"];
-  if (array_key_exists ("qop", $fields))
-  {
-   $qop = strtolower ($fields["qop"]);
-   #$qop = split (" ", $qop);
-   $qop = preg_split ("# #", $qop);
-   if (in_array ("auth", $qop))
-    $qop = "auth";
-   else
-   {
-    self::_HttpError(
-      sprintf (_("digest Authorization: algorithm '%s' not implemented"),
-       $qop),
-      E_USER_WARNING);
-    return false;
-   }
-  }
-  $response = md5 (md5 ($A1).":".$fields["nonce"].":".md5 ($A2));
-  if (isset ($qop) && ($qop == "auth"))
-  {
-   $response =
-    md5 (md5 ($A1).":".$fields["nonce"].":".$nc.":".$cnonce.":".$qop.
-      ":".$A2);
-  }
-  $auth_scheme =
-   sprintf
-   ('Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"',
-    $username, $fields["realm"], $fields['nonce'],
-    $this->arguments["RequestURI"], $response);
-  if (isset ($algorithm))
-   $auth_scheme .= sprintf (', algorithm="%s"', $algorithm);
-  if (isset ($qop))
-   $auth_scheme .= sprintf (', cnonce="%s"', $cnonce);
-  if (array_key_exists ("opaque", $fields))
-   $auth_scheme .= sprintf (', opaque="%s"', $fields['opaque']);
-  if (isset ($qop))
-   $auth_scheme .= sprintf (', qop="%s"', $qop);
-  $auth_scheme .= sprintf (', nc=%s', $nc);
-  $this->nc++;
-  return $auth_scheme;
- }
+    private function _BuildDigest ()
+    {
+        $auth = $this->reply_headers["www-authenticate"];
+        #list ($head, $auth) = split (" ", $auth, 2);
+        list ($head, $auth) = preg_split ("# #", $auth, 2);
+        #$auth = split (", ", $auth);
+        $auth = preg_split ("#, #", $auth);
+        foreach ($auth as $sheme)
+        {
+            #list ($sheme, $value) = split ('=', $sheme);
+            list ($sheme, $value) = preg_split ('#=#', $sheme);
+            $fields[$sheme] = trim (trim ($value), '"');
+        }
+        $nc = sprintf ('%x', $this->nc);
+        $prepend = "";
+        while ((strlen ($nc) + strlen ($prepend)) < 8)
+            $prependi .= "0";
+        $nc = $prepend.$nc;
+        $cnonce = "printipp";
+        $username = $this->user;
+        $password = $this->password;
+        $A1 = $username.":".$fields["realm"].":".$password;
+        if (array_key_exists ("algorithm", $fields))
+        {
+            $algorithm = strtolower ($fields["algorithm"]);
+            switch ($algorithm)
+            {
+                case "md5":
+                    break;
 
-};
+                case "md5-sess":
+                    $A1 =
+                    $username.":".$fields["realm"].":".$password.":".
+                    $fields['nonce'].":".$cnonce;
+                    break;
 
-/*
- * Local variables:
- * mode: php
- * tab-width: 2
- * c-basic-offset: 2
- * End:
- */
-?>
+                default:
+                    return $this->_HttpError(
+                        sprintf (_("digest Authorization: algorithm '%s' not implemented"),
+                            $algorithm),
+                        E_USER_WARNING);
+                return false;
+                break;
+            }
+        }
+        $A2 = "POST:".$this->arguments["RequestURI"];
+        if (array_key_exists ("qop", $fields))
+        {
+            $qop = strtolower ($fields["qop"]);
+            #$qop = split (" ", $qop);
+            $qop = preg_split ("# #", $qop);
+            if (in_array ("auth", $qop))
+            {
+                $qop = "auth";
+            }
+            else
+            {
+                self::_HttpError(
+                    sprintf (_("digest Authorization: algorithm '%s' not implemented"),
+                        $qop),
+                    E_USER_WARNING);
+                return false;
+            }
+        }
+        $response = md5 (md5 ($A1).":".$fields["nonce"].":".md5 ($A2));
+        if (isset ($qop) && ($qop == "auth"))
+        {
+            $response =
+                md5 (md5 ($A1).":".$fields["nonce"].":".$nc.":".$cnonce.":".$qop.
+                    ":".$A2);
+        }
+        $auth_scheme =
+            sprintf
+            ('Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"',
+                $username, $fields["realm"], $fields['nonce'],
+                $this->arguments["RequestURI"], $response);
+        if (isset ($algorithm))
+        {
+            $auth_scheme .= sprintf (', algorithm="%s"', $algorithm);
+        }
+        if (isset ($qop))
+        {
+            $auth_scheme .= sprintf (', cnonce="%s"', $cnonce);
+        }
+        if (array_key_exists ("opaque", $fields))
+        {
+            $auth_scheme .= sprintf (', opaque="%s"', $fields['opaque']);
+        }
+        if (isset ($qop))
+        {
+            $auth_scheme .= sprintf (', qop="%s"', $qop);
+        }
+        $auth_scheme .= sprintf (', nc=%s', $nc);
+        $this->nc++;
+        return $auth_scheme;
+    }
+}
diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql
index 9a48f6378eab4d54ff70c586108d62185127a7c7..d5ac52fd4aa6f284b18fc61293dd4c58a160b8ff 100755
--- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql
+++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql
@@ -26,6 +26,21 @@ create table llx_c_price_expression
   expression    varchar(80) NOT NULL
 )ENGINE=innodb;
 
+--create table for user conf of printing driver
+CREATE TABLE llx_printing 
+(
+ rowid integer AUTO_INCREMENT PRIMARY KEY,
+ tms timestamp,
+ datec datetime,
+ printer_name text NOT NULL, 
+ printer_location text NOT NULL,
+ printer_id varchar(255) NOT NULL,
+ copy integer NOT NULL DEFAULT '1',
+ module varchar(16) NOT NULL,
+ driver varchar(16) NOT NULL,
+ userid integer
+)ENGINE=innodb;
+
 ALTER TABLE llx_product_fournisseur_price ADD fk_price_expression integer DEFAULT NULL;
 
 -- Taiwan VAT Rates
diff --git a/htdocs/install/mysql/tables/llx_printer_ipp.sql b/htdocs/install/mysql/tables/llx_printing.sql
similarity index 77%
rename from htdocs/install/mysql/tables/llx_printer_ipp.sql
rename to htdocs/install/mysql/tables/llx_printing.sql
index a19e05587d63fb4d30beb3066d65f381d8965a14..451564ff74b1cb02fa0979ba612601425b14b2b7 100644
--- a/htdocs/install/mysql/tables/llx_printer_ipp.sql
+++ b/htdocs/install/mysql/tables/llx_printing.sql
@@ -1,5 +1,6 @@
 -- ============================================================================
--- Copyright (C) 2013 Florian HENRY <florian.henry@open-concept.pro>
+-- Copyright (C) 2013   Florian HENRY     <florian.henry@open-concept.pro>
+-- Copyright (C) 2014   Frederic France   <frederic.france@free.fr>
 --
 -- 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
@@ -16,15 +17,16 @@
 --
 -- ============================================================================
 
-CREATE TABLE llx_printer_ipp 
+CREATE TABLE llx_printing 
 (
  rowid integer AUTO_INCREMENT PRIMARY KEY,
- tms 	timestamp,
- datec 	datetime,
+ tms timestamp,
+ datec datetime,
  printer_name text NOT NULL, 
  printer_location text NOT NULL,
- printer_uri varchar(255) NOT NULL,
+ printer_id varchar(255) NOT NULL,
  copy integer NOT NULL DEFAULT '1',
  module varchar(16) NOT NULL,
- login varchar(32) NOT NULL
+ driver varchar(16) NOT NULL,
+ userid integer
 )ENGINE=innodb;
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index bfded6f40e2e597cf7641de510c48b2bf9f9f672..5562002b58ba6e2274a2371cab42d6fb4924634c 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -685,6 +685,7 @@ XMoreLines=%s line(s) hidden
 PublicUrl=Public URL
 AddBox=Add box
 SelectElementAndClickRefresh=Select an element and click Refresh
+PrintFile=Print File %s
 # Week day
 Monday=Monday
 Tuesday=Tuesday
diff --git a/htdocs/langs/en_US/printgcp.lang b/htdocs/langs/en_US/printgcp.lang
new file mode 100644
index 0000000000000000000000000000000000000000..ded5fb63d6e4722f2d4f6d1114f59568484bfd93
--- /dev/null
+++ b/htdocs/langs/en_US/printgcp.lang
@@ -0,0 +1,25 @@
+# Dolibarr language file - Source file is en_US - printgccp
+PRINTGCP=Google Cloud Print
+PrintGCPDesc=This driver allow to send documents directly to a printer with Google Cloud Print.
+PrintingDriverDescprintgcp=Configuration variables for printing driver Google Cloud Print.
+PrintTestDescprintgcp=List of Printers for Google Cloud Print.
+PRINTGCP_LOGIN=Google Account Login
+PRINTGCP_PASSWORD=Google Account Password
+STATE_ONLINE=Online
+STATE_UNKNOWN=Unknown
+STATE_OFFLINE=Offline
+STATE_DORMANT=Offline for quite a while
+TYPE_GOOGLE=Google
+TYPE_HP=HP Printer
+TYPE_DOCS=DOCS
+TYPE_DRIVE=Google Drive
+TYPE_FEDEX=Fedex
+TYPE_ANDROID_CHROME_SNAPSHOT=Android
+TYPE_IOS_CHROME_SNAPSHOT=IOS
+GCP_Name=Name
+GCP_displayName=Display Name
+GCP_Id=Printer Id
+GCP_OwnerName=Owner Name
+GCP_State=Printer State
+GCP_connectionStatus=Online State
+GCP_Type=Printer Type
diff --git a/htdocs/langs/en_US/printing.lang b/htdocs/langs/en_US/printing.lang
new file mode 100644
index 0000000000000000000000000000000000000000..77c6388463614732cd87fb6237faba29d0ecd3cc
--- /dev/null
+++ b/htdocs/langs/en_US/printing.lang
@@ -0,0 +1,10 @@
+# Dolibarr language file - Source file is en_US - printing
+PrintingSetup=Setup of Printing System
+PrintingDesc=This module adds a Print button to send documents directly to a printer with various module.
+ModuleDriverSetup=Setup Module Driver
+PrintingDriverDesc=Configuration variables for printing driver.
+ListDrivers=List of drivers
+PrintTestDesc=List of Printers.
+FileWasSentToPrinter=File %s was sent to printer
+NoActivePrintingModuleFound=No active module to print document
+PleaseSelectaDriverfromList=Please select a driver from list.
diff --git a/htdocs/langs/en_US/printipp.lang b/htdocs/langs/en_US/printipp.lang
index 835e6827f12ee4e466c21f2ee540526389fa7e03..e85d53627c45cbd65b18843bf880498ebdd2b55e 100644
--- a/htdocs/langs/en_US/printipp.lang
+++ b/htdocs/langs/en_US/printipp.lang
@@ -1,6 +1,9 @@
 # Dolibarr language file - Source file is en_US - printipp
+PRINTIPP=PrintIPP Driver
 PrintIPPSetup=Setup of Direct Print module
-PrintIPPDesc=This module adds a Print button to send documents directly to a printer. It requires a Linux system with CUPS installed.
+PrintIPPDesc=This driver allow to send documents directly to a printer. It requires a Linux system with CUPS installed.
+PrintingDriverDescprintipp=Configuration variables for printing driver PrintIPP.
+PrintTestDescprintipp=List of Printers for driver PrintIPP.
 PRINTIPP_ENABLED=Show "Direct print" icon in document lists
 PRINTIPP_HOST=Print server
 PRINTIPP_PORT=Port
@@ -12,3 +15,23 @@ NoDefaultPrinterDefined=No default printer defined
 DefaultPrinter=Default printer
 Printer=Printer
 CupsServer=CUPS Server
+IPP_Uri=Printer Uri
+IPP_Name=Printer Name
+IPP_State=Printer State
+IPP_State_reason=State reason
+IPP_State_reason1=State reason1
+IPP_BW=BW
+IPP_Color=Color
+IPP_Device=Device
+IPP_Media=Printer media
+IPP_Supported=Type of media
+STATE_IPP_idle=Idle
+STATE_IPP_stopped=Stopped
+STATE_IPP_paused=Paused
+STATE_IPP_toner-low-report=Low Toner
+STATE_IPP_none=None
+MEDIA_IPP_stationery=Stationery
+MEDIA_IPP_thermal=Thermal
+IPP_COLOR_print-black=BW Printer
+IPP_COLOR_print-color=Color Printer
+IPP_COLOR_=No
diff --git a/htdocs/printipp/lib/index.html b/htdocs/printing/admin/index.html
similarity index 100%
rename from htdocs/printipp/lib/index.html
rename to htdocs/printing/admin/index.html
diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php
new file mode 100644
index 0000000000000000000000000000000000000000..63784e560f0af256fe9dac55adb1afdaf13c652e
--- /dev/null
+++ b/htdocs/printing/admin/printing.php
@@ -0,0 +1,277 @@
+<?php
+/* Copyright (C) 2013 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2014 Frederic France      <frederic.france@free.fr>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ *      \file       htdocs/printing/admin/printing.php
+ *      \ingroup    printing
+ *      \brief      Page to setup printing module
+ */
+
+require '../../main.inc.php';
+
+require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php';
+require_once DOL_DOCUMENT_ROOT.'/printing/lib/printing.lib.php';
+
+$langs->load("admin");
+$langs->load("printing");
+
+if (! $user->admin) accessforbidden();
+
+$action = GETPOST('action','alpha');
+$mode = GETPOST('mode','alpha');
+$value = GETPOST('value','alpha');
+$varname = GETPOST('varname', 'alpha');
+$driver = GETPOST('driver', 'alpha');
+
+if (! empty($driver)) $langs->load($driver);
+
+if (!$mode) $mode='config';
+
+/*
+ * Action
+ */
+
+if (($mode == 'test' || $mode == 'setup') && empty($driver))
+{
+    setEventMessage($langs->trans('PleaseSelectaDriverfromList'));
+    header("Location: ".$_SERVER['PHP_SELF'].'?mode=config');
+    exit;
+}
+
+if ($action == 'setconst' && $user->admin)
+{
+    $error=0;
+    $db->begin();
+    foreach ($_POST['setupdriver'] as $setupconst) {
+        //print '<pre>'.print_r($setupconst, true).'</pre>';
+        $result=dolibarr_set_const($db, $setupconst['varname'],$setupconst['value'],'chaine',0,'',$conf->entity);
+        if (! $result > 0) $error++;
+    }
+
+    if (! $error)
+    {
+        $db->commit();
+        setEventMessage($langs->trans("SetupSaved"));
+    }
+    else
+    {
+        $db->rollback();
+        dol_print_error($db);
+    }
+    $action='';
+}
+
+if ($action == 'setvalue' && $user->admin)
+{
+    $db->begin();
+
+    $result=dolibarr_set_const($db, $varname, $value,'chaine',0,'',$conf->entity);
+    if (! $result > 0) $error++;
+
+    if (! $error)
+    {
+        $db->commit();
+        setEventMessage($langs->trans("SetupSaved"));
+    }
+    else
+    {
+        $db->rollback();
+        dol_print_error($db);
+    }
+    $action = '';
+}
+
+/*
+ * View
+ */
+
+$form = new Form($db);
+
+llxHeader('',$langs->trans("PrintingSetup"));
+
+$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
+print_fiche_titre($langs->trans("PrintingSetup"),$linkback,'setup');
+
+$head=printingadmin_prepare_head();
+
+if ($mode == 'setup' && $user->admin)
+{
+    print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=setup&amp;driver='.$driver.'">';
+    print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
+    print '<input type="hidden" name="action" value="setconst">';
+
+    dol_fiche_head($head, $mode, $langs->trans("ModuleDriverSetup"), 0, 'technic');
+
+    print $langs->trans("PrintingDriverDesc".$driver)."<br><br>\n";
+
+    print '<table class="noborder" width="100%">'."\n";
+    $var=true;
+    print '<tr class="liste_titre">';
+    print '<th>'.$langs->trans("Parameters").'</th>';
+    print '<th>'.$langs->trans("Value").'</th>';
+    print "</tr>\n";
+
+    if (! empty($driver)) {
+        require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
+        $classname = 'printing_'.$driver;
+        $langs->load($driver);
+        $printer = new $classname($db);
+        //print '<pre>'.print_r($printer, true).'</pre>';
+        $i=0;
+        foreach ($printer->conf as $key) {
+            $var=!$var;
+            print '<tr '.$bc[$var].'>';
+            print '<td'.($key['required']?' class=required':'').'>'.$langs->trans($key['varname']).'</td><td>';
+            print '<input size="32" type="'.(empty($key['type'])?'text':$key['type']).'" name="setupdriver['.$i.'][value]" value="'.$conf->global->{$key['varname']}.'">';
+            print '<input type="hidden" name="setupdriver['.$i.'][varname]" value="'.$key['varname'].'">';
+            print '&nbsp;'.($key['example']!=''?$langs->trans("Example").' : '.$key['example']:'');
+            print '</tr>';
+            $i++;
+        }
+    } else {
+        print $langs->trans('PleaseSelectaDriverfromList');
+    }
+
+    print '</table>';
+    if (! empty($driver)) {
+        print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Modify")).'"></center>';
+    }
+    print '</form>';
+    dol_fiche_end();
+
+}
+if ($mode == 'config' && $user->admin)
+{
+    dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic');
+
+    print $langs->trans("PrintingDesc")."<br><br>\n";
+    
+    print '<table class="noborder" width="100%">'."\n";
+
+    $var=true;
+    print '<tr class="liste_titre">';
+    print '<th>'.$langs->trans("Description").'</th>';
+    print '<th class="center">'.$langs->trans("Active").'</th>';
+    print '<th class="center">'.$langs->trans("Setup").'</th>';
+    print '<th class="center">'.$langs->trans("Test").'</th>';
+    print "</tr>\n";
+
+    $object = new PrintingDriver($db);
+    $result = $object->listDrivers($db, 10);
+    foreach ($result as $driver) {
+        require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
+        $classname = 'printing_'.$driver;
+        $langs->load($driver);
+        $printer = new $classname($db);
+        //print '<pre>'.print_r($printer, true).'</pre>';
+        $var=!$var;
+        print '<tr '.$bc[$var].'>';
+        print '<td>'.img_picto('', $printer->picto).$langs->trans($printer->desc).'</td>';
+        print '<td class="center">';
+        if (! empty($conf->use_javascript_ajax))
+        {
+            print ajax_constantonoff($printer->active);
+        }
+        else
+        {
+            if (empty($conf->global->{$printer->conf}))
+            {
+                print '<a href="'.$_SERVER['PHP_SELF'].'?action=setvalue&amp;varname='.$printer->active.'&amp;value=1">'.img_picto($langs->trans("Disabled"),'off').'</a>';
+            }
+            else
+            {
+                print '<a href="'.$_SERVER['PHP_SELF'].'?action=setvalue&amp;varname='.$printer->active.'&amp;value=0">'.img_picto($langs->trans("Enabled"),'on').'</a>';
+            }
+        }
+        print '<td class="center"><a href="'.$_SERVER['PHP_SELF'].'?mode=setup&amp;driver='.$printer->name.'">'.img_picto('', 'setup').'</a></td>';
+        print '<td class="center"><a href="'.$_SERVER['PHP_SELF'].'?mode=test&amp;driver='.$printer->name.'">'.img_picto('', 'setup').'</a></td>';
+        print '</tr>'."\n";
+    }
+
+    print '</table>';
+
+    dol_fiche_end();
+}
+
+if ($mode == 'test' && $user->admin)
+{
+    dol_fiche_head($head, $mode, $langs->trans("PrintingTest"), 0, 'technic');
+
+    print $langs->trans('PrintTestDesc'.$driver)."<br><br>\n";
+    
+    print '<table class="noborder" width="100%">';
+    if (! empty($driver)) {
+        require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
+        $classname = 'printing_'.$driver;
+        $langs->load($driver);
+        $printer = new $classname($db);
+        //print '<pre>'.print_r($printer, true).'</pre>';
+        print $printer->listAvailablePrinters();
+
+    } else {
+        print $langs->trans('PleaseSelectaDriverfromList');
+    }
+    print '</table>';
+
+    dol_fiche_end();
+}
+
+if ($mode == 'userconf' && $user->admin)
+{
+    dol_fiche_head($head, $mode, $langs->trans("UserConf"), 0, 'technic');
+
+    print $langs->trans('PrintUserConfDesc'.$driver)."<br><br>\n";
+
+    print '<table class="noborder" width="100%">';
+    $var=true;
+    print '<tr class="liste_titre">';
+    print '<th>'.$langs->trans("User").'</th>';
+    print '<th>'.$langs->trans("PrintModule").'</th>';
+    print '<th>'.$langs->trans("PrintDriver").'</th>';
+    print '<th>'.$langs->trans("Printer").'</th>';
+    print '<th>'.$langs->trans("PrinterLocation").'</th>';
+    print '<th>'.$langs->trans("PrinterId").'</th>';
+    print '<th>'.$langs->trans("NumberOfCopy").'</th>';
+    print '<th class="center">'.$langs->trans("Delete").'</th>';
+    print "</tr>\n";
+    $sql = 'SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login FROM '.MAIN_DB_PREFIX.'printing as p, '.MAIN_DB_PREFIX.'user as u WHERE p.userid=u.rowid';
+    $resql = $db->query($sql);
+    while ($row=$db->fetch_array($resql)) {
+        $var=!$var;
+        print '<tr '.$bc[$var].'>';
+        print '<td>'.$row['login'].'</td>';
+        print '<td>'.$row['module'].'</td>';
+        print '<td>'.$row['driver'].'</td>';
+        print '<td>'.$row['printer_name'].'</td>';
+        print '<td>'.$row['printer_location'].'</td>';
+        print '<td>'.$row['printer_id'].'</td>';
+        print '<td>'.$row['copy'].'</td>';
+        print '<td class="center">'.img_picto($langs->trans("Delete"), 'delete').'</td>';
+        print "</tr>\n";
+    }
+    print '</table>';
+
+    dol_fiche_end();
+
+}
+
+llxFooter();
+
+$db->close();
diff --git a/htdocs/printipp/index.php b/htdocs/printing/index.php
similarity index 61%
rename from htdocs/printipp/index.php
rename to htdocs/printing/index.php
index a130805f16ebd3ee3863a21cd22148d9c2804eb7..e8669f44585b4cba1db19a22084808a808ee9b49 100644
--- a/htdocs/printipp/index.php
+++ b/htdocs/printing/index.php
@@ -1,5 +1,6 @@
 <?php
 /*
+ * Copyright (C) 2014       Frederic France      <frederic.france@free.fr>
  *
  * 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
@@ -16,20 +17,21 @@
  */
 
 /**
- *	\file       htdocs/printipp/index.php
- *	\ingroup    printipp
- *	\brief      Printipp
+ *  \file       htdocs/printing/index.php
+ *  \ingroup    printing
+ *  \brief      Printing
  */
 
 require '../main.inc.php';
 require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php';
 
-llxHeader("",$langs->trans("Printer"));
+llxHeader("",$langs->trans("Printing"));
 
-print_fiche_titre($langs->trans("Printer"));
+print_fiche_titre($langs->trans("Printing"));
 
-$printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD);
-$printer->list_jobs('commande');
+// List Jobs from printing modules
+//$printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD);
+//$printer->list_jobs('commande');
 
 llxFooter();
 
diff --git a/htdocs/printing/lib/index.html b/htdocs/printing/lib/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/htdocs/printipp/lib/printipp.lib.php b/htdocs/printing/lib/printing.lib.php
similarity index 55%
rename from htdocs/printipp/lib/printipp.lib.php
rename to htdocs/printing/lib/printing.lib.php
index 64c14609df5ffd19f837820ca80c98777b2930c0..1d09daba0dc536ee88850af86d62caa057dcadda 100644
--- a/htdocs/printipp/lib/printipp.lib.php
+++ b/htdocs/printing/lib/printing.lib.php
@@ -16,44 +16,54 @@
  */
 
 /**
- *  \file           htdocs/printipp/lib/printipp.lib.php
- *  \ingroup        printipp
- *  \brief          Library for printipp functions
+ *  \file           htdocs/printing/lib/printing.lib.php
+ *  \ingroup        printing
+ *  \brief          Library for printing functions
  */
 
 
 
 /**
- *  Define head array for tabs of printipp tools setup pages
+ *  Define head array for tabs of printing tools setup pages
  *
  *  @return         Array of head
  */
-function printippadmin_prepare_head()
+function printingadmin_prepare_head()
 {
     global $langs, $conf;
 
     $h = 0;
     $head = array();
 
-    $head[$h][0] = DOL_URL_ROOT."/printipp/admin/printipp.php?mode=config";
-    $head[$h][1] = $langs->trans("CupsServer");
+    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=config";
+    $head[$h][1] = $langs->trans("ListDrivers");
     $head[$h][2] = 'config';
     $h++;
 
-    $head[$h][0] = DOL_URL_ROOT."/printipp/admin/printipp.php?mode=test";
-    $head[$h][1] = $langs->trans("Printer");
+    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=setup";
+    $head[$h][1] = $langs->trans("SetupDriver");
+    $head[$h][2] = 'setup';
+    $h++;
+
+    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=test";
+    $head[$h][1] = $langs->trans("TestDriver");
     $head[$h][2] = 'test';
     $h++;
 
-    $object=new stdClass();
+    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=userconf";
+    $head[$h][1] = $langs->trans("UserConf");
+    $head[$h][2] = 'userconf';
+    $h++;
+
+    //$object=new stdClass();
 
     // Show more tabs from modules
     // Entries must be declared in modules descriptor with line
     // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
     // $this->tabs = array('entity:-tabname);                                                   to remove a tab
-    complete_head_from_modules($conf,$langs,$object,$head,$h,'printippadmin');
+    //complete_head_from_modules($conf,$langs,$object,$head,$h,'printingadmin');
 
-    complete_head_from_modules($conf,$langs,$object,$head,$h,'printipp','remove');
+    //complete_head_from_modules($conf,$langs,$object,$head,$h,'printing','remove');
 
     return $head;
 }
diff --git a/htdocs/printipp/admin/printipp.php b/htdocs/printipp/admin/printipp.php
deleted file mode 100644
index 28ad55453eb42b3874f557878eb79eb4627e7cc5..0000000000000000000000000000000000000000
--- a/htdocs/printipp/admin/printipp.php
+++ /dev/null
@@ -1,246 +0,0 @@
-<?php
-/* Copyright (C) 2013 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- *      \file       htdocs/printipp/admin/printipp.php
- *      \ingroup    printipp
- *      \brief      Page to setup printipp module
- */
-
-require '../../main.inc.php';
-
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php';
-require_once DOL_DOCUMENT_ROOT.'/printipp/lib/printipp.lib.php';
-
-$langs->load("admin");
-$langs->load("printipp");
-
-if (! $user->admin) accessforbidden();
-
-$action = GETPOST('action','alpha');
-$mode = GETPOST('mode','alpha');
-$value = GETPOST('value','alpha');
-
-if (!$mode) $mode='config';
-
-/*
- * Action
- */
-
-if ($action == 'setvalue' && $user->admin)
-{
-    $db->begin();
-
-    if (! $result > 0) $error++;
-    $result=dolibarr_set_const($db, "PRINTIPP_HOST",GETPOST('PRINTIPP_HOST','alpha'),'chaine',0,'',$conf->entity);
-    if (! $result > 0) $error++;
-    $result=dolibarr_set_const($db, "PRINTIPP_PORT",GETPOST('PRINTIPP_PORT','alpha'),'chaine',0,'',$conf->entity);
-    if (! $result > 0) $error++;
-    $result=dolibarr_set_const($db, "PRINTIPP_USER",GETPOST('PRINTIPP_USER','alpha'),'chaine',0,'',$conf->entity);
-    if (! $result > 0) $error++;
-    $result=dolibarr_set_const($db, "PRINTIPP_PASSWORD",GETPOST('PRINTIPP_PASSWORD','alpha'),'chaine',0,'',$conf->entity);
-    if (! $result > 0) $error++;
-
-    if (! $error)
-    {
-        $db->commit();
-        setEventMessage($langs->trans("SetupSaved"));
-    }
-    else
-    {
-        $db->rollback();
-        dol_print_error($db);
-    }
-}
-
-// Set default model
-else if ($action == 'setprinteruri')
-{
-	if (dolibarr_set_const($db, "PRINTIPP_URI_DEFAULT",$value,'chaine',0,'',$conf->entity))
-	{
-		// La constante qui a ete lue en avant du nouveau set
-		// on passe donc par une variable pour avoir un affichage coherent
-		$conf->global->PRINTIPP_URI_DEFAULT = $value;
-	}
-}
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-llxHeader('',$langs->trans("PrintIPPSetup"));
-
-$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
-print_fiche_titre($langs->trans("PrintIPPSetup"),$linkback,'setup');
-
-$head=printippadmin_prepare_head();
-
-
-if ($mode == 'config' && $user->admin)
-{
-    print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=config">';
-    print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
-    print '<input type="hidden" name="action" value="setvalue">';
-
-	dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic');
-
-	print $langs->trans("PrintIPPDesc")."<br><br>\n";
-    
-    print '<table class="noborder" width="100%">';
-
-    $var=true;
-    print '<tr class="liste_titre">';
-    print '<td>'.$langs->trans("Parameters").'</td>';
-    print '<td>'.$langs->trans("Value").'</td>';
-    print "</tr>\n";
-
-    /*
-    $var=!$var;
-    print '<tr '.$bc[$var].'><td>';
-    print $langs->trans("PRINTIPP_ENABLED").'</td><td colspan="2" align="left">';
-
-    if (! empty($conf->use_javascript_ajax))
-    {
-        print ajax_constantonoff('PRINTIPP_ENABLED');
-    }
-    else
-    {
-        if (empty($conf->global->PRINTIPP_ENABLED))
-        {
-            print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_PRINTIPP_ENABLED">'.img_picto($langs->trans("Disabled"),'off').'</a>';
-         }
-         else
-         {
-             print '<a href="'.$_SERVER['PHP_SELF'].'?action=del_PRINTIPP_ENABLED">'.img_picto($langs->trans("Enabled"),'on').'</a>';
-         }
-    }
-    print '</td></tr>';
-	*/
-    
-    $var=!$var;
-    print '<tr '.$bc[$var].'><td class="fieldrequired">';
-    print $langs->trans("PRINTIPP_HOST").'</td><td>';
-    print '<input size="64" type="text" name="PRINTIPP_HOST" value="'.$conf->global->PRINTIPP_HOST.'">';
-    print ' &nbsp; '.$langs->trans("Example").': localhost';
-    print '</td></tr>';
-
-    $var=!$var;
-    print '<tr '.$bc[$var].'><td class="fieldrequired">';
-    print $langs->trans("PRINTIPP_PORT").'</td><td>';
-    print '<input size="32" type="text" name="PRINTIPP_PORT" value="'.$conf->global->PRINTIPP_PORT.'">';
-    print ' &nbsp; '.$langs->trans("Example").': 631';
-    print '</td></tr>';
-
-    $var=!$var;
-    print '<tr '.$bc[$var].'><td>';
-    print $langs->trans("PRINTIPP_USER").'</td><td>';
-    print '<input size="32" type="text" name="PRINTIPP_USER" value="'.$conf->global->PRINTIPP_USER.'">';
-    print '</td></tr>';
-
-    $var=!$var;
-    print '<tr '.$bc[$var].'><td>';
-    print $langs->trans("PRINTIPP_PASSWORD").'</td><td>';
-    print '<input size="32" type="text" name="PRINTIPP_PASSWORD" value="'.$conf->global->PRINTIPP_PASSWORD.'">';
-    print '</td></tr>';
-
-    //$var=true;
-    //print '<tr class="liste_titre">';
-    //print '<td>'.$langs->trans("OtherParameter").'</td>';
-    //print '<td>'.$langs->trans("Value").'</td>';
-    //print "</tr>\n";
-
-    print '</table>';
-
-    dol_fiche_end();
-    
-    print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Modify")).'"></center>';
-    
-    print '</form>';
-}
-
-if ($mode == 'test' && $user->admin)
-{
-	dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic');
-
-	print $langs->trans("PrintIPPDesc")."<br><br>\n";
-	
-	print '<table class="nobordernopadding" width="100%">';
-    $printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD);
-    $var=true;
-    print '<table width="100%" class="noborder">';
-    print '<tr class="liste_titre">';
-    print '<td>Uri</td>';
-    print '<td>Name</td>';
-    print '<td>State</td>';
-    print '<td>State_reason</td>';
-    print '<td>State_reason1</td>';
-    print '<td>BW</td>';
-    print '<td>Color</td>';
-    //print '<td>Device</td>';
-    print '<td>Media</td>';
-    print '<td>Supported</td>';
-    print '<td>'.$langs->trans("Select").'</td>';
-    print "</tr>\n";
-
-    $list = $printer->getlist_available_printers();
-    $var = true;
-    foreach ($list as $value)
-    {
-        $var=!$var;
-        $printer_det = $printer->get_printer_detail($value);
-        print "<tr ".$bc[$var].">";
-        print '<td>'.$value.'</td>';
-        //print '<td><pre>'.print_r($printer_det,true).'</pre></td>';
-        print '<td>'.$printer_det->printer_name->_value0.'</td>';
-        print '<td>'.$printer_det->printer_state->_value0.'</td>';
-        print '<td>'.$printer_det->printer_state_reasons->_value0.'</td>';
-        print '<td>'.$printer_det->printer_state_reasons->_value1.'</td>';
-        print '<td>'.$printer_det->printer_type->_value2.'</td>';
-        print '<td>'.$printer_det->printer_type->_value3.'</td>';
-        //print '<td>'.$printer_det->device_uri->_value0.'</td>';
-        print '<td>'.$printer_det->media_default->_value0.'</td>';
-        print '<td>'.$printer_det->media_type_supported->_value1.'</td>';
-        // Defaut
-        print "<td align=\"center\">";
-        if ($conf->global->PRINTIPP_URI_DEFAULT == "$value")
-        {
-        	print img_picto($langs->trans("Default"),'on');
-        }
-        else
-        {
-        	print '<a href="'.$_SERVER["PHP_SELF"].'?action=setprinteruri&mode=test&value='.urlencode($value).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>';
-        }
-        print '</td>';
-        print "</tr>\n";
-    }
-    print '</table>';
-
-    if (count($list) == 0) print $langs->trans("NoPrinterFound");
-
-	dol_fiche_end();
-}
-
-
-
-llxFooter();
-
-$db->close();