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