Continued:
[core.git] / framework / main / classes / class_BaseFrameworkSystem.php
1 <?php
2 // Own namespace
3 namespace CoreFramework\Object;
4
5 // Import framework stuff
6 use CoreFramework\Compressor\Compressor;
7 use CoreFramework\Configuration\FrameworkConfiguration;
8 use CoreFramework\Connection\Database\DatabaseConnection;
9 use CoreFramework\Controller\Controller;
10 use CoreFramework\Criteria\Criteria;
11 use CoreFramework\Criteria\Local\LocalSearchCriteria;
12 use CoreFramework\Criteria\Local\LocalUpdateCriteria;
13 use CoreFramework\Factory\Database\Wrapper\DatabaseWrapperFactory;
14 use CoreFramework\Factory\ObjectFactory;
15 use CoreFramework\Filesystem\FrameworkDirectory;
16 use CoreFramework\Generic\FrameworkInterface;
17 use CoreFramework\Generic\NullPointerException;
18 use CoreFramework\Handler\Stream\IoHandler;
19 use CoreFramework\Loader\ClassLoader;
20 use CoreFramework\Manager\ManageableApplication;
21 use CoreFramework\Middleware\Compressor\CompressorChannel;
22 use CoreFramework\Middleware\Debug\DebugMiddleware;
23 use CoreFramework\Parser\Parseable;
24 use CoreFramework\Registry\Register;
25 use CoreFramework\Registry\Registry;
26 use CoreFramework\Request\Requestable;
27 use CoreFramework\Resolver\Resolver;
28 use CoreFramework\Result\Database\CachedDatabaseResult;
29 use CoreFramework\Result\Search\SearchableResult;
30 use CoreFramework\Response\Responseable;
31 use CoreFramework\Stream\Output\OutputStreamer;
32 use CoreFramework\Template\CompileableTemplate;
33 use CoreFramework\Wrapper\Database\DatabaseWrapper;
34
35 // Import SPL stuff
36 use \stdClass;
37 use \ReflectionClass;
38
39 /**
40  * The simulator system class is the super class of all other classes. This
41  * class handles saving of games etc.
42  *
43  * @author              Roland Haeder <webmaster@shipsimu.org>
44  * @version             0.0.0
45  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
46  * @license             GNU GPL 3.0 or any newer version
47  * @link                http://www.shipsimu.org
48  *
49  * This program is free software: you can redistribute it and/or modify
50  * it under the terms of the GNU General Public License as published by
51  * the Free Software Foundation, either version 3 of the License, or
52  * (at your option) any later version.
53  *
54  * This program is distributed in the hope that it will be useful,
55  * but WITHOUT ANY WARRANTY; without even the implied warranty of
56  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
57  * GNU General Public License for more details.
58  *
59  * You should have received a copy of the GNU General Public License
60  * along with this program. If not, see <http://www.gnu.org/licenses/>.
61  */
62 class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
63         /**
64          * Length of output from hash()
65          */
66         private static $hashLength = NULL;
67
68         /**
69          * The real class name
70          */
71         private $realClass = 'BaseFrameworkSystem';
72
73         /**
74          * Instance of a Requestable class
75          */
76         private $requestInstance = NULL;
77
78         /**
79          * Instance of a Responseable class
80          */
81         private $responseInstance = NULL;
82
83         /**
84          * Search criteria instance
85          */
86         private $searchInstance = NULL;
87
88         /**
89          * Update criteria instance
90          */
91         private $updateInstance = NULL;
92
93         /**
94          * The file I/O instance for the template loader
95          */
96         private $fileIoInstance = NULL;
97
98         /**
99          * Resolver instance
100          */
101         private $resolverInstance = NULL;
102
103         /**
104          * Template engine instance
105          */
106         private $templateInstance = NULL;
107
108         /**
109          * Database result instance
110          */
111         private $resultInstance = NULL;
112
113         /**
114          * Instance for user class
115          */
116         private $userInstance = NULL;
117
118         /**
119          * A controller instance
120          */
121         private $controllerInstance = NULL;
122
123         /**
124          * Instance of a RNG
125          */
126         private $rngInstance = NULL;
127
128         /**
129          * Instance of a crypto helper
130          */
131         private $cryptoInstance = NULL;
132
133         /**
134          * Instance of an Iterator class
135          */
136         private $iteratorInstance = NULL;
137
138         /**
139          * Instance of the list
140          */
141         private $listInstance = NULL;
142
143         /**
144          * Instance of a menu
145          */
146         private $menuInstance = NULL;
147
148         /**
149          * Instance of the image
150          */
151         private $imageInstance = NULL;
152
153         /**
154          * Instance of the stacker
155          */
156         private $stackInstance = NULL;
157
158         /**
159          * A Compressor instance
160          */
161         private $compressorInstance = NULL;
162
163         /**
164          * A Parseable instance
165          */
166         private $parserInstance = NULL;
167
168         /**
169          * A HandleableProtocol instance
170          */
171         private $protocolInstance = NULL;
172
173         /**
174          * A database wrapper instance
175          */
176         private $databaseInstance = NULL;
177
178         /**
179          * A helper instance for the form
180          */
181         private $helperInstance = NULL;
182
183         /**
184          * An instance of a Source class
185          */
186         private $sourceInstance = NULL;
187
188         /**
189          * An instance of a UrlSource class
190          */
191         private $urlSourceInstance = NULL;
192
193         /**
194          * An instance of a InputStream class
195          */
196         private $inputStreamInstance = NULL;
197
198         /**
199          * An instance of a OutputStream class
200          */
201         private $outputStreamInstance = NULL;
202
203         /**
204          * Networkable handler instance
205          */
206         private $handlerInstance = NULL;
207
208         /**
209          * Visitor handler instance
210          */
211         private $visitorInstance = NULL;
212
213         /**
214          * DHT instance
215          */
216         private $dhtInstance = NULL;
217
218         /**
219          * An instance of a database wrapper class
220          */
221         private $wrapperInstance = NULL;
222
223         /**
224          * An instance of a file I/O pointer class (not handler)
225          */
226         private $pointerInstance = NULL;
227
228         /**
229          * An instance of an Indexable class
230          */
231         private $indexInstance = NULL;
232
233         /**
234          * An instance of a Block class
235          */
236         private $blockInstance = NULL;
237
238         /**
239          * A Minable instance
240          */
241         private $minableInstance = NULL;
242
243         /**
244          * A FrameworkDirectory instance
245          */
246         private $directoryInstance = NULL;
247
248         /**
249          * Listener instance
250          */
251         private $listenerInstance = NULL;
252
253         /**
254          * An instance of a communicator
255          */
256         private $communicatorInstance = NULL;
257
258         /**
259          * The concrete output instance
260          */
261         private $outputInstance = NULL;
262
263         /**
264          * State instance
265          */
266         private $stateInstance = NULL;
267
268         /**
269          * Thousands separator
270          */
271         private $thousands = '.'; // German
272
273         /**
274          * Decimal separator
275          */
276         private $decimals  = ','; // German
277
278         /**
279          * Socket resource
280          */
281         private $socketResource = FALSE;
282
283         /**
284          * Regular expression to use for validation
285          */
286         private $regularExpression = '';
287
288         /**
289          * Package data
290          */
291         private $packageData = array();
292
293         /**
294          * Generic array
295          */
296         private $genericArray = array();
297
298         /**
299          * Command name
300          */
301         private $commandName = '';
302
303         /**
304          * Controller name
305          */
306         private $controllerName = '';
307
308         /**
309          * Name of used protocol
310          */
311         private $protocolName = 'invalid';
312
313         /**
314          * Array with bitmasks and such for pack/unpack methods to support both
315          * 32-bit and 64-bit systems
316          */
317         private $packingData = array(
318                 32 => array(
319                         'step'   => 3,
320                         'left'   => 0xffff0000,
321                         'right'  => 0x0000ffff,
322                         'factor' => 16,
323                         'format' => 'II',
324                 ),
325                 64 => array(
326                         'step'   => 7,
327                         'left'   => 0xffffffff00000000,
328                         'right'  => 0x00000000ffffffff,
329                         'factor' => 32,
330                         'format' => 'NN'
331                 )
332         );
333
334         /**
335          * Simple 64-bit check, thanks to "Salman A" from stackoverflow.com:
336          *
337          * The integer size is 4 bytes on 32-bit and 8 bytes on a 64-bit system.
338          */
339         private $archArrayElement = FALSE;
340
341         /***********************
342          * Exception codes.... *
343          ***********************/
344
345         // @todo Try to clean these constants up
346         const EXCEPTION_IS_NULL_POINTER              = 0x001;
347         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
348         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
349         const EXCEPTION_MISSING_METHOD               = 0x004;
350         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
351         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
352         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
353         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
354         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
355         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
356         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
357         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
358         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
359         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
360         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
361         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
362         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
363         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
364         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
365         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
366         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
367         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
368         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
369         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
370         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
371         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
372         const EXCEPTION_INVALID_RESOURCE             = 0x01b;
373         const EXCEPTION_UNEXPECTED_OBJECT            = 0x01c;
374         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
375         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
376         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
377         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
378         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
379         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
380         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
381         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
382         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
383         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
384         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
385         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
386         const EXCEPTION_INVALID_STRING               = 0x029;
387         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
388         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
389         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
390         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
391         const EXCEPTION_UNSPPORTED_OPERATION         = 0x02e;
392         const EXCEPTION_FACTORY_REQUIRE_PARAMETER    = 0x02f;
393         const EXCEPTION_MISSING_ELEMENT              = 0x030;
394         const EXCEPTION_HEADERS_ALREADY_SENT         = 0x031;
395         const EXCEPTION_DEFAULT_CONTROLLER_GONE      = 0x032;
396         const EXCEPTION_CLASS_NOT_FOUND              = 0x033;
397         const EXCEPTION_REQUIRED_INTERFACE_MISSING   = 0x034;
398         const EXCEPTION_FATAL_ERROR                  = 0x035;
399         const EXCEPTION_FILE_NOT_FOUND               = 0x036;
400         const EXCEPTION_ASSERTION_FAILED             = 0x037;
401         const EXCEPTION_FILE_NOT_REACHABLE           = 0x038;
402         const EXCEPTION_FILE_CANNOT_BE_READ          = 0x039;
403         const EXCEPTION_FILE_CANNOT_BE_WRITTEN       = 0x03a;
404         const EXCEPTION_PATH_CANNOT_BE_WRITTEN       = 0x03b;
405         const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x03c;
406         const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x03d;
407
408         /**
409          * Hexadecimal->Decimal translation array
410          */
411         private static $hexdec = array(
412                 '0' => 0,
413                 '1' => 1,
414                 '2' => 2,
415                 '3' => 3,
416                 '4' => 4,
417                 '5' => 5,
418                 '6' => 6,
419                 '7' => 7,
420                 '8' => 8,
421                 '9' => 9,
422                 'a' => 10,
423                 'b' => 11,
424                 'c' => 12,
425                 'd' => 13,
426                 'e' => 14,
427                 'f' => 15
428         );
429
430         /**
431          * Decimal->hexadecimal translation array
432          */
433         private static $dechex = array(
434                  0 => '0',
435                  1 => '1',
436                  2 => '2',
437                  3 => '3',
438                  4 => '4',
439                  5 => '5',
440                  6 => '6',
441                  7 => '7',
442                  8 => '8',
443                  9 => '9',
444                 10 => 'a',
445                 11 => 'b',
446                 12 => 'c',
447                 13 => 'd',
448                 14 => 'e',
449                 15 => 'f'
450         );
451
452         /**
453          * Startup time in miliseconds
454          */
455         private static $startupTime = 0;
456
457         /**
458          * Protected super constructor
459          *
460          * @param       $className      Name of the class
461          * @return      void
462          */
463         protected function __construct ($className) {
464                 // Set real class
465                 $this->setRealClass($className);
466
467                 // Set configuration instance if no registry ...
468                 if (!$this instanceof Register) {
469                         // ... because registries doesn't need to be configured
470                         $this->setConfigInstance(FrameworkConfiguration::getSelfInstance());
471                 } // END - if
472
473                 // Is the startup time set? (0 cannot be TRUE anymore)
474                 if (self::$startupTime == 0) {
475                         // Then set it
476                         self::$startupTime = microtime(TRUE);
477                 } // END - if
478
479                 // Set array element
480                 $this->archArrayElement = (PHP_INT_SIZE === 8 ? 64 : 32);
481         }
482
483         /**
484          * Destructor for all classes. You should not call this method on your own.
485          *
486          * @return      void
487          */
488         public function __destruct () {
489                 // Flush any updated entries to the database
490                 $this->flushPendingUpdates();
491
492                 // Is this object already destroyed?
493                 if ($this->__toString() != 'DestructedObject') {
494                         // Destroy all informations about this class but keep some text about it alive
495                         $this->setRealClass('DestructedObject');
496                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
497                         // Already destructed object
498                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('[%s:] The object <span class="object_name">%s</span> is already destroyed.',
499                                 __CLASS__,
500                                 $this->__toString()
501                         ));
502                 } else {
503                         // Do not call this twice
504                         trigger_error(__METHOD__ . ': Called twice.');
505                         exit;
506                 }
507         }
508
509         /**
510          * The __call() method where all non-implemented methods end up
511          *
512          * @param       $methodName             Name of the missing method
513          * @args        $args                   Arguments passed to the method
514          * @return      void
515          */
516         public final function __call ($methodName, $args) {
517                 return self::__callStatic($methodName, $args);
518         }
519
520         /**
521          * The __callStatic() method where all non-implemented static methods end up
522          *
523          * @param       $methodName             Name of the missing method
524          * @args        $args                   Arguments passed to the method
525          * @return      void
526          */
527         public static final function __callStatic ($methodName, $args) {
528                 // Trace message
529                 //* PRINT-DEBUG: */ printf('[%s:%d]: methodName=%s,args[]=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $methodName, gettype($args));
530
531                 // Init argument string
532                 $argsString = '';
533
534                 // Is it NULL, empty or an array?
535                 if (is_null($args)) {
536                         // No arguments
537                         $argsString = 'NULL';
538                 } elseif (is_array($args)) {
539                         // Start braces
540                         $argsString = '(';
541
542                         // Some arguments are there
543                         foreach ($args as $arg) {
544                                 // Add data about the argument
545                                 $argsString .= gettype($arg) . ':';
546
547                                 if (is_null($arg)) {
548                                         // Found a NULL argument
549                                         $argsString .= 'NULL';
550                                 } elseif (is_string($arg)) {
551                                         // Add length for strings
552                                         $argsString .= strlen($arg);
553                                 } elseif ((is_int($arg)) || (is_float($arg))) {
554                                         // ... integer/float
555                                         $argsString .= $arg;
556                                 } elseif (is_array($arg)) {
557                                         // .. or size if array
558                                         $argsString .= count($arg);
559                                 } elseif (is_object($arg)) {
560                                         // Get reflection
561                                         $reflection = new ReflectionClass($arg);
562
563                                         // Is an other object, maybe no __toString() available
564                                         $argsString .= $reflection->getName();
565                                 } elseif ($arg === TRUE) {
566                                         // ... is boolean 'TRUE'
567                                         $argsString .= 'TRUE';
568                                 } elseif ($arg === FALSE) {
569                                         // ... is boolean 'FALSE'
570                                         $argsString .= 'FALSE';
571                                 }
572
573                                 // Comma for next one
574                                 $argsString .= ', ';
575                         } // END - foreach
576
577                         // Remove last comma
578                         if (substr($argsString, -2, 1) == ',') {
579                                 $argsString = substr($argsString, 0, -2);
580                         } // END - if
581
582                         // Close braces
583                         $argsString .= ')';
584                 } else {
585                         // Invalid arguments!
586                         $argsString = '!INVALID:' . gettype($args) . '!';
587                 }
588
589                 // Output stub message
590                 // @TODO __CLASS__ does always return BaseFrameworkSystem but not the extending (=child) class
591                 self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('[unknown::%s:] Stub! Args: %s',
592                         $methodName,
593                         $argsString
594                 ));
595
596                 // Return nothing
597                 return NULL;
598         }
599
600         /**
601          * Getter for $realClass
602          *
603          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
604          */
605         public function __toString () {
606                 return $this->realClass;
607         }
608
609         /**
610          * Magic method to catch setting of missing but set class fields/attributes
611          *
612          * @param       $name   Name of the field/attribute
613          * @param       $value  Value to store
614          * @return      void
615          */
616         public final function __set ($name, $value) {
617                 $this->debugBackTrace(sprintf('Tried to set a missing field. name=%s, value[%s]=%s',
618                         $name,
619                         gettype($value),
620                         print_r($value, TRUE)
621                 ));
622         }
623
624         /**
625          * Magic method to catch getting of missing fields/attributes
626          *
627          * @param       $name   Name of the field/attribute
628          * @return      void
629          */
630         public final function __get ($name) {
631                 $this->debugBackTrace(sprintf('Tried to get a missing field. name=%s',
632                         $name
633                 ));
634         }
635
636         /**
637          * Magic method to catch unsetting of missing fields/attributes
638          *
639          * @param       $name   Name of the field/attribute
640          * @return      void
641          */
642         public final function __unset ($name) {
643                 $this->debugBackTrace(sprintf('Tried to unset a missing field. name=%s',
644                         $name
645                 ));
646         }
647
648         /**
649          * Magic method to catch object serialization
650          *
651          * @return      $unsupported    Unsupported method
652          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
653          */
654         public final function __sleep () {
655                 throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
656         }
657
658         /**
659          * Magic method to catch object deserialization
660          *
661          * @return      $unsupported    Unsupported method
662          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
663          */
664         public final function __wakeup () {
665                 throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
666         }
667
668         /**
669          * Magic method to catch calls when an object instance is called
670          *
671          * @return      $unsupported    Unsupported method
672          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
673          */
674         public final function __invoke () {
675                 throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
676         }
677
678         /**
679          * Setter for the real class name
680          *
681          * @param       $realClass      Class name (string)
682          * @return      void
683          */
684         public final function setRealClass ($realClass) {
685                 // Set real class
686                 $this->realClass = (string) $realClass;
687         }
688
689         /**
690          * Setter for database result instance
691          *
692          * @param       $resultInstance         An instance of a database result class
693          * @return      void
694          * @todo        SearchableResult and UpdateableResult shall have a super interface to use here
695          */
696         protected final function setResultInstance (SearchableResult $resultInstance) {
697                 $this->resultInstance =  $resultInstance;
698         }
699
700         /**
701          * Getter for database result instance
702          *
703          * @return      $resultInstance         An instance of a database result class
704          */
705         public final function getResultInstance () {
706                 return $this->resultInstance;
707         }
708
709         /**
710          * Setter for template engine instances
711          *
712          * @param       $templateInstance       An instance of a template engine class
713          * @return      void
714          */
715         protected final function setTemplateInstance (CompileableTemplate $templateInstance) {
716                 $this->templateInstance = $templateInstance;
717         }
718
719         /**
720          * Getter for template engine instances
721          *
722          * @return      $templateInstance       An instance of a template engine class
723          */
724         protected final function getTemplateInstance () {
725                 return $this->templateInstance;
726         }
727
728         /**
729          * Setter for search instance
730          *
731          * @param       $searchInstance         Searchable criteria instance
732          * @return      void
733          */
734         public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
735                 $this->searchInstance = $searchInstance;
736         }
737
738         /**
739          * Getter for search instance
740          *
741          * @return      $searchInstance         Searchable criteria instance
742          */
743         public final function getSearchInstance () {
744                 return $this->searchInstance;
745         }
746
747         /**
748          * Setter for update instance
749          *
750          * @param       $updateInstance         An instance of a LocalUpdateCriteria clase
751          * @return      void
752          */
753         public final function setUpdateInstance (LocalUpdateCriteria $updateInstance) {
754                 $this->updateInstance = $updateInstance;
755         }
756
757         /**
758          * Getter for update instance
759          *
760          * @return      $updateInstance         Updateable criteria instance
761          */
762         public final function getUpdateInstance () {
763                 return $this->updateInstance;
764         }
765
766         /**
767          * Setter for resolver instance
768          *
769          * @param       $resolverInstance       Instance of a command resolver class
770          * @return      void
771          */
772         public final function setResolverInstance (Resolver $resolverInstance) {
773                 $this->resolverInstance = $resolverInstance;
774         }
775
776         /**
777          * Getter for resolver instance
778          *
779          * @return      $resolverInstance       Instance of a command resolver class
780          */
781         public final function getResolverInstance () {
782                 return $this->resolverInstance;
783         }
784
785         /**
786          * Setter for language instance
787          *
788          * @param       $configInstance         The configuration instance which shall
789          *                                                              be FrameworkConfiguration
790          * @return      void
791          */
792         public final function setConfigInstance (FrameworkConfiguration $configInstance) {
793                 Registry::getRegistry()->addInstance('config', $configInstance);
794         }
795
796         /**
797          * Getter for configuration instance
798          *
799          * @return      $configInstance         Configuration instance
800          */
801         public final function getConfigInstance () {
802                 $configInstance = Registry::getRegistry()->getInstance('config');
803                 return $configInstance;
804         }
805
806         /**
807          * Setter for debug instance
808          *
809          * @param       $debugInstance  The instance for debug output class
810          * @return      void
811          */
812         public final function setDebugInstance (DebugMiddleware $debugInstance) {
813                 Registry::getRegistry()->addInstance('debug', $debugInstance);
814         }
815
816         /**
817          * Getter for debug instance
818          *
819          * @return      $debugInstance  Instance to class DebugConsoleOutput or DebugWebOutput
820          */
821         public final function getDebugInstance () {
822                 // Get debug instance
823                 $debugInstance = Registry::getRegistry()->getInstance('debug');
824
825                 // Return it
826                 return $debugInstance;
827         }
828
829         /**
830          * Setter for web output instance
831          *
832          * @param       $webInstance    The instance for web output class
833          * @return      void
834          */
835         public final function setWebOutputInstance (OutputStreamer $webInstance) {
836                 Registry::getRegistry()->addInstance('web_output', $webInstance);
837         }
838
839         /**
840          * Getter for web output instance
841          *
842          * @return      $webOutputInstance - Instance to class WebOutput
843          */
844         public final function getWebOutputInstance () {
845                 $webOutputInstance = Registry::getRegistry()->getInstance('web_output');
846                 return $webOutputInstance;
847         }
848
849         /**
850          * Setter for database instance
851          *
852          * @param       $databaseInstance       The instance for the database connection (forced DatabaseConnection)
853          * @return      void
854          */
855         public final function setDatabaseInstance (DatabaseConnection $databaseInstance) {
856                 Registry::getRegistry()->addInstance('db_instance', $databaseInstance);
857         }
858
859         /**
860          * Getter for database layer
861          *
862          * @return      $databaseInstance       The database layer instance
863          */
864         public final function getDatabaseInstance () {
865                 // Get instance
866                 $databaseInstance = Registry::getRegistry()->getInstance('db_instance');
867
868                 // Return instance
869                 return $databaseInstance;
870         }
871
872         /**
873          * Setter for compressor channel
874          *
875          * @param       $compressorInstance             An instance of CompressorChannel
876          * @return      void
877          */
878         public final function setCompressorChannel (CompressorChannel $compressorInstance) {
879                 Registry::getRegistry()->addInstance('compressor', $compressorInstance);
880         }
881
882         /**
883          * Getter for compressor channel
884          *
885          * @return      $compressorInstance             The compressor channel
886          */
887         public final function getCompressorChannel () {
888                 $compressorInstance = Registry::getRegistry()->getInstance('compressor');
889                 return $compressorInstance;
890         }
891
892         /**
893          * Protected getter for a manageable application helper class
894          *
895          * @return      $applicationInstance    An instance of a manageable application helper class
896          */
897         protected final function getApplicationInstance () {
898                 $applicationInstance = Registry::getRegistry()->getInstance('application');
899                 return $applicationInstance;
900         }
901
902         /**
903          * Setter for a manageable application helper class
904          *
905          * @param       $applicationInstance    An instance of a manageable application helper class
906          * @return      void
907          */
908         public final function setApplicationInstance (ManageableApplication $applicationInstance) {
909                 Registry::getRegistry()->addInstance('application', $applicationInstance);
910         }
911
912         /**
913          * Setter for request instance
914          *
915          * @param       $requestInstance        An instance of a Requestable class
916          * @return      void
917          */
918         public final function setRequestInstance (Requestable $requestInstance) {
919                 $this->requestInstance = $requestInstance;
920         }
921
922         /**
923          * Getter for request instance
924          *
925          * @return      $requestInstance        An instance of a Requestable class
926          */
927         public final function getRequestInstance () {
928                 return $this->requestInstance;
929         }
930
931         /**
932          * Setter for response instance
933          *
934          * @param       $responseInstance       An instance of a Responseable class
935          * @return      void
936          */
937         public final function setResponseInstance (Responseable $responseInstance) {
938                 $this->responseInstance = $responseInstance;
939         }
940
941         /**
942          * Getter for response instance
943          *
944          * @return      $responseInstance       An instance of a Responseable class
945          */
946         public final function getResponseInstance () {
947                 return $this->responseInstance;
948         }
949
950         /**
951          * Private getter for language instance
952          *
953          * @return      $langInstance   An instance to the language sub-system
954          */
955         protected final function getLanguageInstance () {
956                 $langInstance = Registry::getRegistry()->getInstance('language');
957                 return $langInstance;
958         }
959
960         /**
961          * Setter for language instance
962          *
963          * @param       $langInstance   An instance to the language sub-system
964          * @return      void
965          * @see         LanguageSystem
966          */
967         public final function setLanguageInstance (ManageableLanguage $langInstance) {
968                 Registry::getRegistry()->addInstance('language', $langInstance);
969         }
970
971         /**
972          * Private getter for file IO instance
973          *
974          * @return      $fileIoInstance         An instance to the file I/O sub-system
975          */
976         protected final function getFileIoInstance () {
977                 return $this->fileIoInstance;
978         }
979
980         /**
981          * Setter for file I/O instance
982          *
983          * @param       $fileIoInstance         An instance to the file I/O sub-system
984          * @return      void
985          */
986         public final function setFileIoInstance (IoHandler $fileIoInstance) {
987                 $this->fileIoInstance = $fileIoInstance;
988         }
989
990         /**
991          * Protected setter for user instance
992          *
993          * @param       $userInstance   An instance of a user class
994          * @return      void
995          */
996         protected final function setUserInstance (ManageableAccount $userInstance) {
997                 $this->userInstance = $userInstance;
998         }
999
1000         /**
1001          * Getter for user instance
1002          *
1003          * @return      $userInstance   An instance of a user class
1004          */
1005         public final function getUserInstance () {
1006                 return $this->userInstance;
1007         }
1008
1009         /**
1010          * Setter for controller instance (this surely breaks a bit the MVC patterm)
1011          *
1012          * @param       $controllerInstance             An instance of the controller
1013          * @return      void
1014          */
1015         public final function setControllerInstance (Controller $controllerInstance) {
1016                 $this->controllerInstance = $controllerInstance;
1017         }
1018
1019         /**
1020          * Getter for controller instance (this surely breaks a bit the MVC patterm)
1021          *
1022          * @return      $controllerInstance             An instance of the controller
1023          */
1024         public final function getControllerInstance () {
1025                 return $this->controllerInstance;
1026         }
1027
1028         /**
1029          * Setter for RNG instance
1030          *
1031          * @param       $rngInstance    An instance of a random number generator (RNG)
1032          * @return      void
1033          */
1034         protected final function setRngInstance (RandomNumberGenerator $rngInstance) {
1035                 $this->rngInstance = $rngInstance;
1036         }
1037
1038         /**
1039          * Getter for RNG instance
1040          *
1041          * @return      $rngInstance    An instance of a random number generator (RNG)
1042          */
1043         public final function getRngInstance () {
1044                 return $this->rngInstance;
1045         }
1046
1047         /**
1048          * Setter for Cryptable instance
1049          *
1050          * @param       $cryptoInstance An instance of a Cryptable class
1051          * @return      void
1052          */
1053         protected final function setCryptoInstance (Cryptable $cryptoInstance) {
1054                 $this->cryptoInstance = $cryptoInstance;
1055         }
1056
1057         /**
1058          * Getter for Cryptable instance
1059          *
1060          * @return      $cryptoInstance An instance of a Cryptable class
1061          */
1062         public final function getCryptoInstance () {
1063                 return $this->cryptoInstance;
1064         }
1065
1066         /**
1067          * Setter for the list instance
1068          *
1069          * @param       $listInstance   A list of Listable
1070          * @return      void
1071          */
1072         protected final function setListInstance (Listable $listInstance) {
1073                 $this->listInstance = $listInstance;
1074         }
1075
1076         /**
1077          * Getter for the list instance
1078          *
1079          * @return      $listInstance   A list of Listable
1080          */
1081         protected final function getListInstance () {
1082                 return $this->listInstance;
1083         }
1084
1085         /**
1086          * Setter for the menu instance
1087          *
1088          * @param       $menuInstance   A RenderableMenu instance
1089          * @return      void
1090          */
1091         protected final function setMenuInstance (RenderableMenu $menuInstance) {
1092                 $this->menuInstance = $menuInstance;
1093         }
1094
1095         /**
1096          * Getter for the menu instance
1097          *
1098          * @return      $menuInstance   A RenderableMenu instance
1099          */
1100         protected final function getMenuInstance () {
1101                 return $this->menuInstance;
1102         }
1103
1104         /**
1105          * Setter for image instance
1106          *
1107          * @param       $imageInstance  An instance of an image
1108          * @return      void
1109          */
1110         public final function setImageInstance (BaseImage $imageInstance) {
1111                 $this->imageInstance = $imageInstance;
1112         }
1113
1114         /**
1115          * Getter for image instance
1116          *
1117          * @return      $imageInstance  An instance of an image
1118          */
1119         public final function getImageInstance () {
1120                 return $this->imageInstance;
1121         }
1122
1123         /**
1124          * Setter for stacker instance
1125          *
1126          * @param       $stackInstance  An instance of an stacker
1127          * @return      void
1128          */
1129         public final function setStackInstance (Stackable $stackInstance) {
1130                 $this->stackInstance = $stackInstance;
1131         }
1132
1133         /**
1134          * Getter for stacker instance
1135          *
1136          * @return      $stackInstance  An instance of an stacker
1137          */
1138         public final function getStackInstance () {
1139                 return $this->stackInstance;
1140         }
1141
1142         /**
1143          * Setter for compressor instance
1144          *
1145          * @param       $compressorInstance     An instance of an compressor
1146          * @return      void
1147          */
1148         public final function setCompressorInstance (Compressor $compressorInstance) {
1149                 $this->compressorInstance = $compressorInstance;
1150         }
1151
1152         /**
1153          * Getter for compressor instance
1154          *
1155          * @return      $compressorInstance     An instance of an compressor
1156          */
1157         public final function getCompressorInstance () {
1158                 return $this->compressorInstance;
1159         }
1160
1161         /**
1162          * Setter for Parseable instance
1163          *
1164          * @param       $parserInstance An instance of an Parseable
1165          * @return      void
1166          */
1167         public final function setParserInstance (Parseable $parserInstance) {
1168                 $this->parserInstance = $parserInstance;
1169         }
1170
1171         /**
1172          * Getter for Parseable instance
1173          *
1174          * @return      $parserInstance An instance of an Parseable
1175          */
1176         public final function getParserInstance () {
1177                 return $this->parserInstance;
1178         }
1179
1180         /**
1181          * Setter for HandleableProtocol instance
1182          *
1183          * @param       $protocolInstance       An instance of an HandleableProtocol
1184          * @return      void
1185          */
1186         public final function setProtocolInstance (HandleableProtocol $protocolInstance) {
1187                 $this->protocolInstance = $protocolInstance;
1188         }
1189
1190         /**
1191          * Getter for HandleableProtocol instance
1192          *
1193          * @return      $protocolInstance       An instance of an HandleableProtocol
1194          */
1195         public final function getProtocolInstance () {
1196                 return $this->protocolInstance;
1197         }
1198
1199         /**
1200          * Setter for DatabaseWrapper instance
1201          *
1202          * @param       $wrapperInstance        An instance of an DatabaseWrapper
1203          * @return      void
1204          */
1205         public final function setWrapperInstance (DatabaseWrapper $wrapperInstance) {
1206                 $this->wrapperInstance = $wrapperInstance;
1207         }
1208
1209         /**
1210          * Getter for DatabaseWrapper instance
1211          *
1212          * @return      $wrapperInstance        An instance of an DatabaseWrapper
1213          */
1214         public final function getWrapperInstance () {
1215                 return $this->wrapperInstance;
1216         }
1217
1218         /**
1219          * Setter for socket resource
1220          *
1221          * @param       $socketResource         A valid socket resource
1222          * @return      void
1223          */
1224         public final function setSocketResource ($socketResource) {
1225                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource=' . $socketResource . ',previous[' . gettype($this->socketResource) . ']=' . $this->socketResource);
1226                 $this->socketResource = $socketResource;
1227         }
1228
1229         /**
1230          * Getter for socket resource
1231          *
1232          * @return      $socketResource         A valid socket resource
1233          */
1234         public final function getSocketResource () {
1235                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource[' . gettype($this->socketResource) . ']=' . $this->socketResource);
1236                 return $this->socketResource;
1237         }
1238
1239         /**
1240          * Setter for regular expression
1241          *
1242          * @param       $regularExpression      A valid regular expression
1243          * @return      void
1244          */
1245         public final function setRegularExpression ($regularExpression) {
1246                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression=' . $regularExpression . ',previous[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
1247                 $this->regularExpression = $regularExpression;
1248         }
1249
1250         /**
1251          * Getter for regular expression
1252          *
1253          * @return      $regularExpression      A valid regular expression
1254          */
1255         public final function getRegularExpression () {
1256                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
1257                 return $this->regularExpression;
1258         }
1259
1260         /**
1261          * Setter for helper instance
1262          *
1263          * @param       $helperInstance         An instance of a helper class
1264          * @return      void
1265          */
1266         protected final function setHelperInstance (Helper $helperInstance) {
1267                 $this->helperInstance = $helperInstance;
1268         }
1269
1270         /**
1271          * Getter for helper instance
1272          *
1273          * @return      $helperInstance         An instance of a helper class
1274          */
1275         public final function getHelperInstance () {
1276                 return $this->helperInstance;
1277         }
1278
1279         /**
1280          * Setter for a Source instance
1281          *
1282          * @param       $sourceInstance         An instance of a Source class
1283          * @return      void
1284          */
1285         protected final function setSourceInstance (Source $sourceInstance) {
1286                 $this->sourceInstance = $sourceInstance;
1287         }
1288
1289         /**
1290          * Getter for a Source instance
1291          *
1292          * @return      $sourceInstance         An instance of a Source class
1293          */
1294         protected final function getSourceInstance () {
1295                 return $this->sourceInstance;
1296         }
1297
1298         /**
1299          * Setter for a UrlSource instance
1300          *
1301          * @param       $sourceInstance         An instance of a UrlSource class
1302          * @return      void
1303          */
1304         protected final function setUrlSourceInstance (UrlSource $urlSourceInstance) {
1305                 $this->urlSourceInstance = $urlSourceInstance;
1306         }
1307
1308         /**
1309          * Getter for a UrlSource instance
1310          *
1311          * @return      $urlSourceInstance              An instance of a UrlSource class
1312          */
1313         protected final function getUrlSourceInstance () {
1314                 return $this->urlSourceInstance;
1315         }
1316
1317         /**
1318          * Getter for a InputStream instance
1319          *
1320          * @param       $inputStreamInstance    The InputStream instance
1321          */
1322         protected final function getInputStreamInstance () {
1323                 return $this->inputStreamInstance;
1324         }
1325
1326         /**
1327          * Setter for a InputStream instance
1328          *
1329          * @param       $inputStreamInstance    The InputStream instance
1330          * @return      void
1331          */
1332         protected final function setInputStreamInstance (InputStream $inputStreamInstance) {
1333                 $this->inputStreamInstance = $inputStreamInstance;
1334         }
1335
1336         /**
1337          * Getter for a OutputStream instance
1338          *
1339          * @param       $outputStreamInstance   The OutputStream instance
1340          */
1341         protected final function getOutputStreamInstance () {
1342                 return $this->outputStreamInstance;
1343         }
1344
1345         /**
1346          * Setter for a OutputStream instance
1347          *
1348          * @param       $outputStreamInstance   The OutputStream instance
1349          * @return      void
1350          */
1351         protected final function setOutputStreamInstance (OutputStream $outputStreamInstance) {
1352                 $this->outputStreamInstance = $outputStreamInstance;
1353         }
1354
1355         /**
1356          * Setter for handler instance
1357          *
1358          * @param       $handlerInstance        An instance of a Handleable class
1359          * @return      void
1360          */
1361         protected final function setHandlerInstance (Handleable $handlerInstance) {
1362                 $this->handlerInstance = $handlerInstance;
1363         }
1364
1365         /**
1366          * Getter for handler instance
1367          *
1368          * @return      $handlerInstance        A Networkable instance
1369          */
1370         protected final function getHandlerInstance () {
1371                 return $this->handlerInstance;
1372         }
1373
1374         /**
1375          * Setter for visitor instance
1376          *
1377          * @param       $visitorInstance        A Visitor instance
1378          * @return      void
1379          */
1380         protected final function setVisitorInstance (Visitor $visitorInstance) {
1381                 $this->visitorInstance = $visitorInstance;
1382         }
1383
1384         /**
1385          * Getter for visitor instance
1386          *
1387          * @return      $visitorInstance        A Visitor instance
1388          */
1389         protected final function getVisitorInstance () {
1390                 return $this->visitorInstance;
1391         }
1392
1393         /**
1394          * Setter for DHT instance
1395          *
1396          * @param       $dhtInstance    A Distributable instance
1397          * @return      void
1398          */
1399         protected final function setDhtInstance (Distributable $dhtInstance) {
1400                 $this->dhtInstance = $dhtInstance;
1401         }
1402
1403         /**
1404          * Getter for DHT instance
1405          *
1406          * @return      $dhtInstance    A Distributable instance
1407          */
1408         protected final function getDhtInstance () {
1409                 return $this->dhtInstance;
1410         }
1411
1412         /**
1413          * Setter for raw package Data
1414          *
1415          * @param       $packageData    Raw package Data
1416          * @return      void
1417          */
1418         public final function setPackageData (array $packageData) {
1419                 $this->packageData = $packageData;
1420         }
1421
1422         /**
1423          * Getter for raw package Data
1424          *
1425          * @return      $packageData    Raw package Data
1426          */
1427         public function getPackageData () {
1428                 return $this->packageData;
1429         }
1430
1431
1432         /**
1433          * Setter for Iterator instance
1434          *
1435          * @param       $iteratorInstance       An instance of an Iterator
1436          * @return      void
1437          */
1438         protected final function setIteratorInstance (Iterator $iteratorInstance) {
1439                 $this->iteratorInstance = $iteratorInstance;
1440         }
1441
1442         /**
1443          * Getter for Iterator instance
1444          *
1445          * @return      $iteratorInstance       An instance of an Iterator
1446          */
1447         public final function getIteratorInstance () {
1448                 return $this->iteratorInstance;
1449         }
1450
1451         /**
1452          * Setter for FilePointer instance
1453          *
1454          * @param       $pointerInstance        An instance of an FilePointer class
1455          * @return      void
1456          */
1457         protected final function setPointerInstance (FilePointer $pointerInstance) {
1458                 $this->pointerInstance = $pointerInstance;
1459         }
1460
1461         /**
1462          * Getter for FilePointer instance
1463          *
1464          * @return      $pointerInstance        An instance of an FilePointer class
1465          */
1466         public final function getPointerInstance () {
1467                 return $this->pointerInstance;
1468         }
1469
1470         /**
1471          * Unsets pointer instance which triggers a call of __destruct() if the
1472          * instance is still there. This is surely not fatal on already "closed"
1473          * file pointer instances.
1474          *
1475          * I don't want to mess around with above setter by giving it a default
1476          * value NULL as setter should always explicitly only set (existing) object
1477          * instances and NULL is NULL.
1478          *
1479          * @return      void
1480          */
1481         protected final function unsetPointerInstance () {
1482                 // Simply it to NULL
1483                 $this->pointerInstance = NULL;
1484         }
1485
1486         /**
1487          * Setter for Indexable instance
1488          *
1489          * @param       $indexInstance  An instance of an Indexable class
1490          * @return      void
1491          */
1492         protected final function setIndexInstance (Indexable $indexInstance) {
1493                 $this->indexInstance = $indexInstance;
1494         }
1495
1496         /**
1497          * Getter for Indexable instance
1498          *
1499          * @return      $indexInstance  An instance of an Indexable class
1500          */
1501         public final function getIndexInstance () {
1502                 return $this->indexInstance;
1503         }
1504
1505         /**
1506          * Setter for Block instance
1507          *
1508          * @param       $blockInstance  An instance of an Block class
1509          * @return      void
1510          */
1511         protected final function setBlockInstance (Block $blockInstance) {
1512                 $this->blockInstance = $blockInstance;
1513         }
1514
1515         /**
1516          * Getter for Block instance
1517          *
1518          * @return      $blockInstance  An instance of an Block class
1519          */
1520         public final function getBlockInstance () {
1521                 return $this->blockInstance;
1522         }
1523
1524         /**
1525          * Setter for Minable instance
1526          *
1527          * @param       $minableInstance        A Minable instance
1528          * @return      void
1529          */
1530         protected final function setMinableInstance (Minable $minableInstance) {
1531                 $this->minableInstance = $minableInstance;
1532         }
1533
1534         /**
1535          * Getter for minable instance
1536          *
1537          * @return      $minableInstance        A Minable instance
1538          */
1539         protected final function getMinableInstance () {
1540                 return $this->minableInstance;
1541         }
1542
1543         /**
1544          * Setter for FrameworkDirectory instance
1545          *
1546          * @param       $directoryInstance      A FrameworkDirectory instance
1547          * @return      void
1548          */
1549         protected final function setDirectoryInstance (FrameworkDirectory $directoryInstance) {
1550                 $this->directoryInstance = $directoryInstance;
1551         }
1552
1553         /**
1554          * Getter for FrameworkDirectory instance
1555          *
1556          * @return      $directoryInstance      A FrameworkDirectory instance
1557          */
1558         protected final function getDirectoryInstance () {
1559                 return $this->directoryInstance;
1560         }
1561
1562         /**
1563          * Setter for listener instance
1564          *
1565          * @param       $listenerInstance       A Listenable instance
1566          * @return      void
1567          */
1568         protected final function setListenerInstance (Listenable $listenerInstance) {
1569                 $this->listenerInstance = $listenerInstance;
1570         }
1571
1572         /**
1573          * Getter for listener instance
1574          *
1575          * @return      $listenerInstance       A Listenable instance
1576          */
1577         protected final function getListenerInstance () {
1578                 return $this->listenerInstance;
1579         }
1580
1581         /**
1582          * Getter for communicator instance
1583          *
1584          * @return      $communicatorInstance   An instance of a Communicator class
1585          */
1586         public final function getCommunicatorInstance () {
1587                 return $this->communicatorInstance;
1588         }
1589
1590         /**
1591          * Setter for communicator instance
1592          *
1593          * @param       $communicatorInstance   An instance of a Communicator class
1594          * @return      void
1595          */
1596         protected final function setCommunicatorInstance (Communicator $communicatorInstance) {
1597                 $this->communicatorInstance = $communicatorInstance;
1598         }
1599
1600         /**
1601          * Setter for state instance
1602          *
1603          * @param       $stateInstance  A Stateable instance
1604          * @return      void
1605          */
1606         public final function setStateInstance (Stateable $stateInstance) {
1607                 $this->stateInstance = $stateInstance;
1608         }
1609
1610         /**
1611          * Getter for state instance
1612          *
1613          * @return      $stateInstance  A Stateable instance
1614          */
1615         public final function getStateInstance () {
1616                 return $this->stateInstance;
1617         }
1618
1619         /**
1620          * Setter for output instance
1621          *
1622          * @param       $outputInstance The debug output instance
1623          * @return      void
1624          */
1625         public final function setOutputInstance (OutputStreamer $outputInstance) {
1626                 $this->outputInstance = $outputInstance;
1627         }
1628
1629         /**
1630          * Getter for output instance
1631          *
1632          * @return      $outputInstance The debug output instance
1633          */
1634         public final function getOutputInstance () {
1635                 return $this->outputInstance;
1636         }
1637
1638         /**
1639          * Setter for command name
1640          *
1641          * @param       $commandName    Last validated command name
1642          * @return      void
1643          */
1644         protected final function setCommandName ($commandName) {
1645                 $this->commandName = $commandName;
1646         }
1647
1648         /**
1649          * Getter for command name
1650          *
1651          * @return      $commandName    Last validated command name
1652          */
1653         protected final function getCommandName () {
1654                 return $this->commandName;
1655         }
1656
1657         /**
1658          * Setter for controller name
1659          *
1660          * @param       $controllerName Last validated controller name
1661          * @return      void
1662          */
1663         protected final function setControllerName ($controllerName) {
1664                 $this->controllerName = $controllerName;
1665         }
1666
1667         /**
1668          * Getter for controller name
1669          *
1670          * @return      $controllerName Last validated controller name
1671          */
1672         protected final function getControllerName () {
1673                 return $this->controllerName;
1674         }
1675
1676         /**
1677          * Getter for protocol name
1678          *
1679          * @return      $protocolName   Name of used protocol
1680          */
1681         public final function getProtocolName () {
1682                 return $this->protocolName;
1683         }
1684
1685         /**
1686          * Setter for protocol name
1687          *
1688          * @param       $protocolName   Name of used protocol
1689          * @return      void
1690          */
1691         protected final function setProtocolName ($protocolName) {
1692                 $this->protocolName = $protocolName;
1693         }
1694
1695         /**
1696          * Checks whether an object equals this object. You should overwrite this
1697          * method to implement own equality checks
1698          *
1699          * @param       $objectInstance         An instance of a FrameworkInterface object
1700          * @return      $equals                         Whether both objects equals
1701          */
1702         public function equals (FrameworkInterface $objectInstance) {
1703                 // Now test it
1704                 $equals = ((
1705                         $this->__toString() == $objectInstance->__toString()
1706                 ) && (
1707                         $this->hashCode() == $objectInstance->hashCode()
1708                 ));
1709
1710                 // Return the result
1711                 return $equals;
1712         }
1713
1714         /**
1715          * Generates a generic hash code of this class. You should really overwrite
1716          * this method with your own hash code generator code. But keep KISS in mind.
1717          *
1718          * @return      $hashCode       A generic hash code respresenting this whole class
1719          */
1720         public function hashCode () {
1721                 // Simple hash code
1722                 return crc32($this->__toString());
1723         }
1724
1725         /**
1726          * Formats computer generated price values into human-understandable formats
1727          * with thousand and decimal separators.
1728          *
1729          * @param       $value          The in computer format value for a price
1730          * @param       $currency       The currency symbol (use HTML-valid characters!)
1731          * @param       $decNum         Number of decimals after commata
1732          * @return      $price          The for the current language formated price string
1733          * @throws      MissingDecimalsThousandsSeparatorException      If decimals or
1734          *                                                                                              thousands separator
1735          *                                                                                              is missing
1736          */
1737         public function formatCurrency ($value, $currency = '&euro;', $decNum = 2) {
1738                 // Are all required attriutes set?
1739                 if ((!isset($this->decimals)) || (!isset($this->thousands))) {
1740                         // Throw an exception
1741                         throw new MissingDecimalsThousandsSeparatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
1742                 } // END - if
1743
1744                 // Cast the number
1745                 $value = (float) $value;
1746
1747                 // Reformat the US number
1748                 $price = number_format($value, $decNum, $this->decimals, $this->thousands) . $currency;
1749
1750                 // Return as string...
1751                 return $price;
1752         }
1753
1754         /**
1755          * Appends a trailing slash to a string
1756          *
1757          * @param       $str    A string (maybe) without trailing slash
1758          * @return      $str    A string with an auto-appended trailing slash
1759          */
1760         public final function addMissingTrailingSlash ($str) {
1761                 // Is there a trailing slash?
1762                 if (substr($str, -1, 1) != '/') {
1763                         $str .= '/';
1764                 } // END - if
1765
1766                 // Return string with trailing slash
1767                 return $str;
1768         }
1769
1770         /**
1771          * Prepare the template engine (HtmlTemplateEngine by default) for a given
1772          * application helper instance (ApplicationHelper by default).
1773          *
1774          * @param               $applicationInstance    An application helper instance or
1775          *                                                                              null if we shall use the default
1776          * @return              $templateInstance               The template engine instance
1777          * @throws              NullPointerException    If the discovered application
1778          *                                                                              instance is still null
1779          */
1780         protected function prepareTemplateInstance (ManageableApplication $applicationInstance = NULL) {
1781                 // Is the application instance set?
1782                 if (is_null($applicationInstance)) {
1783                         // Get the current instance
1784                         $applicationInstance = $this->getApplicationInstance();
1785
1786                         // Still null?
1787                         if (is_null($applicationInstance)) {
1788                                 // Thrown an exception
1789                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1790                         } // END - if
1791                 } // END - if
1792
1793                 // Initialize the template engine
1794                 $templateInstance = ObjectFactory::createObjectByConfiguredName('html_template_class');
1795
1796                 // Return the prepared instance
1797                 return $templateInstance;
1798         }
1799
1800         /**
1801          * Debugs this instance by putting out it's full content
1802          *
1803          * @param       $message        Optional message to show in debug output
1804          * @return      void
1805          */
1806         public final function debugInstance ($message = '') {
1807                 // Restore the error handler to avoid trouble with missing array elements or undeclared variables
1808                 restore_error_handler();
1809
1810                 // Init content
1811                 $content = '';
1812
1813                 // Is a message set?
1814                 if (!empty($message)) {
1815                         // Construct message
1816                         $content = sprintf('<div class="debug_message">Message: %s</div>' . PHP_EOL, $message);
1817                 } // END - if
1818
1819                 // Generate the output
1820                 $content .= sprintf('<pre>%s</pre>',
1821                         trim(
1822                                 htmlentities(
1823                                         print_r($this, TRUE)
1824                                 )
1825                         )
1826                 );
1827
1828                 // Output it
1829                 ApplicationEntryPoint::app_exit(sprintf('<div class="debug_header">%s debug output:</div><div class="debug_content">%s</div>Loaded includes: <div class="debug_include_list">%s</div>',
1830                         $this->__toString(),
1831                         $content,
1832                         ClassLoader::getSelfInstance()->getPrintableIncludeList()
1833                 ));
1834         }
1835
1836         /**
1837          * Replaces control characters with printable output
1838          *
1839          * @param       $str    String with control characters
1840          * @return      $str    Replaced string
1841          */
1842         protected function replaceControlCharacters ($str) {
1843                 // Replace them
1844                 $str = str_replace(
1845                         chr(13), '[r]', str_replace(
1846                         chr(10), '[n]', str_replace(
1847                         chr(9) , '[t]',
1848                         $str
1849                 )));
1850
1851                 // Return it
1852                 return $str;
1853         }
1854
1855         /**
1856          * Output a partial stub message for the caller method
1857          *
1858          * @param       $message        An optional message to display
1859          * @return      void
1860          */
1861         protected function partialStub ($message = '') {
1862                 // Get the backtrace
1863                 $backtrace = debug_backtrace();
1864
1865                 // Generate the class::method string
1866                 $methodName = 'UnknownClass-&gt;unknownMethod';
1867                 if ((isset($backtrace[1]['class'])) && (isset($backtrace[1]['function']))) {
1868                         $methodName = $backtrace[1]['class'] . '-&gt;' . $backtrace[1]['function'];
1869                 } // END - if
1870
1871                 // Construct the full message
1872                 $stubMessage = sprintf('[%s:] Partial stub!',
1873                         $methodName
1874                 );
1875
1876                 // Is the extra message given?
1877                 if (!empty($message)) {
1878                         // Then add it as well
1879                         $stubMessage .= ' Message: ' . $message;
1880                 } // END - if
1881
1882                 // Debug instance is there?
1883                 if (!is_null($this->getDebugInstance())) {
1884                         // Output stub message
1885                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($stubMessage);
1886                 } else {
1887                         // Trigger an error
1888                         trigger_error($stubMessage);
1889                         exit;
1890                 }
1891         }
1892
1893         /**
1894          * Outputs a debug backtrace and stops further script execution
1895          *
1896          * @param       $message        An optional message to output
1897          * @param       $doExit         Whether exit the program (TRUE is default)
1898          * @return      void
1899          */
1900         public function debugBackTrace ($message = '', $doExit = TRUE) {
1901                 // Sorry, there is no other way getting this nice backtrace
1902                 if (!empty($message)) {
1903                         // Output message
1904                         printf('Message: %s<br />' . PHP_EOL, $message);
1905                 } // END - if
1906
1907                 print('<pre>');
1908                 debug_print_backtrace();
1909                 print('</pre>');
1910
1911                 // Exit program?
1912                 if ($doExit === TRUE) {
1913                         exit();
1914                 } // END - if
1915         }
1916
1917         /**
1918          * Creates an instance of a debugger instance
1919          *
1920          * @param       $className              Name of the class (currently unsupported)
1921          * @param       $lineNumber             Line number where the call was made
1922          * @return      $debugInstance  An instance of a debugger class
1923          * @deprecated  Not fully, as the new Logger facilities are not finished yet.
1924          */
1925         public final static function createDebugInstance ($className, $lineNumber = NULL) {
1926                 // Is the instance set?
1927                 if (!Registry::getRegistry()->instanceExists('debug')) {
1928                         // Init debug instance
1929                         $debugInstance = NULL;
1930
1931                         // Try it
1932                         try {
1933                                 // Get a debugger instance
1934                                 $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_' . self::getResponseTypeFromSystem() . '_class'), $className);
1935                         } catch (NullPointerException $e) {
1936                                 // Didn't work, no instance there
1937                                 exit(sprintf('Cannot create debugInstance! Exception=%s,message=%s,className=%s,lineNumber=%d' . PHP_EOL, $e->__toString(), $e->getMessage(), $className, $lineNumber));
1938                         }
1939
1940                         // Empty string should be ignored and used for testing the middleware
1941                         DebugMiddleware::getSelfInstance()->output('');
1942
1943                         // Set it in its own class. This will set it in the registry
1944                         $debugInstance->setDebugInstance($debugInstance);
1945                 } else {
1946                         // Get instance from registry
1947                         $debugInstance = Registry::getRegistry()->getDebugInstance();
1948                 }
1949
1950                 // Return it
1951                 return $debugInstance;
1952         }
1953
1954         /**
1955          * Simple output of a message with line-break
1956          *
1957          * @param       $message        Message to output
1958          * @return      void
1959          */
1960         public function outputLine ($message) {
1961                 // Simply output it
1962                 print($message . PHP_EOL);
1963         }
1964
1965         /**
1966          * Outputs a debug message whether to debug instance (should be set!) or
1967          * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
1968          * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
1969          *
1970          * @param       $message        Message we shall send out...
1971          * @param       $doPrint        Whether print or die here (default: print)
1972          * @paran       $stripTags      Whether to strip tags (default: FALSE)
1973          * @return      void
1974          */
1975         public function debugOutput ($message, $doPrint = TRUE, $stripTags = FALSE) {
1976                 // Set debug instance to NULL
1977                 $debugInstance = NULL;
1978
1979                 // Try it:
1980                 try {
1981                         // Get debug instance
1982                         $debugInstance = $this->getDebugInstance();
1983                 } catch (NullPointerException $e) {
1984                         // The debug instance is not set (yet)
1985                 }
1986
1987                 // Is the debug instance there?
1988                 if (is_object($debugInstance)) {
1989                         // Use debug output handler
1990                         $debugInstance->output($message, $stripTags);
1991
1992                         if ($doPrint === FALSE) {
1993                                 // Die here if not printed
1994                                 exit();
1995                         } // END - if
1996                 } else {
1997                         // Are debug times enabled?
1998                         if ($this->getConfigInstance()->getConfigEntry('debug_' . self::getResponseTypeFromSystem() . '_output_timings') == 'Y') {
1999                                 // Prepent it
2000                                 $message = $this->getPrintableExecutionTime() . $message;
2001                         } // END - if
2002
2003                         // Put directly out
2004                         if ($doPrint === TRUE) {
2005                                 // Print message
2006                                 $this->outputLine($message);
2007                         } else {
2008                                 // Die here
2009                                 exit($message);
2010                         }
2011                 }
2012         }
2013
2014         /**
2015          * Converts e.g. a command from URL to a valid class by keeping out bad characters
2016          *
2017          * @param       $str            The string, what ever it is needs to be converted
2018          * @return      $className      Generated class name
2019          */
2020         public static final function convertToClassName ($str) {
2021                 // Init class name
2022                 $className = '';
2023
2024                 // Convert all dashes in underscores
2025                 $str = self::convertDashesToUnderscores($str);
2026
2027                 // Now use that underscores to get classname parts for hungarian style
2028                 foreach (explode('_', $str) as $strPart) {
2029                         // Make the class name part lower case and first upper case
2030                         $className .= ucfirst(strtolower($strPart));
2031                 } // END - foreach
2032
2033                 // Return class name
2034                 return $className;
2035         }
2036
2037         /**
2038          * Converts dashes to underscores, e.g. useable for configuration entries
2039          *
2040          * @param       $str    The string with maybe dashes inside
2041          * @return      $str    The converted string with no dashed, but underscores
2042          */
2043         public static final function convertDashesToUnderscores ($str) {
2044                 // Convert them all
2045                 $str = str_replace('-', '_', $str);
2046
2047                 // Return converted string
2048                 return $str;
2049         }
2050
2051         /**
2052          * Marks up the code by adding e.g. line numbers
2053          *
2054          * @param       $phpCode                Unmarked PHP code
2055          * @return      $markedCode             Marked PHP code
2056          */
2057         public function markupCode ($phpCode) {
2058                 // Init marked code
2059                 $markedCode = '';
2060
2061                 // Get last error
2062                 $errorArray = error_get_last();
2063
2064                 // Init the code with error message
2065                 if (is_array($errorArray)) {
2066                         // Get error infos
2067                         $markedCode = sprintf('<div id="error_header">File: <span id="error_data">%s</span>, Line: <span id="error_data">%s</span>, Message: <span id="error_data">%s</span>, Type: <span id="error_data">%s</span></div>',
2068                                 basename($errorArray['file']),
2069                                 $errorArray['line'],
2070                                 $errorArray['message'],
2071                                 $errorArray['type']
2072                         );
2073                 } // END - if
2074
2075                 // Add line number to the code
2076                 foreach (explode(chr(10), $phpCode) as $lineNo => $code) {
2077                         // Add line numbers
2078                         $markedCode .= sprintf('<span id="code_line">%s</span>: %s' . PHP_EOL,
2079                                 ($lineNo + 1),
2080                                 htmlentities($code, ENT_QUOTES)
2081                         );
2082                 } // END - foreach
2083
2084                 // Return the code
2085                 return $markedCode;
2086         }
2087
2088         /**
2089          * Filter a given GMT timestamp (non Uni* stamp!) to make it look more
2090          * beatiful for web-based front-ends. If null is given a message id
2091          * null_timestamp will be resolved and returned.
2092          *
2093          * @param       $timestamp      Timestamp to prepare (filter) for display
2094          * @return      $readable       A readable timestamp
2095          */
2096         public function doFilterFormatTimestamp ($timestamp) {
2097                 // Default value to return
2098                 $readable = '???';
2099
2100                 // Is the timestamp null?
2101                 if (is_null($timestamp)) {
2102                         // Get a message string
2103                         $readable = $this->getLanguageInstance()->getMessage('null_timestamp');
2104                 } else {
2105                         switch ($this->getLanguageInstance()->getLanguageCode()) {
2106                                 case 'de': // German format is a bit different to default
2107                                         // Split the GMT stamp up
2108                                         $dateTime  = explode(' ', $timestamp  );
2109                                         $dateArray = explode('-', $dateTime[0]);
2110                                         $timeArray = explode(':', $dateTime[1]);
2111
2112                                         // Construct the timestamp
2113                                         $readable = sprintf($this->getConfigInstance()->getConfigEntry('german_date_time'),
2114                                                 $dateArray[0],
2115                                                 $dateArray[1],
2116                                                 $dateArray[2],
2117                                                 $timeArray[0],
2118                                                 $timeArray[1],
2119                                                 $timeArray[2]
2120                                         );
2121                                         break;
2122
2123                                 default: // Default is pass-through
2124                                         $readable = $timestamp;
2125                                         break;
2126                         } // END - switch
2127                 }
2128
2129                 // Return the stamp
2130                 return $readable;
2131         }
2132
2133         /**
2134          * Filter a given number into a localized number
2135          *
2136          * @param       $value          The raw value from e.g. database
2137          * @return      $localized      Localized value
2138          */
2139         public function doFilterFormatNumber ($value) {
2140                 // Generate it from config and localize dependencies
2141                 switch ($this->getLanguageInstance()->getLanguageCode()) {
2142                         case 'de': // German format is a bit different to default
2143                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), ',', '.');
2144                                 break;
2145
2146                         default: // US, etc.
2147                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), '.', ',');
2148                                 break;
2149                 } // END - switch
2150
2151                 // Return it
2152                 return $localized;
2153         }
2154
2155         /**
2156          * "Getter" for databse entry
2157          *
2158          * @return      $entry  An array with database entries
2159          * @throws      NullPointerException    If the database result is not found
2160          * @throws      InvalidDatabaseResultException  If the database result is invalid
2161          */
2162         protected final function getDatabaseEntry () {
2163                 // Is there an instance?
2164                 if (!$this->getResultInstance() instanceof SearchableResult) {
2165                         // Throw an exception here
2166                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
2167                 } // END - if
2168
2169                 // Rewind it
2170                 $this->getResultInstance()->rewind();
2171
2172                 // Do we have an entry?
2173                 if ($this->getResultInstance()->valid() === FALSE) {
2174                         // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available
2175                         throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
2176                 } // END - if
2177
2178                 // Get next entry
2179                 $this->getResultInstance()->next();
2180
2181                 // Fetch it
2182                 $entry = $this->getResultInstance()->current();
2183
2184                 // And return it
2185                 return $entry;
2186         }
2187
2188         /**
2189          * Getter for field name
2190          *
2191          * @param       $fieldName              Field name which we shall get
2192          * @return      $fieldValue             Field value from the user
2193          * @throws      NullPointerException    If the result instance is null
2194          */
2195         public final function getField ($fieldName) {
2196                 // Default field value
2197                 $fieldValue = NULL;
2198
2199                 // Get result instance
2200                 $resultInstance = $this->getResultInstance();
2201
2202                 // Is this instance null?
2203                 if (is_null($resultInstance)) {
2204                         // Then the user instance is no longer valid (expired cookies?)
2205                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
2206                 } // END - if
2207
2208                 // Get current array
2209                 $fieldArray = $resultInstance->current();
2210                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, TRUE).'</pre>');
2211
2212                 // Convert dashes to underscore
2213                 $fieldName2 = self::convertDashesToUnderscores($fieldName);
2214
2215                 // Does the field exist?
2216                 if ($this->isFieldSet($fieldName)) {
2217                         // Get it
2218                         $fieldValue = $fieldArray[$fieldName2];
2219                 } elseif (defined('DEVELOPER')) {
2220                         // Missing field entry, may require debugging
2221                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldArray<pre>=' . print_r($fieldArray, TRUE) . '</pre>,fieldName=' . $fieldName . ' not found!');
2222                 } else {
2223                         // Missing field entry, may require debugging
2224                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldName=' . $fieldName . ' not found!');
2225                 }
2226
2227                 // Return it
2228                 return $fieldValue;
2229         }
2230
2231         /**
2232          * Checks if given field is set
2233          *
2234          * @param       $fieldName      Field name to check
2235          * @return      $isSet          Whether the given field name is set
2236          * @throws      NullPointerException    If the result instance is null
2237          */
2238         public function isFieldSet ($fieldName) {
2239                 // Get result instance
2240                 $resultInstance = $this->getResultInstance();
2241
2242                 // Is this instance null?
2243                 if (is_null($resultInstance)) {
2244                         // Then the user instance is no longer valid (expired cookies?)
2245                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
2246                 } // END - if
2247
2248                 // Get current array
2249                 $fieldArray = $resultInstance->current();
2250                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . $this->__toString() . ':' . __LINE__ . '] fieldName=' . $fieldName . ',fieldArray=<pre>'.print_r($fieldArray, TRUE).'</pre>');
2251
2252                 // Convert dashes to underscore
2253                 $fieldName = self::convertDashesToUnderscores($fieldName);
2254
2255                 // Determine it
2256                 $isSet = isset($fieldArray[$fieldName]);
2257
2258                 // Return result
2259                 return $isSet;
2260         }
2261
2262         /**
2263          * Flushs all pending updates to the database layer
2264          *
2265          * @return      void
2266          */
2267         public function flushPendingUpdates () {
2268                 // Get result instance
2269                 $resultInstance = $this->getResultInstance();
2270
2271                 // Do we have data to update?
2272                 if ((is_object($resultInstance)) && ($resultInstance->ifDataNeedsFlush())) {
2273                         // Get wrapper class name config entry
2274                         $configEntry = $resultInstance->getUpdateInstance()->getWrapperConfigEntry();
2275
2276                         // Create object instance
2277                         $wrapperInstance = DatabaseWrapperFactory::createWrapperByConfiguredName($configEntry);
2278
2279                         // Yes, then send the whole result to the database layer
2280                         $wrapperInstance->doUpdateByResult($this->getResultInstance());
2281                 } // END - if
2282         }
2283
2284         /**
2285          * Outputs a deprecation warning to the developer.
2286          *
2287          * @param       $message        The message we shall output to the developer
2288          * @return      void
2289          * @todo        Write a logging mechanism for productive mode
2290          */
2291         public function deprecationWarning ($message) {
2292                 // Is developer mode active?
2293                 if (defined('DEVELOPER')) {
2294                         // Debug instance is there?
2295                         if (!is_null($this->getDebugInstance())) {
2296                                 // Output stub message
2297                                 self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($message);
2298                         } else {
2299                                 // Trigger an error
2300                                 trigger_error($message . "<br />\n");
2301                                 exit;
2302                         }
2303                 } else {
2304                         // @TODO Finish this part!
2305                         $this->partialStub('Developer mode inactive. Message:' . $message);
2306                 }
2307         }
2308
2309         /**
2310          * Checks whether the given PHP extension is loaded
2311          *
2312          * @param       $phpExtension   The PHP extension we shall check
2313          * @return      $isLoaded       Whether the PHP extension is loaded
2314          */
2315         public final function isPhpExtensionLoaded ($phpExtension) {
2316                 // Is it loaded?
2317                 $isLoaded = in_array($phpExtension, get_loaded_extensions());
2318
2319                 // Return result
2320                 return $isLoaded;
2321         }
2322
2323         /**
2324          * "Getter" as a time() replacement but with milliseconds. You should use this
2325          * method instead of the encapsulated getimeofday() function.
2326          *
2327          * @return      $milliTime      Timestamp with milliseconds
2328          */
2329         public function getMilliTime () {
2330                 // Get the time of day as float
2331                 $milliTime = gettimeofday(TRUE);
2332
2333                 // Return it
2334                 return $milliTime;
2335         }
2336
2337         /**
2338          * Idles (sleeps) for given milliseconds
2339          *
2340          * @return      $hasSlept       Whether it goes fine
2341          */
2342         public function idle ($milliSeconds) {
2343                 // Sleep is fine by default
2344                 $hasSlept = TRUE;
2345
2346                 // Idle so long with found function
2347                 if (function_exists('time_sleep_until')) {
2348                         // Get current time and add idle time
2349                         $sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
2350
2351                         // New PHP 5.1.0 function found, ignore errors
2352                         $hasSlept = @time_sleep_until($sleepUntil);
2353                 } else {
2354                         /*
2355                          * My Sun station doesn't have that function even with latest PHP
2356                          * package. :(
2357                          */
2358                         usleep($milliSeconds * 1000);
2359                 }
2360
2361                 // Return result
2362                 return $hasSlept;
2363         }
2364         /**
2365          * Converts a hexadecimal string, even with negative sign as first string to
2366          * a decimal number using BC functions.
2367          *
2368          * This work is based on comment #86673 on php.net documentation page at:
2369          * <http://de.php.net/manual/en/function.dechex.php#86673>
2370          *
2371          * @param       $hex    Hexadecimal string
2372          * @return      $dec    Decimal number
2373          */
2374         protected function hex2dec ($hex) {
2375                 // Convert to all lower-case
2376                 $hex = strtolower($hex);
2377
2378                 // Detect sign (negative/positive numbers)
2379                 $sign = '';
2380                 if (substr($hex, 0, 1) == '-') {
2381                         $sign = '-';
2382                         $hex = substr($hex, 1);
2383                 } // END - if
2384
2385                 // Decode the hexadecimal string into a decimal number
2386                 $dec = 0;
2387                 for ($i = strlen($hex) - 1, $e = 1; $i >= 0; $i--, $e = bcmul($e, 16)) {
2388                         $factor = self::$hexdec[substr($hex, $i, 1)];
2389                         $dec = bcadd($dec, bcmul($factor, $e));
2390                 } // END - for
2391
2392                 // Return the decimal number
2393                 return $sign . $dec;
2394         }
2395
2396         /**
2397          * Converts even very large decimal numbers, also signed, to a hexadecimal
2398          * string.
2399          *
2400          * This work is based on comment #97756 on php.net documentation page at:
2401          * <http://de.php.net/manual/en/function.hexdec.php#97756>
2402          *
2403          * @param       $dec            Decimal number, even with negative sign
2404          * @param       $maxLength      Optional maximum length of the string
2405          * @return      $hex    Hexadecimal string
2406          */
2407         protected function dec2hex ($dec, $maxLength = 0) {
2408                 // maxLength can be zero or devideable by 2
2409                 assert(($maxLength == 0) || (($maxLength % 2) == 0));
2410
2411                 // Detect sign (negative/positive numbers)
2412                 $sign = '';
2413                 if ($dec < 0) {
2414                         $sign = '-';
2415                         $dec = abs($dec);
2416                 } // END - if
2417
2418                 // Encode the decimal number into a hexadecimal string
2419                 $hex = '';
2420                 do {
2421                         $hex = self::$dechex[($dec % (2 ^ 4))] . $hex;
2422                         $dec /= (2 ^ 4);
2423                 } while ($dec >= 1);
2424
2425                 /*
2426                  * Leading zeros are required for hex-decimal "numbers". In some
2427                  * situations more leading zeros are wanted, so check for both
2428                  * conditions.
2429                  */
2430                 if ($maxLength > 0) {
2431                         // Prepend more zeros
2432                         $hex = str_pad($hex, $maxLength, '0', STR_PAD_LEFT);
2433                 } elseif ((strlen($hex) % 2) != 0) {
2434                         // Only make string's length dividable by 2
2435                         $hex = '0' . $hex;
2436                 }
2437
2438                 // Return the hexadecimal string
2439                 return $sign . $hex;
2440         }
2441
2442         /**
2443          * Converts a ASCII string (0 to 255) into a decimal number.
2444          *
2445          * @param       $asc    The ASCII string to be converted
2446          * @return      $dec    Decimal number
2447          */
2448         protected function asc2dec ($asc) {
2449                 // Convert it into a hexadecimal number
2450                 $hex = bin2hex($asc);
2451
2452                 // And back into a decimal number
2453                 $dec = $this->hex2dec($hex);
2454
2455                 // Return it
2456                 return $dec;
2457         }
2458
2459         /**
2460          * Converts a decimal number into an ASCII string.
2461          *
2462          * @param       $dec            Decimal number
2463          * @return      $asc    An ASCII string
2464          */
2465         protected function dec2asc ($dec) {
2466                 // First convert the number into a hexadecimal string
2467                 $hex = $this->dec2hex($dec);
2468
2469                 // Then convert it into the ASCII string
2470                 $asc = $this->hex2asc($hex);
2471
2472                 // Return it
2473                 return $asc;
2474         }
2475
2476         /**
2477          * Converts a hexadecimal number into an ASCII string. Negative numbers
2478          * are not allowed.
2479          *
2480          * @param       $hex    Hexadecimal string
2481          * @return      $asc    An ASCII string
2482          */
2483         protected function hex2asc ($hex) {
2484                 // Check for length, it must be devideable by 2
2485                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('hex='.$hex);
2486                 assert((strlen($hex) % 2) == 0);
2487
2488                 // Walk the string
2489                 $asc = '';
2490                 for ($idx = 0; $idx < strlen($hex); $idx+=2) {
2491                         // Get the decimal number of the chunk
2492                         $part = hexdec(substr($hex, $idx, 2));
2493
2494                         // Add it to the final string
2495                         $asc .= chr($part);
2496                 } // END - for
2497
2498                 // Return the final string
2499                 return $asc;
2500         }
2501
2502         /**
2503          * Checks whether the given encoded data was encoded with Base64
2504          *
2505          * @param       $encodedData    Encoded data we shall check
2506          * @return      $isBase64               Whether the encoded data is Base64
2507          */
2508         protected function isBase64Encoded ($encodedData) {
2509                 // Determine it
2510                 $isBase64 = (@base64_decode($encodedData, TRUE) !== FALSE);
2511
2512                 // Return it
2513                 return $isBase64;
2514         }
2515
2516         /**
2517          * "Getter" to get response/request type from analysis of the system.
2518          *
2519          * @return      $responseType   Analyzed response type
2520          */
2521         protected static function getResponseTypeFromSystem () {
2522                 // Default is console
2523                 $responseType = 'console';
2524
2525                 // Is 'HTTP_HOST' set?
2526                 if (isset($_SERVER['HTTP_HOST'])) {
2527                         /*
2528                          * Then it is a HTML response/request as RSS and so on may be
2529                          * transfered over HTTP as well.
2530                          */
2531                         $responseType = 'html';
2532                 } // END - if
2533
2534                 // Return it
2535                 return $responseType;
2536         }
2537
2538         /**
2539          * Gets a cache key from Criteria instance
2540          *
2541          * @param       $criteriaInstance       An instance of a Criteria class
2542          * @param       $onlyKeys                       Only use these keys for a cache key
2543          * @return      $cacheKey                       A cache key suitable for lookup/storage purposes
2544          */
2545         protected function getCacheKeyByCriteria (Criteria $criteriaInstance, array $onlyKeys = array()) {
2546                 // Generate it
2547                 $cacheKey = sprintf('%s@%s',
2548                         $this->__toString(),
2549                         $criteriaInstance->getCacheKey($onlyKeys)
2550                 );
2551
2552                 // And return it
2553                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . ': cacheKey=' . $cacheKey);
2554                 return $cacheKey;
2555         }
2556
2557         /**
2558          * Getter for startup time in miliseconds
2559          *
2560          * @return      $startupTime    Startup time in miliseconds
2561          */
2562         protected function getStartupTime () {
2563                 return self::$startupTime;
2564         }
2565
2566         /**
2567          * "Getter" for a printable currently execution time in nice braces
2568          *
2569          * @return      $executionTime  Current execution time in nice braces
2570          */
2571         protected function getPrintableExecutionTime () {
2572                 // Caculate the execution time
2573                 $executionTime = microtime(TRUE) - $this->getStartupTime();
2574
2575                 // Pack it in nice braces
2576                 $executionTime = sprintf('[ %01.5f ] ', $executionTime);
2577
2578                 // And return it
2579                 return $executionTime;
2580         }
2581
2582         /**
2583          * Hashes a given string with a simple but stronger hash function (no salt)
2584          * and hex-encode it.
2585          *
2586          * @param       $str    The string to be hashed
2587          * @return      $hash   The hash from string $str
2588          */
2589         public static final function hash ($str) {
2590                 // Hash given string with (better secure) hasher
2591                 $hash = bin2hex(mhash(MHASH_SHA256, $str));
2592
2593                 // Return it
2594                 return $hash;
2595         }
2596
2597         /**
2598          * "Getter" for length of hash() output. This will be "cached" to speed up
2599          * things.
2600          *
2601          * @return      $length         Length of hash() output
2602          */
2603         public static final function getHashLength () {
2604                 // Is it cashed?
2605                 if (is_null(self::$hashLength)) {
2606                         // No, then hash a string and save its length.
2607                         self::$hashLength = strlen(self::hash('abc123'));
2608                 } // END - if
2609
2610                 // Return it
2611                 return self::$hashLength;
2612         }
2613
2614         /**
2615          * Checks whether the given number is really a number (only chars 0-9).
2616          *
2617          * @param       $num            A string consisting only chars between 0 and 9
2618          * @param       $castValue      Whether to cast the value to double. Do only use this to secure numbers from Requestable classes.
2619          * @param       $assertMismatch         Whether to assert mismatches
2620          * @return      $ret            The (hopefully) secured numbered value
2621          */
2622         public function bigintval ($num, $castValue = TRUE, $assertMismatch = FALSE) {
2623                 // Filter all numbers out
2624                 $ret = preg_replace('/[^0123456789]/', '', $num);
2625
2626                 // Shall we cast?
2627                 if ($castValue === TRUE) {
2628                         // Cast to biggest numeric type
2629                         $ret = (double) $ret;
2630                 } // END - if
2631
2632                 // Assert only if requested
2633                 if ($assertMismatch === TRUE) {
2634                         // Has the whole value changed?
2635                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2636                 } // END - if
2637
2638                 // Return result
2639                 return $ret;
2640         }
2641
2642         /**
2643          * Checks whether the given hexadecimal number is really a hex-number (only chars 0-9,a-f).
2644          *
2645          * @param       $num    A string consisting only chars between 0 and 9
2646          * @param       $assertMismatch         Whether to assert mismatches
2647          * @return      $ret    The (hopefully) secured hext-numbered value
2648          */
2649         public function hexval ($num, $assertMismatch = FALSE) {
2650                 // Filter all numbers out
2651                 $ret = preg_replace('/[^0123456789abcdefABCDEF]/', '', $num);
2652
2653                 // Assert only if requested
2654                 if ($assertMismatch === TRUE) {
2655                         // Has the whole value changed?
2656                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2657                 } // END - if
2658
2659                 // Return result
2660                 return $ret;
2661         }
2662
2663         /**
2664          * Checks whether start/end marker are set
2665          *
2666          * @param       $data   Data to be checked
2667          * @return      $isset  Whether start/end marker are set
2668          */
2669         public final function ifStartEndMarkersSet ($data) {
2670                 // Determine it
2671                 $isset = ((substr($data, 0, strlen(BaseRawDataHandler::STREAM_START_MARKER)) == BaseRawDataHandler::STREAM_START_MARKER) && (substr($data, -1 * strlen(BaseRawDataHandler::STREAM_END_MARKER), strlen(BaseRawDataHandler::STREAM_END_MARKER)) == BaseRawDataHandler::STREAM_END_MARKER));
2672
2673                 // ... and return it
2674                 return $isset;
2675         }
2676
2677         /**
2678          * Determines if an element is set in the generic array
2679          *
2680          * @param       $keyGroup       Main group for the key
2681          * @param       $subGroup       Sub group for the key
2682          * @param       $key            Key to check
2683          * @param       $element        Element to check
2684          * @return      $isset          Whether the given key is set
2685          */
2686         protected final function isGenericArrayElementSet ($keyGroup, $subGroup, $key, $element) {
2687                 // Debug message
2688                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2689
2690                 // Is it there?
2691                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
2692
2693                 // Return it
2694                 return $isset;
2695         }
2696         /**
2697          * Determines if a key is set in the generic array
2698          *
2699          * @param       $keyGroup       Main group for the key
2700          * @param       $subGroup       Sub group for the key
2701          * @param       $key            Key to check
2702          * @return      $isset          Whether the given key is set
2703          */
2704         protected final function isGenericArrayKeySet ($keyGroup, $subGroup, $key) {
2705                 // Debug message
2706                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2707
2708                 // Is it there?
2709                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key]);
2710
2711                 // Return it
2712                 return $isset;
2713         }
2714
2715
2716         /**
2717          * Determines if a group is set in the generic array
2718          *
2719          * @param       $keyGroup       Main group
2720          * @param       $subGroup       Sub group
2721          * @return      $isset          Whether the given group is set
2722          */
2723         protected final function isGenericArrayGroupSet ($keyGroup, $subGroup) {
2724                 // Debug message
2725                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
2726
2727                 // Is it there?
2728                 $isset = isset($this->genericArray[$keyGroup][$subGroup]);
2729
2730                 // Return it
2731                 return $isset;
2732         }
2733
2734         /**
2735          * Getter for sub key group
2736          *
2737          * @param       $keyGroup       Main key group
2738          * @param       $subGroup       Sub key group
2739          * @return      $array          An array with all array elements
2740          */
2741         protected final function getGenericSubArray ($keyGroup, $subGroup) {
2742                 // Is it there?
2743                 if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
2744                         // No, then abort here
2745                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
2746                         exit;
2747                 } // END - if
2748
2749                 // Debug message
2750                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',value=' . print_r($this->genericArray[$keyGroup][$subGroup], TRUE));
2751
2752                 // Return it
2753                 return $this->genericArray[$keyGroup][$subGroup];
2754         }
2755
2756         /**
2757          * Unsets a given key in generic array
2758          *
2759          * @param       $keyGroup       Main group for the key
2760          * @param       $subGroup       Sub group for the key
2761          * @param       $key            Key to unset
2762          * @return      void
2763          */
2764         protected final function unsetGenericArrayKey ($keyGroup, $subGroup, $key) {
2765                 // Debug message
2766                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2767
2768                 // Remove it
2769                 unset($this->genericArray[$keyGroup][$subGroup][$key]);
2770         }
2771
2772         /**
2773          * Unsets a given element in generic array
2774          *
2775          * @param       $keyGroup       Main group for the key
2776          * @param       $subGroup       Sub group for the key
2777          * @param       $key            Key to unset
2778          * @param       $element        Element to unset
2779          * @return      void
2780          */
2781         protected final function unsetGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
2782                 // Debug message
2783                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2784
2785                 // Remove it
2786                 unset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
2787         }
2788
2789         /**
2790          * Append a string to a given generic array key
2791          *
2792          * @param       $keyGroup       Main group for the key
2793          * @param       $subGroup       Sub group for the key
2794          * @param       $key            Key to unset
2795          * @param       $value          Value to add/append
2796          * @return      void
2797          */
2798         protected final function appendStringToGenericArrayKey ($keyGroup, $subGroup, $key, $value, $appendGlue = '') {
2799                 // Debug message
2800                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, TRUE) . ',appendGlue=' . $appendGlue);
2801
2802                 // Is it already there?
2803                 if ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2804                         // Append it
2805                         $this->genericArray[$keyGroup][$subGroup][$key] .= $appendGlue . (string) $value;
2806                 } else {
2807                         // Add it
2808                         $this->genericArray[$keyGroup][$subGroup][$key] = (string) $value;
2809                 }
2810         }
2811
2812         /**
2813          * Append a string to a given generic array element
2814          *
2815          * @param       $keyGroup       Main group for the key
2816          * @param       $subGroup       Sub group for the key
2817          * @param       $key            Key to unset
2818          * @param       $element        Element to check
2819          * @param       $value          Value to add/append
2820          * @return      void
2821          */
2822         protected final function appendStringToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value, $appendGlue = '') {
2823                 // Debug message
2824                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, TRUE) . ',appendGlue=' . $appendGlue);
2825
2826                 // Is it already there?
2827                 if ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2828                         // Append it
2829                         $this->genericArray[$keyGroup][$subGroup][$key][$element] .= $appendGlue . (string) $value;
2830                 } else {
2831                         // Add it
2832                         $this->setStringGenericArrayElement($keyGroup, $subGroup, $key, $element, $value);
2833                 }
2834         }
2835
2836         /**
2837          * Sets a string in a given generic array element
2838          *
2839          * @param       $keyGroup       Main group for the key
2840          * @param       $subGroup       Sub group for the key
2841          * @param       $key            Key to unset
2842          * @param       $element        Element to check
2843          * @param       $value          Value to add/append
2844          * @return      void
2845          */
2846         protected final function setStringGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value, $appendGlue = '') {
2847                 // Debug message
2848                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, TRUE) . ',appendGlue=' . $appendGlue);
2849
2850                 // Set it
2851                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = (string) $value;
2852         }
2853
2854         /**
2855          * Initializes given generic array group
2856          *
2857          * @param       $keyGroup       Main group for the key
2858          * @param       $subGroup       Sub group for the key
2859          * @param       $key            Key to use
2860          * @param       $forceInit      Optionally force initialization
2861          * @return      void
2862          */
2863         protected final function initGenericArrayGroup ($keyGroup, $subGroup, $forceInit = FALSE) {
2864                 // Debug message
2865                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',forceInit=' . intval($forceInit));
2866
2867                 // Is it already set?
2868                 if (($forceInit === FALSE) && ($this->isGenericArrayGroupSet($keyGroup, $subGroup))) {
2869                         // Already initialized
2870                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' already initialized.');
2871                         exit;
2872                 } // END - if
2873
2874                 // Initialize it
2875                 $this->genericArray[$keyGroup][$subGroup] = array();
2876         }
2877
2878         /**
2879          * Initializes given generic array key
2880          *
2881          * @param       $keyGroup       Main group for the key
2882          * @param       $subGroup       Sub group for the key
2883          * @param       $key            Key to use
2884          * @param       $forceInit      Optionally force initialization
2885          * @return      void
2886          */
2887         protected final function initGenericArrayKey ($keyGroup, $subGroup, $key, $forceInit = FALSE) {
2888                 // Debug message
2889                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',forceInit=' . intval($forceInit));
2890
2891                 // Is it already set?
2892                 if (($forceInit === FALSE) && ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key))) {
2893                         // Already initialized
2894                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' already initialized.');
2895                         exit;
2896                 } // END - if
2897
2898                 // Initialize it
2899                 $this->genericArray[$keyGroup][$subGroup][$key] = array();
2900         }
2901
2902         /**
2903          * Initializes given generic array element
2904          *
2905          * @param       $keyGroup       Main group for the key
2906          * @param       $subGroup       Sub group for the key
2907          * @param       $key            Key to use
2908          * @param       $element        Element to use
2909          * @param       $forceInit      Optionally force initialization
2910          * @return      void
2911          */
2912         protected final function initGenericArrayElement ($keyGroup, $subGroup, $key, $element, $forceInit = FALSE) {
2913                 // Debug message
2914                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',forceInit=' . intval($forceInit));
2915
2916                 // Is it already set?
2917                 if (($forceInit === FALSE) && ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element))) {
2918                         // Already initialized
2919                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' already initialized.');
2920                         exit;
2921                 } // END - if
2922
2923                 // Initialize it
2924                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = array();
2925         }
2926
2927         /**
2928          * Pushes an element to a generic key
2929          *
2930          * @param       $keyGroup       Main group for the key
2931          * @param       $subGroup       Sub group for the key
2932          * @param       $key            Key to use
2933          * @param       $value          Value to add/append
2934          * @return      $count          Number of array elements
2935          */
2936         protected final function pushValueToGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
2937                 // Debug message
2938                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, TRUE));
2939
2940                 // Is it set?
2941                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2942                         // Initialize array
2943                         $this->initGenericArrayKey($keyGroup, $subGroup, $key);
2944                 } // END - if
2945
2946                 // Then push it
2947                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key], $value);
2948
2949                 // Return count
2950                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], TRUE));
2951                 //* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
2952                 return $count;
2953         }
2954
2955         /**
2956          * Pushes an element to a generic array element
2957          *
2958          * @param       $keyGroup       Main group for the key
2959          * @param       $subGroup       Sub group for the key
2960          * @param       $key            Key to use
2961          * @param       $element        Element to check
2962          * @param       $value          Value to add/append
2963          * @return      $count          Number of array elements
2964          */
2965         protected final function pushValueToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
2966                 // Debug message
2967                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, TRUE));
2968
2969                 // Is it set?
2970                 if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2971                         // Initialize array
2972                         $this->initGenericArrayElement($keyGroup, $subGroup, $key, $element);
2973                 } // END - if
2974
2975                 // Then push it
2976                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key][$element], $value);
2977
2978                 // Return count
2979                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], TRUE));
2980                 //* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
2981                 return $count;
2982         }
2983
2984         /**
2985          * Pops an element from  a generic group
2986          *
2987          * @param       $keyGroup       Main group for the key
2988          * @param       $subGroup       Sub group for the key
2989          * @param       $key            Key to unset
2990          * @return      $value          Last "popped" value
2991          */
2992         protected final function popGenericArrayElement ($keyGroup, $subGroup, $key) {
2993                 // Debug message
2994                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2995
2996                 // Is it set?
2997                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2998                         // Not found
2999                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
3000                         exit;
3001                 } // END - if
3002
3003                 // Then "pop" it
3004                 $value = array_pop($this->genericArray[$keyGroup][$subGroup][$key]);
3005
3006                 // Return value
3007                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], TRUE));
3008                 //* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, TRUE) . PHP_EOL);
3009                 return $value;
3010         }
3011
3012         /**
3013          * Shifts an element from  a generic group
3014          *
3015          * @param       $keyGroup       Main group for the key
3016          * @param       $subGroup       Sub group for the key
3017          * @param       $key            Key to unset
3018          * @return      $value          Last "popped" value
3019          */
3020         protected final function shiftGenericArrayElement ($keyGroup, $subGroup, $key) {
3021                 // Debug message
3022                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
3023
3024                 // Is it set?
3025                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
3026                         // Not found
3027                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
3028                         exit;
3029                 } // END - if
3030
3031                 // Then "shift" it
3032                 $value = array_shift($this->genericArray[$keyGroup][$subGroup][$key]);
3033
3034                 // Return value
3035                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], TRUE));
3036                 //* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, TRUE) . PHP_EOL);
3037                 return $value;
3038         }
3039
3040         /**
3041          * Count generic array group
3042          *
3043          * @param       $keyGroup       Main group for the key
3044          * @return      $count          Count of given group
3045          */
3046         protected final function countGenericArray ($keyGroup) {
3047                 // Debug message
3048                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
3049
3050                 // Is it there?
3051                 if (!isset($this->genericArray[$keyGroup])) {
3052                         // Abort here
3053                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' not found.');
3054                         exit;
3055                 } // END - if
3056
3057                 // Then count it
3058                 $count = count($this->genericArray[$keyGroup]);
3059
3060                 // Debug message
3061                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',count=' . $count);
3062
3063                 // Return it
3064                 return $count;
3065         }
3066
3067         /**
3068          * Count generic array sub group
3069          *
3070          * @param       $keyGroup       Main group for the key
3071          * @param       $subGroup       Sub group for the key
3072          * @return      $count          Count of given group
3073          */
3074         protected final function countGenericArrayGroup ($keyGroup, $subGroup) {
3075                 // Debug message
3076                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
3077
3078                 // Is it there?
3079                 if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
3080                         // Abort here
3081                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
3082                         exit;
3083                 } // END - if
3084
3085                 // Then count it
3086                 $count = count($this->genericArray[$keyGroup][$subGroup]);
3087
3088                 // Debug message
3089                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',count=' . $count);
3090
3091                 // Return it
3092                 return $count;
3093         }
3094
3095         /**
3096          * Count generic array elements
3097          *
3098          * @param       $keyGroup       Main group for the key
3099          * @param       $subGroup       Sub group for the key
3100          * @para        $key            Key to count
3101          * @return      $count          Count of given key
3102          */
3103         protected final function countGenericArrayElements ($keyGroup, $subGroup, $key) {
3104                 // Debug message
3105                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
3106
3107                 // Is it there?
3108                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
3109                         // Abort here
3110                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
3111                         exit;
3112                 } elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
3113                         // Not valid
3114                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' is not an array.');
3115                         exit;
3116                 }
3117
3118                 // Then count it
3119                 $count = count($this->genericArray[$keyGroup][$subGroup][$key]);
3120
3121                 // Debug message
3122                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',count=' . $count);
3123
3124                 // Return it
3125                 return $count;
3126         }
3127
3128         /**
3129          * Getter for whole generic group array
3130          *
3131          * @param       $keyGroup       Key group to get
3132          * @return      $array          Whole generic array group
3133          */
3134         protected final function getGenericArray ($keyGroup) {
3135                 // Debug message
3136                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
3137
3138                 // Is it there?
3139                 if (!isset($this->genericArray[$keyGroup])) {
3140                         // Then abort here
3141                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' does not exist.');
3142                         exit;
3143                 } // END - if
3144
3145                 // Return it
3146                 return $this->genericArray[$keyGroup];
3147         }
3148
3149         /**
3150          * Setter for generic array key
3151          *
3152          * @param       $keyGroup       Key group to get
3153          * @param       $subGroup       Sub group for the key
3154          * @param       $key            Key to unset
3155          * @param       $value          Mixed value from generic array element
3156          * @return      void
3157          */
3158         protected final function setGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
3159                 // Debug message
3160                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, TRUE));
3161
3162                 // Set value here
3163                 $this->genericArray[$keyGroup][$subGroup][$key] = $value;
3164         }
3165
3166         /**
3167          * Getter for generic array key
3168          *
3169          * @param       $keyGroup       Key group to get
3170          * @param       $subGroup       Sub group for the key
3171          * @param       $key            Key to unset
3172          * @return      $value          Mixed value from generic array element
3173          */
3174         protected final function getGenericArrayKey ($keyGroup, $subGroup, $key) {
3175                 // Debug message
3176                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
3177
3178                 // Is it there?
3179                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
3180                         // Then abort here
3181                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' does not exist.');
3182                         exit;
3183                 } // END - if
3184
3185                 // Return it
3186                 return $this->genericArray[$keyGroup][$subGroup][$key];
3187         }
3188
3189         /**
3190          * Sets a value in given generic array key/element
3191          *
3192          * @param       $keyGroup       Main group for the key
3193          * @param       $subGroup       Sub group for the key
3194          * @param       $key            Key to set
3195          * @param       $element        Element to set
3196          * @param       $value          Value to set
3197          * @return      void
3198          */
3199         protected final function setGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
3200                 // Debug message
3201                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, TRUE));
3202
3203                 // Then set it
3204                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = $value;
3205         }
3206
3207         /**
3208          * Getter for generic array element
3209          *
3210          * @param       $keyGroup       Key group to get
3211          * @param       $subGroup       Sub group for the key
3212          * @param       $key            Key to look for
3213          * @param       $element        Element to look for
3214          * @return      $value          Mixed value from generic array element
3215          */
3216         protected final function getGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
3217                 // Debug message
3218                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
3219
3220                 // Is it there?
3221                 if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
3222                         // Then abort here
3223                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' does not exist.');
3224                         exit;
3225                 } // END - if
3226
3227                 // Return it
3228                 return $this->genericArray[$keyGroup][$subGroup][$key][$element];
3229         }
3230
3231         /**
3232          * Checks if a given sub group is valid (array)
3233          *
3234          * @param       $keyGroup       Key group to get
3235          * @param       $subGroup       Sub group for the key
3236          * @return      $isValid        Whether given sub group is valid
3237          */
3238         protected final function isValidGenericArrayGroup ($keyGroup, $subGroup) {
3239                 // Debug message
3240                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
3241
3242                 // Determine it
3243                 $isValid = (($this->isGenericArrayGroupSet($keyGroup, $subGroup)) && (is_array($this->getGenericSubArray($keyGroup, $subGroup))));
3244
3245                 // Return it
3246                 return $isValid;
3247         }
3248
3249         /**
3250          * Checks if a given key is valid (array)
3251          *
3252          * @param       $keyGroup       Key group to get
3253          * @param       $subGroup       Sub group for the key
3254          * @param       $key            Key to check
3255          * @return      $isValid        Whether given sub group is valid
3256          */
3257         protected final function isValidGenericArrayKey ($keyGroup, $subGroup, $key) {
3258                 // Debug message
3259                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
3260
3261                 // Determine it
3262                 $isValid = (($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) && (is_array($this->getGenericArrayKey($keyGroup, $subGroup, $key))));
3263
3264                 // Return it
3265                 return $isValid;
3266         }
3267
3268         /**
3269          * Initializes the web output instance
3270          *
3271          * @return      void
3272          */
3273         protected function initWebOutputInstance () {
3274                 // Get application instance
3275                 $applicationInstance = Registry::getRegistry()->getInstance('app');
3276
3277                 // Is this a response instance?
3278                 if ($this instanceof Responseable) {
3279                         // Then set it in application instance
3280                         $applicationInstance->setResponseInstance($this);
3281                 } // END - if
3282
3283                 // Init web output instance
3284                 $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class', array($applicationInstance));
3285
3286                 // Set it locally
3287                 $this->setWebOutputInstance($outputInstance);
3288         }
3289
3290         /**
3291          * Translates boolean TRUE to 'Y' and FALSE to 'N'
3292          *
3293          * @param       $boolean                Boolean value
3294          * @return      $translated             Translated boolean value
3295          */
3296         public static final function translateBooleanToYesNo ($boolean) {
3297                 // Make sure it is really boolean
3298                 assert(is_bool($boolean));
3299
3300                 // "Translate" it
3301                 $translated = ($boolean === TRUE) ? 'Y' : 'N';
3302
3303                 // ... and return it
3304                 return $translated;
3305         }
3306
3307         /**
3308          * Encodes raw data (almost any type) by "serializing" it and then pack it
3309          * into a "binary format".
3310          *
3311          * @param       $rawData        Raw data (almost any type)
3312          * @return      $encoded        Encoded data
3313          */
3314         protected function encodeData ($rawData) {
3315                 // Make sure no objects or resources pass through
3316                 assert(!is_object($rawData));
3317                 assert(!is_resource($rawData));
3318
3319                 // First "serialize" it (json_encode() is faster than serialize())
3320                 $encoded = $this->packString(json_encode($rawData));
3321
3322                 // And return it
3323                 return $encoded;
3324         }
3325
3326         /**
3327          * Pack a string into a "binary format". Please execuse me that this is
3328          * widely undocumented. :-(
3329          *
3330          * @param       $str            Unpacked string
3331          * @return      $packed         Packed string
3332          * @todo        Improve documentation
3333          */
3334         protected function packString ($str) {
3335                 // Debug message
3336                 //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('str=' . $str . ' - CALLED!');
3337
3338                 // First compress the string (gzcompress is okay)
3339                 $str = gzcompress($str);
3340
3341                 // Init variable
3342                 $packed = '';
3343
3344                 // And start the "encoding" loop
3345                 for ($idx = 0; $idx < strlen($str); $idx += $this->packingData[$this->archArrayElement]['step']) {
3346                         $big = 0;
3347                         for ($i = 0; $i < $this->packingData[$this->archArrayElement]['step']; $i++) {
3348                                 $factor = ($this->packingData[$this->archArrayElement]['step'] - 1 - $i);
3349
3350                                 if (($idx + $i) <= strlen($str)) {
3351                                         $ord = ord(substr($str, ($idx + $i), 1));
3352
3353                                         $add = $ord * pow(256, $factor);
3354
3355                                         $big += $add;
3356
3357                                         //print 'idx=' . $idx . ',i=' . $i . ',ord=' . $ord . ',factor=' . $factor . ',add=' . $add . ',big=' . $big . PHP_EOL;
3358                                 } // END - if
3359                         } // END - for
3360
3361                         $l = ($big & $this->packingData[$this->archArrayElement]['left']) >>$this->packingData[$this->archArrayElement]['factor'];
3362                         $r = $big & $this->packingData[$this->archArrayElement]['right'];
3363
3364                         $chunk = str_pad(pack($this->packingData[$this->archArrayElement]['format'], $l, $r), 8, '0', STR_PAD_LEFT);
3365                         //* NOISY-DEBUG */ print 'big=' . $big . ',chunk('.strlen($chunk) . ')='.md5($chunk).PHP_EOL;
3366
3367                         $packed .= $chunk;
3368                 } // END - for
3369
3370                 // Return it
3371                 //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('packed=' . $packed . ' - EXIT!');
3372                 return $packed;
3373         }
3374
3375         /**
3376          * Checks whether the given file/path is in open_basedir(). This does not
3377          * gurantee that the file is actually readable and/or writeable. If you need
3378          * such gurantee then please use isReadableFile() instead.
3379          *
3380          * @param       $filePathName   Name of the file/path to be checked
3381          * @return      $isReachable    Whether it is within open_basedir()
3382          */
3383         protected static function isReachableFilePath ($filePathName) {
3384                 // Is not reachable by default
3385                 $isReachable = FALSE;
3386
3387                 // Get open_basedir parameter
3388                 $openBaseDir = ini_get('open_basedir');
3389
3390                 // Is it set?
3391                 if (!empty($openBaseDir)) {
3392                         // Check all entries
3393                         foreach (explode(PATH_SEPARATOR, $openBaseDir) as $dir) {
3394                                 // Check on existence
3395                                 if (substr($filePathName, 0, strlen($dir)) == $dir) {
3396                                         // Is reachable
3397                                         $isReachable = TRUE;
3398                                 } // END - if
3399                         } // END - foreach
3400                 } else {
3401                         // If open_basedir is not set, all is allowed
3402                         $isReachable = TRUE;
3403                 }
3404
3405                 // Return status
3406                 return $isReachable;
3407         }
3408
3409         /**
3410          * Checks whether the give file is within open_basedir() (done by
3411          * isReachableFilePath()), is actually a file and is readable.
3412          *
3413          * @param       $fileName               Name of the file to be checked
3414          * @return      $isReadable             Whether the file is readable (and therefor exists)
3415          */
3416         public static function isReadableFile ($fileName) {
3417                 // Default is not readable
3418                 $isReadable = FALSE;
3419
3420                 // Is within parameters, so check if it is a file and readable
3421                 $isReadable = ((self::isReachableFilePath($fileName)) && (file_exists($fileName)) && (is_file($fileName)) && (is_readable($fileName)));
3422
3423                 // Return status
3424                 return $isReadable;
3425         }
3426
3427         /**
3428          * Creates a full-qualified file name (FQFN) for given file name by adding
3429          * a configured temporary file path to it.
3430          *
3431          * @param       $fileName       Name for temporary file
3432          * @return      $fqfn   Full-qualified file name
3433          * @throw       PathWriteProtectedException If the path in 'temp_file_path' is write-protected
3434          * @throws      FileIoException If the file cannot be written
3435          */
3436          protected static function createTempPathForFile ($fileName) {
3437                 // Get config entry
3438                 $basePath = FrameworkConfiguration::getSelfInstance()->getConfigEntry('temp_file_path');
3439
3440                 // Is the path writeable?
3441                 if (!is_writable($basePath)) {
3442                         // Path is write-protected
3443                         throw new PathWriteProtectedException($fileName, self::EXCEPTION_PATH_CANNOT_BE_WRITTEN);
3444                 } // END - if
3445
3446                 // Add it
3447                 $fqfn = $basePath . '/' . $fileName;
3448
3449                 // Is it reachable?
3450                 if (!self::isReachableFilePath($fqfn)) {
3451                         // Not reachable
3452                         throw new FileIoException($fqfn, self::EXCEPTION_FILE_NOT_REACHABLE);
3453                 } // END - if
3454
3455                 // Return it
3456                 return $fqfn;
3457          }
3458
3459         /**
3460          * "Getter" for a printable state name
3461          *
3462          * @return      $stateName      Name of the node's state in a printable format
3463          */
3464         public final function getPrintableState () {
3465                 // Default is 'null'
3466                 $stateName = 'null';
3467
3468                 // Get the state instance
3469                 $stateInstance = $this->getStateInstance();
3470
3471                 // Is it an instance of Stateable?
3472                 if ($stateInstance instanceof Stateable) {
3473                         // Then use that state name
3474                         $stateName = $stateInstance->getStateName();
3475                 } // END - if
3476
3477                 // Return result
3478                 return $stateName;
3479         }
3480
3481         /**
3482          * Handles socket error for given socket resource and peer data. This method
3483          * validates $socketResource if it is a valid resource (see is_resource())
3484          * but assumes valid data in array $recipientData, except that
3485          * count($recipientData) is always 2.
3486          *
3487          * @param       $method                         Value of __METHOD__ from calling method
3488          * @param       $line                           Value of __LINE__ from calling method
3489          * @param       $socketResource         A valid socket resource
3490          * @param       $socketData                     A valid socket data array (0 = IP/file name, 1 = port)
3491          * @return      void
3492          * @throws      InvalidSocketException  If $socketResource is no socket resource
3493          * @throws      NoSocketErrorDetectedException  If socket_last_error() gives zero back
3494          * @todo        Move all this socket-related stuff into own class, most of it resides in BaseListener
3495          */
3496         protected final function handleSocketError ($method, $line, $socketResource, array $socketData) {
3497                 // This method handles only socket resources
3498                 if (!is_resource($socketResource)) {
3499                         // No resource, abort here
3500                         throw new InvalidSocketException(array($this, $socketResource), BaseListener::EXCEPTION_INVALID_SOCKET);
3501                 } // END - if
3502
3503                 // Check socket array, 1st element is mostly IP address (or file name), 2nd is port number
3504                 //* DEBUG-DIE: */ die(__METHOD__ . ':socketData=' . print_r($socketData, TRUE));
3505                 assert(isset($socketData[0]));
3506                 assert(isset($socketData[1]));
3507
3508                 // Get error code for first validation (0 is not an error)
3509                 $errorCode = socket_last_error($socketResource);
3510
3511                 // If the error code is zero, someone called this method without an error
3512                 if ($errorCode == 0) {
3513                         // No error detected (or previously cleared outside this method)
3514                         throw new NoSocketErrorDetectedException(array($this, $socketResource), BaseListener::EXCEPTION_NO_SOCKET_ERROR);
3515                 } // END - if
3516
3517                 // Get handler (method) name
3518                 $handlerName = $this->getSocketErrorHandlerFromCode($errorCode);
3519
3520                 // Call-back the error handler method
3521                 call_user_func_array(array($this, $handlerName), array($socketResource, $socketData));
3522
3523                 // Finally clear the error because it has been handled
3524                 socket_clear_error($socketResource);
3525         }
3526
3527 }