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