]> git.mxchange.org Git - core.git/blob - framework/main/classes/class_BaseFrameworkSystem.php
Continued:
[core.git] / framework / main / classes / class_BaseFrameworkSystem.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Object;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Bootstrap\FrameworkBootstrap;
7 use Org\Mxchange\CoreFramework\Criteria\Criteria;
8 use Org\Mxchange\CoreFramework\Criteria\Local\LocalSearchCriteria;
9 use Org\Mxchange\CoreFramework\Criteria\Local\LocalUpdateCriteria;
10 use Org\Mxchange\CoreFramework\Crypto\Cryptable;
11 use Org\Mxchange\CoreFramework\Crypto\RandomNumber\RandomNumberGenerator;
12 use Org\Mxchange\CoreFramework\Database\Frontend\DatabaseWrapper;
13 use Org\Mxchange\CoreFramework\EntryPoint\ApplicationEntryPoint;
14 use Org\Mxchange\CoreFramework\Factory\Database\Wrapper\DatabaseWrapperFactory;
15 use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
16 use Org\Mxchange\CoreFramework\Filesystem\Block;
17 use Org\Mxchange\CoreFramework\Filesystem\FilePointer;
18 use Org\Mxchange\CoreFramework\Filesystem\FrameworkDirectory;
19 use Org\Mxchange\CoreFramework\Filesystem\PathWriteProtectedException;
20 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
21 use Org\Mxchange\CoreFramework\Generic\NullPointerException;
22 use Org\Mxchange\CoreFramework\Generic\UnsupportedOperationException;
23 use Org\Mxchange\CoreFramework\Handler\Handleable;
24 use Org\Mxchange\CoreFramework\Helper\Helper;
25 use Org\Mxchange\CoreFramework\Index\Indexable;
26 use Org\Mxchange\CoreFramework\Lists\Listable;
27 use Org\Mxchange\CoreFramework\Loader\ClassLoader;
28 use Org\Mxchange\CoreFramework\Localization\ManageableLanguage;
29 use Org\Mxchange\CoreFramework\Manager\ManageableApplication;
30 use Org\Mxchange\CoreFramework\Menu\RenderableMenu;
31 use Org\Mxchange\CoreFramework\Middleware\Debug\DebugMiddleware;
32 use Org\Mxchange\CoreFramework\Parser\Parseable;
33 use Org\Mxchange\CoreFramework\Registry\GenericRegistry;
34 use Org\Mxchange\CoreFramework\Result\Database\CachedDatabaseResult;
35 use Org\Mxchange\CoreFramework\Result\Search\SearchableResult;
36 use Org\Mxchange\CoreFramework\Stacker\Stackable;
37 use Org\Mxchange\CoreFramework\State\Stateable;
38 use Org\Mxchange\CoreFramework\Stream\Input\InputStream;
39 use Org\Mxchange\CoreFramework\Stream\Output\OutputStreamer;
40 use Org\Mxchange\CoreFramework\Stream\Output\OutputStream;
41 use Org\Mxchange\CoreFramework\Template\CompileableTemplate;
42 use Org\Mxchange\CoreFramework\User\ManageableAccount;
43 use Org\Mxchange\CoreFramework\Utils\String\StringUtils;
44 use Org\Mxchange\CoreFramework\Visitor\Visitor;
45
46 // Import SPL stuff
47 use \stdClass;
48 use \InvalidArgumentException;
49 use \Iterator;
50 use \ReflectionClass;
51 use \SplFileInfo;
52
53 /**
54  * The simulator system class is the super class of all other classes. This
55  * class handles saving of games etc.
56  *
57  * @author              Roland Haeder <webmaster@shipsimu.org>
58  * @version             0.0.0
59  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team
60  * @license             GNU GPL 3.0 or any newer version
61  * @link                http://www.shipsimu.org
62  *
63  * This program is free software: you can redistribute it and/or modify
64  * it under the terms of the GNU General Public License as published by
65  * the Free Software Foundation, either version 3 of the License, or
66  * (at your option) any later version.
67  *
68  * This program is distributed in the hope that it will be useful,
69  * but WITHOUT ANY WARRANTY; without even the implied warranty of
70  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
71  * GNU General Public License for more details.
72  *
73  * You should have received a copy of the GNU General Public License
74  * along with this program. If not, see <http://www.gnu.org/licenses/>.
75  */
76 abstract class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
77         /**
78          * Length of output from hash()
79          */
80         private static $hashLength = NULL;
81
82         /**
83          * Self-referencing instance
84          */
85         private static $instance = NULL;
86
87         /**
88          * The real class name
89          */
90         private $realClass = __CLASS__;
91
92         /**
93          * Search criteria instance
94          */
95         private $searchInstance = NULL;
96
97         /**
98          * Update criteria instance
99          */
100         private $updateInstance = NULL;
101
102         /**
103          * Template engine instance
104          */
105         private $templateInstance = NULL;
106
107         /**
108          * Database result instance
109          */
110         private $resultInstance = NULL;
111
112         /**
113          * Instance for user class
114          */
115         private $userInstance = NULL;
116
117         /**
118          * Instance of a RNG
119          */
120         private $rngInstance = NULL;
121
122         /**
123          * Instance of a crypto helper
124          */
125         private $cryptoInstance = NULL;
126
127         /**
128          * Instance of an Iterator class
129          */
130         private $iteratorInstance = NULL;
131
132         /**
133          * Instance of the list
134          */
135         private $listInstance = NULL;
136
137         /**
138          * Instance of a menu
139          */
140         private $menuInstance = NULL;
141
142         /**
143          * Instance of the image
144          */
145         private $imageInstance = NULL;
146
147         /**
148          * Instance of the stacker
149          */
150         private $stackInstance = NULL;
151
152         /**
153          * A Parseable instance
154          */
155         private $parserInstance = NULL;
156
157         /**
158          * A helper instance for the form
159          */
160         private $helperInstance = NULL;
161
162         /**
163          * An instance of a InputStream class
164          */
165         private $inputStreamInstance = NULL;
166
167         /**
168          * An instance of a OutputStream class
169          */
170         private $outputStreamInstance = NULL;
171
172         /**
173          * Handler instance
174          */
175         private $handlerInstance = NULL;
176
177         /**
178          * Visitor handler instance
179          */
180         private $visitorInstance = NULL;
181
182         /**
183          * An instance of a database wrapper class
184          */
185         private $wrapperInstance = NULL;
186
187         /**
188          * An instance of a file I/O pointer class (not handler)
189          */
190         private $pointerInstance = NULL;
191
192         /**
193          * An instance of an Indexable class
194          */
195         private $indexInstance = NULL;
196
197         /**
198          * An instance of a Block class
199          */
200         private $blockInstance = NULL;
201
202         /**
203          * A FrameworkDirectory instance
204          */
205         private $directoryInstance = NULL;
206
207         /**
208          * The concrete output instance
209          */
210         private $outputInstance = NULL;
211
212         /**
213          * State instance
214          */
215         private $stateInstance = NULL;
216
217         /**
218          * Call-back instance
219          */
220         private $callbackInstance = NULL;
221
222         /**
223          * Generic array
224          */
225         private $genericArray = array();
226
227         /***********************
228          * Exception codes.... *
229          ***********************/
230
231         // @todo Try to clean these constants up
232         const EXCEPTION_IS_NULL_POINTER              = 0x001;
233         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
234         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
235         const EXCEPTION_MISSING_METHOD               = 0x004;
236         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
237         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
238         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
239         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
240         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
241         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
242         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
243         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
244         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
245         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
246         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
247         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
248         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
249         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
250         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
251         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
252         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
253         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
254         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
255         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
256         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
257         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
258         const EXCEPTION_INVALID_RESOURCE             = 0x01b;
259         const EXCEPTION_UNEXPECTED_OBJECT            = 0x01c;
260         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
261         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
262         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
263         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
264         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
265         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
266         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
267         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
268         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
269         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
270         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
271         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
272         const EXCEPTION_INVALID_STRING               = 0x029;
273         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
274         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
275         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
276         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
277         const EXCEPTION_UNSPPORTED_OPERATION         = 0x02e;
278         const EXCEPTION_FACTORY_REQUIRE_PARAMETER    = 0x02f;
279         const EXCEPTION_MISSING_ELEMENT              = 0x030;
280         const EXCEPTION_HEADERS_ALREADY_SENT         = 0x031;
281         const EXCEPTION_DEFAULT_CONTROLLER_GONE      = 0x032;
282         const EXCEPTION_CLASS_NOT_FOUND              = 0x033;
283         const EXCEPTION_REQUIRED_INTERFACE_MISSING   = 0x034;
284         const EXCEPTION_FATAL_ERROR                  = 0x035;
285         const EXCEPTION_FILE_NOT_FOUND               = 0x036;
286         const EXCEPTION_ASSERTION_FAILED             = 0x037;
287         const EXCEPTION_FILE_NOT_REACHABLE           = 0x038;
288         const EXCEPTION_FILE_CANNOT_BE_READ          = 0x039;
289         const EXCEPTION_FILE_CANNOT_BE_WRITTEN       = 0x03a;
290         const EXCEPTION_PATH_CANNOT_BE_WRITTEN       = 0x03b;
291         const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x03c;
292         const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x03d;
293         const EXCEPTION_INVALID_SOCKET               = 0x03e;
294         const EXCEPTION_SELF_INSTANCE                = 0x03f;
295
296         /**
297          * Hexadecimal->Decimal translation array
298          */
299         private static $hexdec = array(
300                 '0' => 0,
301                 '1' => 1,
302                 '2' => 2,
303                 '3' => 3,
304                 '4' => 4,
305                 '5' => 5,
306                 '6' => 6,
307                 '7' => 7,
308                 '8' => 8,
309                 '9' => 9,
310                 'a' => 10,
311                 'b' => 11,
312                 'c' => 12,
313                 'd' => 13,
314                 'e' => 14,
315                 'f' => 15
316         );
317
318         /**
319          * Decimal->hexadecimal translation array
320          */
321         private static $dechex = array(
322                  0 => '0',
323                  1 => '1',
324                  2 => '2',
325                  3 => '3',
326                  4 => '4',
327                  5 => '5',
328                  6 => '6',
329                  7 => '7',
330                  8 => '8',
331                  9 => '9',
332                 10 => 'a',
333                 11 => 'b',
334                 12 => 'c',
335                 13 => 'd',
336                 14 => 'e',
337                 15 => 'f'
338         );
339
340         /**
341          * Startup time in miliseconds
342          */
343         private static $startupTime = 0;
344
345         /**
346          * Protected super constructor
347          *
348          * @param       $className      Name of the class
349          * @return      void
350          */
351         protected function __construct (string $className) {
352                 // Set real class
353                 $this->setRealClass($className);
354
355                 // Is the startup time set? (0 cannot be true anymore)
356                 if (self::$startupTime == 0) {
357                         // Then set it
358                         self::$startupTime = microtime(true);
359                 } // END - if
360         }
361
362         /**
363          * Destructor for all classes. You should not call this method on your own.
364          *
365          * @return      void
366          */
367         public function __destruct () {
368                 // Flush any updated entries to the database
369                 $this->flushPendingUpdates();
370
371                 // Is this object already destroyed?
372                 if ($this->__toString() != 'DestructedObject') {
373                         // Destroy all informations about this class but keep some text about it alive
374                         $this->setRealClass('DestructedObject');
375                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
376                         // Already destructed object
377                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('The object <span class="object_name">%s</span> is already destroyed.',
378                                 $this->__toString()
379                         ));
380                 } else {
381                         // Do not call this twice
382                         trigger_error(__METHOD__ . ': Called twice.');
383                         exit;
384                 }
385         }
386
387         /**
388          * The __call() method where all non-implemented methods end up
389          *
390          * @param       $methodName             Name of the missing method
391          * @args        $args                   Arguments passed to the method
392          * @return      void
393          */
394         public final function __call ($methodName, $args) {
395                 // Set self-instance
396                 self::$instance = $this;
397
398                 // Call static method
399                 self::__callStatic($methodName, $args);
400
401                 // Clear self-instance
402                 self::$instance = NULL;
403         }
404
405         /**
406          * The __callStatic() method where all non-implemented static methods end up
407          *
408          * @param       $methodName             Name of the missing method
409          * @param       $args                   Arguments passed to the method
410          * @return      void
411          * @throws      InvalidArgumentException If self::$instance is not a framework's own object
412          */
413         public static final function __callStatic ($methodName, $args) {
414                 // Trace message
415                 //* PRINT-DEBUG: */ printf('[%s:%d]: methodName=%s,args[]=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $methodName, gettype($args));
416
417                 // Init argument string and class name
418                 $argsString = '';
419                 $className = 'unknown';
420
421                 // Is self-instance set?
422                 if (self::$instance instanceof FrameworkInterface) {
423                         // Framework's own instance
424                         $className = self::$instance->__toString();
425                 } elseif (!is_null(self::$instance)) {
426                         // Invalid argument!
427                         throw new InvalidArgumentException(sprintf('self::instance[%s] is not expected.', gettype(self::$instance)), self::EXCEPTION_SELF_INSTANCE);
428                 }
429
430                 // Is it NULL, empty or an array?
431                 if (is_null($args)) {
432                         // No arguments
433                         $argsString = 'NULL';
434                 } elseif (is_array($args)) {
435                         // Start braces
436                         $argsString = '(';
437
438                         // Some arguments are there
439                         foreach ($args as $arg) {
440                                 // Add data about the argument
441                                 $argsString .= gettype($arg) . ':';
442
443                                 if (is_null($arg)) {
444                                         // Found a NULL argument
445                                         $argsString .= 'NULL';
446                                 } elseif (is_string($arg)) {
447                                         // Add length for strings
448                                         $argsString .= strlen($arg);
449                                 } elseif ((is_int($arg)) || (is_float($arg))) {
450                                         // ... integer/float
451                                         $argsString .= $arg;
452                                 } elseif (is_array($arg)) {
453                                         // .. or size if array
454                                         $argsString .= count($arg);
455                                 } elseif (is_object($arg)) {
456                                         // Get reflection
457                                         $reflection = new ReflectionClass($arg);
458
459                                         // Is an other object, maybe no __toString() available
460                                         $argsString .= $reflection->getName();
461                                 } elseif ($arg === true) {
462                                         // ... is boolean 'true'
463                                         $argsString .= 'true';
464                                 } elseif ($arg === false) {
465                                         // ... is boolean 'false'
466                                         $argsString .= 'false';
467                                 }
468
469                                 // Comma for next one
470                                 $argsString .= ', ';
471                         } // END - foreach
472
473                         // Last comma found?
474                         if (substr($argsString, -2, 1) == ',') {
475                                 // Remove last comma
476                                 $argsString = substr($argsString, 0, -2);
477                         } // END - if
478
479                         // Close braces
480                         $argsString .= ')';
481                 } else {
482                         // Invalid arguments!
483                         $argsString = sprintf('!INVALID:%s!', gettype($args));
484                 }
485
486                 // Output stub message
487                 // @TODO __CLASS__ does always return BaseFrameworkSystem but not the extending (=child) class
488                 self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('[%s::%s]: Stub! Args: %s',
489                         $className,
490                         $methodName,
491                         $argsString
492                 ));
493
494                 // Return nothing
495                 return NULL;
496         }
497
498         /**
499          * Getter for $realClass
500          *
501          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
502          */
503         public function __toString () {
504                 return $this->realClass;
505         }
506
507         /**
508          * Magic method to catch setting of missing but set class fields/attributes
509          *
510          * @param       $name   Name of the field/attribute
511          * @param       $value  Value to store
512          * @return      void
513          */
514         public final function __set ($name, $value) {
515                 $this->debugBackTrace(sprintf('Tried to set a missing field. name=%s, value[%s]=%s',
516                         $name,
517                         gettype($value),
518                         print_r($value, true)
519                 ));
520         }
521
522         /**
523          * Magic method to catch getting of missing fields/attributes
524          *
525          * @param       $name   Name of the field/attribute
526          * @return      void
527          */
528         public final function __get ($name) {
529                 $this->debugBackTrace(sprintf('Tried to get a missing field. name=%s',
530                         $name
531                 ));
532         }
533
534         /**
535          * Magic method to catch unsetting of missing fields/attributes
536          *
537          * @param       $name   Name of the field/attribute
538          * @return      void
539          */
540         public final function __unset ($name) {
541                 $this->debugBackTrace(sprintf('Tried to unset a missing field. name=%s',
542                         $name
543                 ));
544         }
545
546         /**
547          * Magic method to catch object serialization
548          *
549          * @return      $unsupported    Unsupported method
550          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
551          */
552         public final function __sleep () {
553                 throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
554         }
555
556         /**
557          * Magic method to catch object deserialization
558          *
559          * @return      $unsupported    Unsupported method
560          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
561          */
562         public final function __wakeup () {
563                 throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
564         }
565
566         /**
567          * Magic method to catch calls when an object instance is called
568          *
569          * @return      $unsupported    Unsupported method
570          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
571          */
572         public final function __invoke () {
573                 throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
574         }
575
576         /**
577          * Setter for the real class name
578          *
579          * @param       $realClass      Class name (string)
580          * @return      void
581          */
582         public final function setRealClass ($realClass) {
583                 // Set real class
584                 $this->realClass = (string) $realClass;
585         }
586
587         /**
588          * Setter for database result instance
589          *
590          * @param       $resultInstance         An instance of a database result class
591          * @return      void
592          * @todo        SearchableResult and UpdateableResult shall have a super interface to use here
593          */
594         protected final function setResultInstance (SearchableResult $resultInstance) {
595                 $this->resultInstance =  $resultInstance;
596         }
597
598         /**
599          * Getter for database result instance
600          *
601          * @return      $resultInstance         An instance of a database result class
602          */
603         public final function getResultInstance () {
604                 return $this->resultInstance;
605         }
606
607         /**
608          * Setter for template engine instances
609          *
610          * @param       $templateInstance       An instance of a template engine class
611          * @return      void
612          */
613         protected final function setTemplateInstance (CompileableTemplate $templateInstance) {
614                 $this->templateInstance = $templateInstance;
615         }
616
617         /**
618          * Getter for template engine instances
619          *
620          * @return      $templateInstance       An instance of a template engine class
621          */
622         protected final function getTemplateInstance () {
623                 return $this->templateInstance;
624         }
625
626         /**
627          * Setter for search instance
628          *
629          * @param       $searchInstance         Searchable criteria instance
630          * @return      void
631          */
632         public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
633                 $this->searchInstance = $searchInstance;
634         }
635
636         /**
637          * Getter for search instance
638          *
639          * @return      $searchInstance         Searchable criteria instance
640          */
641         public final function getSearchInstance () {
642                 return $this->searchInstance;
643         }
644
645         /**
646          * Setter for update instance
647          *
648          * @param       $updateInstance         An instance of a LocalUpdateCriteria clase
649          * @return      void
650          */
651         public final function setUpdateInstance (LocalUpdateCriteria $updateInstance) {
652                 $this->updateInstance = $updateInstance;
653         }
654
655         /**
656          * Getter for update instance
657          *
658          * @return      $updateInstance         Updateable criteria instance
659          */
660         public final function getUpdateInstance () {
661                 return $this->updateInstance;
662         }
663
664         /**
665          * Setter for debug instance
666          *
667          * @param       $debugInstance  The instance for debug output class
668          * @return      void
669          */
670         public final function setDebugInstance (DebugMiddleware $debugInstance) {
671                 GenericRegistry::getRegistry()->addInstance('debug', $debugInstance);
672         }
673
674         /**
675          * Getter for debug instance
676          *
677          * @return      $debugInstance  Instance to class DebugConsoleOutput or DebugWebOutput
678          */
679         public final function getDebugInstance () {
680                 // Get debug instance
681                 $debugInstance = GenericRegistry::getRegistry()->getInstance('debug');
682
683                 // Return it
684                 return $debugInstance;
685         }
686
687         /**
688          * Setter for web output instance
689          *
690          * @param       $webInstance    The instance for web output class
691          * @return      void
692          */
693         public final function setWebOutputInstance (OutputStreamer $webInstance) {
694                 GenericRegistry::getRegistry()->addInstance('web_output', $webInstance);
695         }
696
697         /**
698          * Getter for web output instance
699          *
700          * @return      $webOutputInstance - Instance to class WebOutput
701          */
702         public final function getWebOutputInstance () {
703                 $webOutputInstance = GenericRegistry::getRegistry()->getInstance('web_output');
704                 return $webOutputInstance;
705         }
706
707         /**
708          * Private getter for language instance
709          *
710          * @return      $langInstance   An instance to the language sub-system
711          */
712         protected final function getLanguageInstance () {
713                 $langInstance = GenericRegistry::getRegistry()->getInstance('language');
714                 return $langInstance;
715         }
716
717         /**
718          * Setter for language instance
719          *
720          * @param       $langInstance   An instance to the language sub-system
721          * @return      void
722          * @see         LanguageSystem
723          */
724         public final function setLanguageInstance (ManageableLanguage $langInstance) {
725                 GenericRegistry::getRegistry()->addInstance('language', $langInstance);
726         }
727
728         /**
729          * Protected setter for user instance
730          *
731          * @param       $userInstance   An instance of a user class
732          * @return      void
733          */
734         protected final function setUserInstance (ManageableAccount $userInstance) {
735                 $this->userInstance = $userInstance;
736         }
737
738         /**
739          * Getter for user instance
740          *
741          * @return      $userInstance   An instance of a user class
742          */
743         public final function getUserInstance () {
744                 return $this->userInstance;
745         }
746
747         /**
748          * Setter for RNG instance
749          *
750          * @param       $rngInstance    An instance of a random number generator (RNG)
751          * @return      void
752          */
753         protected final function setRngInstance (RandomNumberGenerator $rngInstance) {
754                 $this->rngInstance = $rngInstance;
755         }
756
757         /**
758          * Getter for RNG instance
759          *
760          * @return      $rngInstance    An instance of a random number generator (RNG)
761          */
762         public final function getRngInstance () {
763                 return $this->rngInstance;
764         }
765
766         /**
767          * Setter for Cryptable instance
768          *
769          * @param       $cryptoInstance An instance of a Cryptable class
770          * @return      void
771          */
772         protected final function setCryptoInstance (Cryptable $cryptoInstance) {
773                 $this->cryptoInstance = $cryptoInstance;
774         }
775
776         /**
777          * Getter for Cryptable instance
778          *
779          * @return      $cryptoInstance An instance of a Cryptable class
780          */
781         public final function getCryptoInstance () {
782                 return $this->cryptoInstance;
783         }
784
785         /**
786          * Setter for the list instance
787          *
788          * @param       $listInstance   A list of Listable
789          * @return      void
790          */
791         protected final function setListInstance (Listable $listInstance) {
792                 $this->listInstance = $listInstance;
793         }
794
795         /**
796          * Getter for the list instance
797          *
798          * @return      $listInstance   A list of Listable
799          */
800         protected final function getListInstance () {
801                 return $this->listInstance;
802         }
803
804         /**
805          * Setter for the menu instance
806          *
807          * @param       $menuInstance   A RenderableMenu instance
808          * @return      void
809          */
810         protected final function setMenuInstance (RenderableMenu $menuInstance) {
811                 $this->menuInstance = $menuInstance;
812         }
813
814         /**
815          * Getter for the menu instance
816          *
817          * @return      $menuInstance   A RenderableMenu instance
818          */
819         protected final function getMenuInstance () {
820                 return $this->menuInstance;
821         }
822
823         /**
824          * Setter for image instance
825          *
826          * @param       $imageInstance  An instance of an image
827          * @return      void
828          */
829         public final function setImageInstance (BaseImage $imageInstance) {
830                 $this->imageInstance = $imageInstance;
831         }
832
833         /**
834          * Getter for image instance
835          *
836          * @return      $imageInstance  An instance of an image
837          */
838         public final function getImageInstance () {
839                 return $this->imageInstance;
840         }
841
842         /**
843          * Setter for stacker instance
844          *
845          * @param       $stackInstance  An instance of an stacker
846          * @return      void
847          */
848         public final function setStackInstance (Stackable $stackInstance) {
849                 $this->stackInstance = $stackInstance;
850         }
851
852         /**
853          * Getter for stacker instance
854          *
855          * @return      $stackInstance  An instance of an stacker
856          */
857         public final function getStackInstance () {
858                 return $this->stackInstance;
859         }
860
861         /**
862          * Setter for Parseable instance
863          *
864          * @param       $parserInstance An instance of an Parseable
865          * @return      void
866          */
867         public final function setParserInstance (Parseable $parserInstance) {
868                 $this->parserInstance = $parserInstance;
869         }
870
871         /**
872          * Getter for Parseable instance
873          *
874          * @return      $parserInstance An instance of an Parseable
875          */
876         public final function getParserInstance () {
877                 return $this->parserInstance;
878         }
879
880         /**
881          * Setter for DatabaseWrapper instance
882          *
883          * @param       $wrapperInstance        An instance of an DatabaseWrapper
884          * @return      void
885          */
886         public final function setWrapperInstance (DatabaseWrapper $wrapperInstance) {
887                 $this->wrapperInstance = $wrapperInstance;
888         }
889
890         /**
891          * Getter for DatabaseWrapper instance
892          *
893          * @return      $wrapperInstance        An instance of an DatabaseWrapper
894          */
895         public final function getWrapperInstance () {
896                 return $this->wrapperInstance;
897         }
898
899         /**
900          * Setter for helper instance
901          *
902          * @param       $helperInstance         An instance of a helper class
903          * @return      void
904          */
905         protected final function setHelperInstance (Helper $helperInstance) {
906                 $this->helperInstance = $helperInstance;
907         }
908
909         /**
910          * Getter for helper instance
911          *
912          * @return      $helperInstance         An instance of a helper class
913          */
914         public final function getHelperInstance () {
915                 return $this->helperInstance;
916         }
917
918         /**
919          * Getter for a InputStream instance
920          *
921          * @param       $inputStreamInstance    The InputStream instance
922          */
923         protected final function getInputStreamInstance () {
924                 return $this->inputStreamInstance;
925         }
926
927         /**
928          * Setter for a InputStream instance
929          *
930          * @param       $inputStreamInstance    The InputStream instance
931          * @return      void
932          */
933         protected final function setInputStreamInstance (InputStream $inputStreamInstance) {
934                 $this->inputStreamInstance = $inputStreamInstance;
935         }
936
937         /**
938          * Getter for a OutputStream instance
939          *
940          * @param       $outputStreamInstance   The OutputStream instance
941          */
942         protected final function getOutputStreamInstance () {
943                 return $this->outputStreamInstance;
944         }
945
946         /**
947          * Setter for a OutputStream instance
948          *
949          * @param       $outputStreamInstance   The OutputStream instance
950          * @return      void
951          */
952         protected final function setOutputStreamInstance (OutputStream $outputStreamInstance) {
953                 $this->outputStreamInstance = $outputStreamInstance;
954         }
955
956         /**
957          * Setter for handler instance
958          *
959          * @param       $handlerInstance        An instance of a Handleable class
960          * @return      void
961          */
962         protected final function setHandlerInstance (Handleable $handlerInstance) {
963                 $this->handlerInstance = $handlerInstance;
964         }
965
966         /**
967          * Getter for handler instance
968          *
969          * @return      $handlerInstance        A Handleable instance
970          */
971         protected final function getHandlerInstance () {
972                 return $this->handlerInstance;
973         }
974
975         /**
976          * Setter for visitor instance
977          *
978          * @param       $visitorInstance        A Visitor instance
979          * @return      void
980          */
981         protected final function setVisitorInstance (Visitor $visitorInstance) {
982                 $this->visitorInstance = $visitorInstance;
983         }
984
985         /**
986          * Getter for visitor instance
987          *
988          * @return      $visitorInstance        A Visitor instance
989          */
990         protected final function getVisitorInstance () {
991                 return $this->visitorInstance;
992         }
993
994         /**
995          * Setter for Iterator instance
996          *
997          * @param       $iteratorInstance       An instance of an Iterator
998          * @return      void
999          */
1000         protected final function setIteratorInstance (Iterator $iteratorInstance) {
1001                 $this->iteratorInstance = $iteratorInstance;
1002         }
1003
1004         /**
1005          * Getter for Iterator instance
1006          *
1007          * @return      $iteratorInstance       An instance of an Iterator
1008          */
1009         public final function getIteratorInstance () {
1010                 return $this->iteratorInstance;
1011         }
1012
1013         /**
1014          * Setter for FilePointer instance
1015          *
1016          * @param       $pointerInstance        An instance of an FilePointer class
1017          * @return      void
1018          */
1019         protected final function setPointerInstance (FilePointer $pointerInstance) {
1020                 $this->pointerInstance = $pointerInstance;
1021         }
1022
1023         /**
1024          * Getter for FilePointer instance
1025          *
1026          * @return      $pointerInstance        An instance of an FilePointer class
1027          */
1028         public final function getPointerInstance () {
1029                 return $this->pointerInstance;
1030         }
1031
1032         /**
1033          * Unsets pointer instance which triggers a call of __destruct() if the
1034          * instance is still there. This is surely not fatal on already "closed"
1035          * file pointer instances.
1036          *
1037          * I don't want to mess around with above setter by giving it a default
1038          * value NULL as setter should always explicitly only set (existing) object
1039          * instances and NULL is NULL.
1040          *
1041          * @return      void
1042          */
1043         protected final function unsetPointerInstance () {
1044                 // Simply it to NULL
1045                 $this->pointerInstance = NULL;
1046         }
1047
1048         /**
1049          * Setter for Indexable instance
1050          *
1051          * @param       $indexInstance  An instance of an Indexable class
1052          * @return      void
1053          */
1054         protected final function setIndexInstance (Indexable $indexInstance) {
1055                 $this->indexInstance = $indexInstance;
1056         }
1057
1058         /**
1059          * Getter for Indexable instance
1060          *
1061          * @return      $indexInstance  An instance of an Indexable class
1062          */
1063         public final function getIndexInstance () {
1064                 return $this->indexInstance;
1065         }
1066
1067         /**
1068          * Setter for Block instance
1069          *
1070          * @param       $blockInstance  An instance of an Block class
1071          * @return      void
1072          */
1073         protected final function setBlockInstance (Block $blockInstance) {
1074                 $this->blockInstance = $blockInstance;
1075         }
1076
1077         /**
1078          * Getter for Block instance
1079          *
1080          * @return      $blockInstance  An instance of an Block class
1081          */
1082         public final function getBlockInstance () {
1083                 return $this->blockInstance;
1084         }
1085
1086         /**
1087          * Setter for FrameworkDirectory instance
1088          *
1089          * @param       $directoryInstance      A FrameworkDirectory instance
1090          * @return      void
1091          */
1092         protected final function setDirectoryInstance (FrameworkDirectory $directoryInstance) {
1093                 $this->directoryInstance = $directoryInstance;
1094         }
1095
1096         /**
1097          * Getter for FrameworkDirectory instance
1098          *
1099          * @return      $directoryInstance      A FrameworkDirectory instance
1100          */
1101         protected final function getDirectoryInstance () {
1102                 return $this->directoryInstance;
1103         }
1104
1105         /**
1106          * Setter for state instance
1107          *
1108          * @param       $stateInstance  A Stateable instance
1109          * @return      void
1110          */
1111         public final function setStateInstance (Stateable $stateInstance) {
1112                 $this->stateInstance = $stateInstance;
1113         }
1114
1115         /**
1116          * Getter for state instance
1117          *
1118          * @return      $stateInstance  A Stateable instance
1119          */
1120         public final function getStateInstance () {
1121                 return $this->stateInstance;
1122         }
1123
1124         /**
1125          * Setter for output instance
1126          *
1127          * @param       $outputInstance The debug output instance
1128          * @return      void
1129          */
1130         public final function setOutputInstance (OutputStreamer $outputInstance) {
1131                 $this->outputInstance = $outputInstance;
1132         }
1133
1134         /**
1135          * Getter for output instance
1136          *
1137          * @return      $outputInstance The debug output instance
1138          */
1139         public final function getOutputInstance () {
1140                 return $this->outputInstance;
1141         }
1142
1143         /**
1144          * Setter for call-back instance
1145          *
1146          * @param       $callbackInstance       An instance of a FrameworkInterface class
1147          * @return      void
1148          */
1149         public final function setCallbackInstance (FrameworkInterface $callbackInstance) {
1150                 $this->callbackInstance = $callbackInstance;
1151         }
1152
1153         /**
1154          * Getter for call-back instance
1155          *
1156          * @return      $callbackInstance       An instance of a FrameworkInterface class
1157          */
1158         protected final function getCallbackInstance () {
1159                 return $this->callbackInstance;
1160         }
1161
1162         /**
1163          * Checks whether an object equals this object. You should overwrite this
1164          * method to implement own equality checks
1165          *
1166          * @param       $objectInstance         An instance of a FrameworkInterface object
1167          * @return      $equals                         Whether both objects equals
1168          */
1169         public function equals (FrameworkInterface $objectInstance) {
1170                 // Now test it
1171                 $equals = ((
1172                         $this->__toString() == $objectInstance->__toString()
1173                 ) && (
1174                         $this->hashCode() == $objectInstance->hashCode()
1175                 ));
1176
1177                 // Return the result
1178                 return $equals;
1179         }
1180
1181         /**
1182          * Generates a generic hash code of this class. You should really overwrite
1183          * this method with your own hash code generator code. But keep KISS in mind.
1184          *
1185          * @return      $hashCode       A generic hash code respresenting this whole class
1186          */
1187         public function hashCode () {
1188                 // Simple hash code
1189                 return crc32($this->__toString());
1190         }
1191
1192         /**
1193          * Appends a trailing slash to a string
1194          *
1195          * @param       $str    A string (maybe) without trailing slash
1196          * @return      $str    A string with an auto-appended trailing slash
1197          */
1198         public final function addMissingTrailingSlash ($str) {
1199                 // Is there a trailing slash?
1200                 if (substr($str, -1, 1) != '/') {
1201                         $str .= '/';
1202                 } // END - if
1203
1204                 // Return string with trailing slash
1205                 return $str;
1206         }
1207
1208         /**
1209          * Prepare the template engine (HtmlTemplateEngine by default) for a given
1210          * application helper instance (ApplicationHelper by default).
1211          *
1212          * @param               $applicationInstance    An application helper instance or
1213          *                                                                              null if we shall use the default
1214          * @return              $templateInstance               The template engine instance
1215          * @throws              NullPointerException    If the discovered application
1216          *                                                                              instance is still null
1217          */
1218         protected function prepareTemplateInstance (ManageableApplication $applicationInstance = NULL) {
1219                 // Is the application instance set?
1220                 if (is_null($applicationInstance)) {
1221                         // Get the current instance
1222                         $applicationInstance = GenericRegistry::getRegistry()->getInstance('application');
1223
1224                         // Still null?
1225                         if (is_null($applicationInstance)) {
1226                                 // Thrown an exception
1227                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1228                         } // END - if
1229                 } // END - if
1230
1231                 // Initialize the template engine
1232                 $templateInstance = ObjectFactory::createObjectByConfiguredName('html_template_class');
1233
1234                 // Return the prepared instance
1235                 return $templateInstance;
1236         }
1237
1238         /**
1239          * Debugs this instance by putting out it's full content
1240          *
1241          * @param       $message        Optional message to show in debug output
1242          * @return      void
1243          */
1244         public final function debugInstance ($message = '') {
1245                 // Restore the error handler to avoid trouble with missing array elements or undeclared variables
1246                 restore_error_handler();
1247
1248                 // Init content
1249                 $content = '';
1250
1251                 // Is a message set?
1252                 if (!empty($message)) {
1253                         // Construct message
1254                         $content = sprintf('<div class="debug_message">
1255         Message: %s
1256 </div>' . PHP_EOL, $message);
1257                 } // END - if
1258
1259                 // Generate the output
1260                 $content .= sprintf('<pre>%s</pre>',
1261                         trim(
1262                                 htmlentities(
1263                                         print_r($this, true)
1264                                 )
1265                         )
1266                 );
1267
1268                 // Output it
1269                 ApplicationEntryPoint::exitApplication(sprintf('<div class="debug_header">
1270         %s debug output:
1271 </div>
1272 <div class="debug_content">
1273         %s
1274 </div>
1275 Loaded includes:
1276 <div class="debug_include_list">
1277         %s
1278 </div>',
1279                         $this->__toString(),
1280                         $content,
1281                         ClassLoader::getSelfInstance()->getPrintableIncludeList()
1282                 ));
1283         }
1284
1285         /**
1286          * Replaces control characters with printable output
1287          *
1288          * @param       $str    String with control characters
1289          * @return      $str    Replaced string
1290          */
1291         protected function replaceControlCharacters ($str) {
1292                 // Replace them
1293                 $str = str_replace(
1294                         chr(13), '[r]', str_replace(
1295                         chr(10), '[n]', str_replace(
1296                         chr(9) , '[t]',
1297                         $str
1298                 )));
1299
1300                 // Return it
1301                 return $str;
1302         }
1303
1304         /**
1305          * Output a partial stub message for the caller method
1306          *
1307          * @param       $message        An optional message to display
1308          * @return      void
1309          */
1310         protected function partialStub ($message = '') {
1311                 // Init variable
1312                 $stubMessage = 'Partial stub!';
1313
1314                 // Is an extra message given?
1315                 if (!empty($message)) {
1316                         // Then add it as well
1317                         $stubMessage .= ' Message: ' . $message;
1318                 } // END - if
1319
1320                 // Debug instance is there?
1321                 if (!is_null($this->getDebugInstance())) {
1322                         // Output stub message
1323                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($stubMessage);
1324                 } else {
1325                         // Trigger an error
1326                         trigger_error($stubMessage);
1327                         exit;
1328                 }
1329         }
1330
1331         /**
1332          * Outputs a debug backtrace and stops further script execution
1333          *
1334          * @param       $message        An optional message to output
1335          * @param       $doExit         Whether exit the program (true is default)
1336          * @return      void
1337          */
1338         public function debugBackTrace ($message = '', $doExit = true) {
1339                 // Sorry, there is no other way getting this nice backtrace
1340                 if (!empty($message)) {
1341                         // Output message
1342                         printf('Message: %s<br />' . PHP_EOL, $message);
1343                 } // END - if
1344
1345                 print('<pre>');
1346                 debug_print_backtrace();
1347                 print('</pre>');
1348
1349                 // Exit program?
1350                 if ($doExit === true) {
1351                         exit();
1352                 } // END - if
1353         }
1354
1355         /**
1356          * Creates an instance of a debugger instance
1357          *
1358          * @param       $className              Name of the class (currently unsupported)
1359          * @param       $lineNumber             Line number where the call was made
1360          * @return      $debugInstance  An instance of a debugger class
1361          * @deprecated  Not fully, as the new Logger facilities are not finished yet.
1362          */
1363         public final static function createDebugInstance ($className, $lineNumber = NULL) {
1364                 // Is the instance set?
1365                 if (!GenericRegistry::getRegistry()->instanceExists('debug')) {
1366                         // Init debug instance
1367                         $debugInstance = NULL;
1368
1369                         // Try it
1370                         try {
1371                                 // Get a debugger instance
1372                                 $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_class'), $className);
1373                         } catch (NullPointerException $e) {
1374                                 // Didn't work, no instance there
1375                                 exit(sprintf('Cannot create debugInstance! Exception=%s,message=%s,className=%s,lineNumber=%d' . PHP_EOL, $e->__toString(), $e->getMessage(), $className, $lineNumber));
1376                         }
1377
1378                         // Empty string should be ignored and used for testing the middleware
1379                         DebugMiddleware::getSelfInstance()->output('');
1380
1381                         // Set it in registry
1382                         GenericRegistry::getRegistry()->addInstance('debug', $debugInstance);
1383                 } else {
1384                         // Get instance from registry
1385                         $debugInstance = GenericRegistry::getRegistry()->getDebugInstance();
1386                 }
1387
1388                 // Return it
1389                 return $debugInstance;
1390         }
1391
1392         /**
1393          * Simple output of a message with line-break
1394          *
1395          * @param       $message        Message to output
1396          * @return      void
1397          */
1398         public function outputLine ($message) {
1399                 // Simply output it
1400                 print($message . PHP_EOL);
1401         }
1402
1403         /**
1404          * Outputs a debug message whether to debug instance (should be set!) or
1405          * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
1406          * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
1407          *
1408          * @param       $message        Message we shall send out...
1409          * @param       $doPrint        Whether print or die here (default: print)
1410          * @paran       $stripTags      Whether to strip tags (default: false)
1411          * @return      void
1412          */
1413         public function debugOutput ($message, $doPrint = true, $stripTags = false) {
1414                 // Set debug instance to NULL
1415                 $debugInstance = NULL;
1416
1417                 // Get backtrace
1418                 $backtrace = debug_backtrace(!DEBUG_BACKTRACE_PROVIDE_OBJECT);
1419
1420                 // Is function partialStub/__callStatic ?
1421                 if (in_array($backtrace[1]['function'], array('partialStub', '__call', '__callStatic'))) {
1422                         // Prepend class::function:line from 3rd element
1423                         $message = sprintf('[%s::%s:%d]: %s',
1424                                 $backtrace[2]['class'],
1425                                 $backtrace[2]['function'],
1426                                 (isset($backtrace[2]['line']) ? $backtrace[2]['line'] : '0'),
1427                                 $message
1428                         );
1429                 } else {
1430                         // Prepend class::function:line from 2nd element
1431                         $message = sprintf('[%s::%s:%d]: %s',
1432                                 $backtrace[1]['class'],
1433                                 $backtrace[1]['function'],
1434                                 (isset($backtrace[1]['line']) ? $backtrace[1]['line'] : '0'),
1435                                 $message
1436                         );
1437                 }
1438
1439                 // Try it:
1440                 try {
1441                         // Get debug instance
1442                         $debugInstance = $this->getDebugInstance();
1443                 } catch (NullPointerException $e) {
1444                         // The debug instance is not set (yet)
1445                 }
1446
1447                 // Is the debug instance there?
1448                 if (is_object($debugInstance)) {
1449                         // Use debug output handler
1450                         $debugInstance->output($message, $stripTags);
1451
1452                         if ($doPrint === false) {
1453                                 // Die here if not printed
1454                                 exit();
1455                         } // END - if
1456                 } else {
1457                         // Are debug times enabled?
1458                         if (FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_output_timings') == 'Y') {
1459                                 // Prepent it
1460                                 $message = $this->getPrintableExecutionTime() . $message;
1461                         } // END - if
1462
1463                         // Put directly out
1464                         if ($doPrint === true) {
1465                                 // Print message
1466                                 $this->outputLine($message);
1467                         } else {
1468                                 // Die here
1469                                 exit($message);
1470                         }
1471                 }
1472         }
1473
1474         /**
1475          * Marks up the code by adding e.g. line numbers
1476          *
1477          * @param       $phpCode                Unmarked PHP code
1478          * @return      $markedCode             Marked PHP code
1479          */
1480         public function markupCode ($phpCode) {
1481                 // Init marked code
1482                 $markedCode = '';
1483
1484                 // Get last error
1485                 $errorArray = error_get_last();
1486
1487                 // Init the code with error message
1488                 if (is_array($errorArray)) {
1489                         // Get error infos
1490                         $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>',
1491                                 basename($errorArray['file']),
1492                                 $errorArray['line'],
1493                                 $errorArray['message'],
1494                                 $errorArray['type']
1495                         );
1496                 } // END - if
1497
1498                 // Add line number to the code
1499                 foreach (explode(chr(10), $phpCode) as $lineNo => $code) {
1500                         // Add line numbers
1501                         $markedCode .= sprintf('<span id="code_line">%s</span>: %s' . PHP_EOL,
1502                                 ($lineNo + 1),
1503                                 htmlentities($code, ENT_QUOTES)
1504                         );
1505                 } // END - foreach
1506
1507                 // Return the code
1508                 return $markedCode;
1509         }
1510
1511         /**
1512          * Filter a given GMT timestamp (non Uni* stamp!) to make it look more
1513          * beatiful for web-based front-ends. If null is given a message id
1514          * null_timestamp will be resolved and returned.
1515          *
1516          * @param       $timestamp      Timestamp to prepare (filter) for display
1517          * @return      $readable       A readable timestamp
1518          */
1519         public function doFilterFormatTimestamp ($timestamp) {
1520                 // Default value to return
1521                 $readable = '???';
1522
1523                 // Is the timestamp null?
1524                 if (is_null($timestamp)) {
1525                         // Get a message string
1526                         $readable = $this->getLanguageInstance()->getMessage('null_timestamp');
1527                 } else {
1528                         switch ($this->getLanguageInstance()->getLanguageCode()) {
1529                                 case 'de': // German format is a bit different to default
1530                                         // Split the GMT stamp up
1531                                         $dateTime  = explode(' ', $timestamp  );
1532                                         $dateArray = explode('-', $dateTime[0]);
1533                                         $timeArray = explode(':', $dateTime[1]);
1534
1535                                         // Construct the timestamp
1536                                         $readable = sprintf(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('german_date_time'),
1537                                                 $dateArray[0],
1538                                                 $dateArray[1],
1539                                                 $dateArray[2],
1540                                                 $timeArray[0],
1541                                                 $timeArray[1],
1542                                                 $timeArray[2]
1543                                         );
1544                                         break;
1545
1546                                 default: // Default is pass-through
1547                                         $readable = $timestamp;
1548                                         break;
1549                         } // END - switch
1550                 }
1551
1552                 // Return the stamp
1553                 return $readable;
1554         }
1555
1556         /**
1557          * Filter a given number into a localized number
1558          *
1559          * @param       $value          The raw value from e.g. database
1560          * @return      $localized      Localized value
1561          */
1562         public function doFilterFormatNumber ($value) {
1563                 // Generate it from config and localize dependencies
1564                 switch ($this->getLanguageInstance()->getLanguageCode()) {
1565                         case 'de': // German format is a bit different to default
1566                                 $localized = number_format($value, FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('decimals'), ',', '.');
1567                                 break;
1568
1569                         default: // US, etc.
1570                                 $localized = number_format($value, FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('decimals'), '.', ',');
1571                                 break;
1572                 } // END - switch
1573
1574                 // Return it
1575                 return $localized;
1576         }
1577
1578         /**
1579          * "Getter" for databse entry
1580          *
1581          * @return      $entry  An array with database entries
1582          * @throws      NullPointerException    If the database result is not found
1583          * @throws      InvalidDatabaseResultException  If the database result is invalid
1584          */
1585         protected final function getDatabaseEntry () {
1586                 // Is there an instance?
1587                 if (!$this->getResultInstance() instanceof SearchableResult) {
1588                         // Throw an exception here
1589                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1590                 } // END - if
1591
1592                 // Rewind it
1593                 $this->getResultInstance()->rewind();
1594
1595                 // Do we have an entry?
1596                 if ($this->getResultInstance()->valid() === false) {
1597                         // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available
1598                         throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
1599                 } // END - if
1600
1601                 // Get next entry
1602                 $this->getResultInstance()->next();
1603
1604                 // Fetch it
1605                 $entry = $this->getResultInstance()->current();
1606
1607                 // And return it
1608                 return $entry;
1609         }
1610
1611         /**
1612          * Getter for field name
1613          *
1614          * @param       $fieldName              Field name which we shall get
1615          * @return      $fieldValue             Field value from the user
1616          * @throws      NullPointerException    If the result instance is null
1617          */
1618         public final function getField (string $fieldName) {
1619                 // Default field value
1620                 $fieldValue = NULL;
1621
1622                 // Get result instance
1623                 $resultInstance = $this->getResultInstance();
1624
1625                 // Is this instance null?
1626                 if (is_null($resultInstance)) {
1627                         // Then the user instance is no longer valid (expired cookies?)
1628                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1629                 } // END - if
1630
1631                 // Get current array
1632                 $fieldArray = $resultInstance->current();
1633                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, true).'</pre>');
1634
1635                 // Convert dashes to underscore
1636                 $fieldName2 = StringUtils::convertDashesToUnderscores($fieldName);
1637
1638                 // Does the field exist?
1639                 if ($this->isFieldSet($fieldName)) {
1640                         // Get it
1641                         $fieldValue = $fieldArray[$fieldName2];
1642                 } elseif (defined('DEVELOPER')) {
1643                         // Missing field entry, may require debugging
1644                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldArray<pre>=' . print_r($fieldArray, true) . '</pre>,fieldName=' . $fieldName . ' not found!');
1645                 } else {
1646                         // Missing field entry, may require debugging
1647                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldName=' . $fieldName . ' not found!');
1648                 }
1649
1650                 // Return it
1651                 return $fieldValue;
1652         }
1653
1654         /**
1655          * Checks if given field is set
1656          *
1657          * @param       $fieldName      Field name to check
1658          * @return      $isSet          Whether the given field name is set
1659          * @throws      NullPointerException    If the result instance is null
1660          */
1661         public function isFieldSet (string $fieldName) {
1662                 // Get result instance
1663                 $resultInstance = $this->getResultInstance();
1664
1665                 // Is this instance null?
1666                 if (is_null($resultInstance)) {
1667                         // Then the user instance is no longer valid (expired cookies?)
1668                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1669                 } // END - if
1670
1671                 // Get current array
1672                 $fieldArray = $resultInstance->current();
1673                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . $this->__toString() . ':' . __LINE__ . '] fieldName=' . $fieldName . ',fieldArray=<pre>'.print_r($fieldArray, true).'</pre>');
1674
1675                 // Convert dashes to underscore
1676                 $fieldName = StringUtils::convertDashesToUnderscores($fieldName);
1677
1678                 // Determine it
1679                 $isSet = isset($fieldArray[$fieldName]);
1680
1681                 // Return result
1682                 return $isSet;
1683         }
1684
1685         /**
1686          * Flushs all pending updates to the database layer
1687          *
1688          * @return      void
1689          */
1690         public function flushPendingUpdates () {
1691                 // Get result instance
1692                 $resultInstance = $this->getResultInstance();
1693
1694                 // Do we have data to update?
1695                 if ((is_object($resultInstance)) && ($resultInstance->ifDataNeedsFlush())) {
1696                         // Get wrapper class name config entry
1697                         $configEntry = $resultInstance->getUpdateInstance()->getWrapperConfigEntry();
1698
1699                         // Create object instance
1700                         $wrapperInstance = DatabaseWrapperFactory::createWrapperByConfiguredName($configEntry);
1701
1702                         // Yes, then send the whole result to the database layer
1703                         $wrapperInstance->doUpdateByResult($this->getResultInstance());
1704                 } // END - if
1705         }
1706
1707         /**
1708          * Outputs a deprecation warning to the developer.
1709          *
1710          * @param       $message        The message we shall output to the developer
1711          * @return      void
1712          * @todo        Write a logging mechanism for productive mode
1713          */
1714         public function deprecationWarning ($message) {
1715                 // Is developer mode active?
1716                 if (defined('DEVELOPER')) {
1717                         // Debug instance is there?
1718                         if (!is_null($this->getDebugInstance())) {
1719                                 // Output stub message
1720                                 self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($message);
1721                         } else {
1722                                 // Trigger an error
1723                                 trigger_error($message . "<br />\n");
1724                                 exit;
1725                         }
1726                 } else {
1727                         // @TODO Finish this part!
1728                         $this->partialStub('Developer mode inactive. Message:' . $message);
1729                 }
1730         }
1731
1732         /**
1733          * Checks whether the given PHP extension is loaded
1734          *
1735          * @param       $phpExtension   The PHP extension we shall check
1736          * @return      $isLoaded       Whether the PHP extension is loaded
1737          */
1738         public final function isPhpExtensionLoaded ($phpExtension) {
1739                 // Is it loaded?
1740                 $isLoaded = in_array($phpExtension, get_loaded_extensions());
1741
1742                 // Return result
1743                 return $isLoaded;
1744         }
1745
1746         /**
1747          * "Getter" as a time() replacement but with milliseconds. You should use this
1748          * method instead of the encapsulated getimeofday() function.
1749          *
1750          * @return      $milliTime      Timestamp with milliseconds
1751          */
1752         public function getMilliTime () {
1753                 // Get the time of day as float
1754                 $milliTime = gettimeofday(true);
1755
1756                 // Return it
1757                 return $milliTime;
1758         }
1759
1760         /**
1761          * Idles (sleeps) for given milliseconds
1762          *
1763          * @return      $hasSlept       Whether it goes fine
1764          */
1765         public function idle ($milliSeconds) {
1766                 // Sleep is fine by default
1767                 $hasSlept = true;
1768
1769                 // Idle so long with found function
1770                 if (function_exists('time_sleep_until')) {
1771                         // Get current time and add idle time
1772                         $sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
1773
1774                         // New PHP 5.1.0 function found, ignore errors
1775                         $hasSlept = @time_sleep_until($sleepUntil);
1776                 } else {
1777                         /*
1778                          * My Sun station doesn't have that function even with latest PHP
1779                          * package. :(
1780                          */
1781                         usleep($milliSeconds * 1000);
1782                 }
1783
1784                 // Return result
1785                 return $hasSlept;
1786         }
1787         /**
1788          * Converts a hexadecimal string, even with negative sign as first string to
1789          * a decimal number using BC functions.
1790          *
1791          * This work is based on comment #86673 on php.net documentation page at:
1792          * <http://de.php.net/manual/en/function.dechex.php#86673>
1793          *
1794          * @param       $hex    Hexadecimal string
1795          * @return      $dec    Decimal number
1796          */
1797         protected function hex2dec ($hex) {
1798                 // Convert to all lower-case
1799                 $hex = strtolower($hex);
1800
1801                 // Detect sign (negative/positive numbers)
1802                 $sign = '';
1803                 if (substr($hex, 0, 1) == '-') {
1804                         $sign = '-';
1805                         $hex = substr($hex, 1);
1806                 } // END - if
1807
1808                 // Decode the hexadecimal string into a decimal number
1809                 $dec = 0;
1810                 for ($i = strlen($hex) - 1, $e = 1; $i >= 0; $i--, $e = bcmul($e, 16)) {
1811                         $factor = self::$hexdec[substr($hex, $i, 1)];
1812                         $dec = bcadd($dec, bcmul($factor, $e));
1813                 } // END - for
1814
1815                 // Return the decimal number
1816                 return $sign . $dec;
1817         }
1818
1819         /**
1820          * Converts even very large decimal numbers, also signed, to a hexadecimal
1821          * string.
1822          *
1823          * This work is based on comment #97756 on php.net documentation page at:
1824          * <http://de.php.net/manual/en/function.hexdec.php#97756>
1825          *
1826          * @param       $dec            Decimal number, even with negative sign
1827          * @param       $maxLength      Optional maximum length of the string
1828          * @return      $hex    Hexadecimal string
1829          */
1830         protected function dec2hex ($dec, $maxLength = 0) {
1831                 // maxLength can be zero or devideable by 2
1832                 assert(($maxLength == 0) || (($maxLength % 2) == 0));
1833
1834                 // Detect sign (negative/positive numbers)
1835                 $sign = '';
1836                 if ($dec < 0) {
1837                         $sign = '-';
1838                         $dec = abs($dec);
1839                 } // END - if
1840
1841                 // Encode the decimal number into a hexadecimal string
1842                 $hex = '';
1843                 do {
1844                         $hex = self::$dechex[($dec % (2 ^ 4))] . $hex;
1845                         $dec /= (2 ^ 4);
1846                 } while ($dec >= 1);
1847
1848                 /*
1849                  * Leading zeros are required for hex-decimal "numbers". In some
1850                  * situations more leading zeros are wanted, so check for both
1851                  * conditions.
1852                  */
1853                 if ($maxLength > 0) {
1854                         // Prepend more zeros
1855                         $hex = str_pad($hex, $maxLength, '0', STR_PAD_LEFT);
1856                 } elseif ((strlen($hex) % 2) != 0) {
1857                         // Only make string's length dividable by 2
1858                         $hex = '0' . $hex;
1859                 }
1860
1861                 // Return the hexadecimal string
1862                 return $sign . $hex;
1863         }
1864
1865         /**
1866          * Converts a ASCII string (0 to 255) into a decimal number.
1867          *
1868          * @param       $asc    The ASCII string to be converted
1869          * @return      $dec    Decimal number
1870          */
1871         protected function asc2dec ($asc) {
1872                 // Convert it into a hexadecimal number
1873                 $hex = bin2hex($asc);
1874
1875                 // And back into a decimal number
1876                 $dec = $this->hex2dec($hex);
1877
1878                 // Return it
1879                 return $dec;
1880         }
1881
1882         /**
1883          * Converts a decimal number into an ASCII string.
1884          *
1885          * @param       $dec            Decimal number
1886          * @return      $asc    An ASCII string
1887          */
1888         protected function dec2asc ($dec) {
1889                 // First convert the number into a hexadecimal string
1890                 $hex = $this->dec2hex($dec);
1891
1892                 // Then convert it into the ASCII string
1893                 $asc = $this->hex2asc($hex);
1894
1895                 // Return it
1896                 return $asc;
1897         }
1898
1899         /**
1900          * Converts a hexadecimal number into an ASCII string. Negative numbers
1901          * are not allowed.
1902          *
1903          * @param       $hex    Hexadecimal string
1904          * @return      $asc    An ASCII string
1905          */
1906         protected function hex2asc ($hex) {
1907                 // Check for length, it must be devideable by 2
1908                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('hex='.$hex);
1909                 assert((strlen($hex) % 2) == 0);
1910
1911                 // Walk the string
1912                 $asc = '';
1913                 for ($idx = 0; $idx < strlen($hex); $idx+=2) {
1914                         // Get the decimal number of the chunk
1915                         $part = hexdec(substr($hex, $idx, 2));
1916
1917                         // Add it to the final string
1918                         $asc .= chr($part);
1919                 } // END - for
1920
1921                 // Return the final string
1922                 return $asc;
1923         }
1924
1925         /**
1926          * Checks whether the given encoded data was encoded with Base64
1927          *
1928          * @param       $encodedData    Encoded data we shall check
1929          * @return      $isBase64               Whether the encoded data is Base64
1930          */
1931         protected function isBase64Encoded ($encodedData) {
1932                 // Determine it
1933                 $isBase64 = (@base64_decode($encodedData, true) !== false);
1934
1935                 // Return it
1936                 return $isBase64;
1937         }
1938
1939         /**
1940          * Gets a cache key from Criteria instance
1941          *
1942          * @param       $criteriaInstance       An instance of a Criteria class
1943          * @param       $onlyKeys                       Only use these keys for a cache key
1944          * @return      $cacheKey                       A cache key suitable for lookup/storage purposes
1945          */
1946         protected function getCacheKeyByCriteria (Criteria $criteriaInstance, array $onlyKeys = array()) {
1947                 // Generate it
1948                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FRAMEWORK-SYSTEM: criteriaInstance=' . $criteriaInstance->__toString() . ',onlyKeys()=' . count($onlyKeys) . ' - CALLED!');
1949                 $cacheKey = sprintf('%s@%s',
1950                         $this->__toString(),
1951                         $criteriaInstance->getCacheKey($onlyKeys)
1952                 );
1953
1954                 // And return it
1955                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FRAMEWORK-SYSTEM: cacheKey=' . $cacheKey . ' - EXIT!');
1956                 return $cacheKey;
1957         }
1958
1959         /**
1960          * Getter for startup time in miliseconds
1961          *
1962          * @return      $startupTime    Startup time in miliseconds
1963          */
1964         protected function getStartupTime () {
1965                 return self::$startupTime;
1966         }
1967
1968         /**
1969          * "Getter" for a printable currently execution time in nice braces
1970          *
1971          * @return      $executionTime  Current execution time in nice braces
1972          */
1973         protected function getPrintableExecutionTime () {
1974                 // Caculate the execution time
1975                 $executionTime = microtime(true) - $this->getStartupTime();
1976
1977                 // Pack it in nice braces
1978                 $executionTime = sprintf('[ %01.5f ] ', $executionTime);
1979
1980                 // And return it
1981                 return $executionTime;
1982         }
1983
1984         /**
1985          * Hashes a given string with a simple but stronger hash function (no salt)
1986          * and hex-encode it.
1987          *
1988          * @param       $str    The string to be hashed
1989          * @return      $hash   The hash from string $str
1990          */
1991         public static final function hash ($str) {
1992                 // Hash given string with (better secure) hasher
1993                 $hash = bin2hex(mhash(MHASH_SHA256, $str));
1994
1995                 // Return it
1996                 return $hash;
1997         }
1998
1999         /**
2000          * "Getter" for length of hash() output. This will be "cached" to speed up
2001          * things.
2002          *
2003          * @return      $length         Length of hash() output
2004          */
2005         public static final function getHashLength () {
2006                 // Is it cashed?
2007                 if (is_null(self::$hashLength)) {
2008                         // No, then hash a string and save its length.
2009                         self::$hashLength = strlen(self::hash('abc123'));
2010                 } // END - if
2011
2012                 // Return it
2013                 return self::$hashLength;
2014         }
2015
2016         /**
2017          * Checks whether the given number is really a number (only chars 0-9).
2018          *
2019          * @param       $num            A string consisting only chars between 0 and 9
2020          * @param       $castValue      Whether to cast the value to double. Do only use this to secure numbers from Requestable classes.
2021          * @param       $assertMismatch         Whether to assert mismatches
2022          * @return      $ret            The (hopefully) secured numbered value
2023          */
2024         public function bigintval ($num, $castValue = true, $assertMismatch = false) {
2025                 // Filter all numbers out
2026                 $ret = preg_replace('/[^0123456789]/', '', $num);
2027
2028                 // Shall we cast?
2029                 if ($castValue === true) {
2030                         // Cast to biggest numeric type
2031                         $ret = (double) $ret;
2032                 } // END - if
2033
2034                 // Assert only if requested
2035                 if ($assertMismatch === true) {
2036                         // Has the whole value changed?
2037                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2038                 } // END - if
2039
2040                 // Return result
2041                 return $ret;
2042         }
2043
2044         /**
2045          * Checks whether the given hexadecimal number is really a hex-number (only chars 0-9,a-f).
2046          *
2047          * @param       $num    A string consisting only chars between 0 and 9
2048          * @param       $assertMismatch         Whether to assert mismatches
2049          * @return      $ret    The (hopefully) secured hext-numbered value
2050          */
2051         public function hexval ($num, $assertMismatch = false) {
2052                 // Filter all numbers out
2053                 $ret = preg_replace('/[^0123456789abcdefABCDEF]/', '', $num);
2054
2055                 // Assert only if requested
2056                 if ($assertMismatch === true) {
2057                         // Has the whole value changed?
2058                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2059                 } // END - if
2060
2061                 // Return result
2062                 return $ret;
2063         }
2064
2065         /**
2066          * Determines if an element is set in the generic array
2067          *
2068          * @param       $keyGroup       Main group for the key
2069          * @param       $subGroup       Sub group for the key
2070          * @param       $key            Key to check
2071          * @param       $element        Element to check
2072          * @return      $isset          Whether the given key is set
2073          */
2074         protected final function isGenericArrayElementSet ($keyGroup, $subGroup, $key, $element) {
2075                 // Debug message
2076                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2077
2078                 // Is it there?
2079                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
2080
2081                 // Return it
2082                 return $isset;
2083         }
2084         /**
2085          * Determines if a key is set in the generic array
2086          *
2087          * @param       $keyGroup       Main group for the key
2088          * @param       $subGroup       Sub group for the key
2089          * @param       $key            Key to check
2090          * @return      $isset          Whether the given key is set
2091          */
2092         protected final function isGenericArrayKeySet ($keyGroup, $subGroup, $key) {
2093                 // Debug message
2094                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2095
2096                 // Is it there?
2097                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key]);
2098
2099                 // Return it
2100                 return $isset;
2101         }
2102
2103
2104         /**
2105          * Determines if a group is set in the generic array
2106          *
2107          * @param       $keyGroup       Main group
2108          * @param       $subGroup       Sub group
2109          * @return      $isset          Whether the given group is set
2110          */
2111         protected final function isGenericArrayGroupSet ($keyGroup, $subGroup) {
2112                 // Debug message
2113                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
2114
2115                 // Is it there?
2116                 $isset = isset($this->genericArray[$keyGroup][$subGroup]);
2117
2118                 // Return it
2119                 return $isset;
2120         }
2121
2122         /**
2123          * Getter for sub key group
2124          *
2125          * @param       $keyGroup       Main key group
2126          * @param       $subGroup       Sub key group
2127          * @return      $array          An array with all array elements
2128          */
2129         protected final function getGenericSubArray ($keyGroup, $subGroup) {
2130                 // Is it there?
2131                 if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
2132                         // No, then abort here
2133                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
2134                         exit;
2135                 } // END - if
2136
2137                 // Debug message
2138                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',value=' . print_r($this->genericArray[$keyGroup][$subGroup], true));
2139
2140                 // Return it
2141                 return $this->genericArray[$keyGroup][$subGroup];
2142         }
2143
2144         /**
2145          * Unsets a given key in generic array
2146          *
2147          * @param       $keyGroup       Main group for the key
2148          * @param       $subGroup       Sub group for the key
2149          * @param       $key            Key to unset
2150          * @return      void
2151          */
2152         protected final function unsetGenericArrayKey ($keyGroup, $subGroup, $key) {
2153                 // Debug message
2154                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2155
2156                 // Remove it
2157                 unset($this->genericArray[$keyGroup][$subGroup][$key]);
2158         }
2159
2160         /**
2161          * Unsets a given element in generic array
2162          *
2163          * @param       $keyGroup       Main group for the key
2164          * @param       $subGroup       Sub group for the key
2165          * @param       $key            Key to unset
2166          * @param       $element        Element to unset
2167          * @return      void
2168          */
2169         protected final function unsetGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
2170                 // Debug message
2171                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2172
2173                 // Remove it
2174                 unset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
2175         }
2176
2177         /**
2178          * Append a string to a given generic array key
2179          *
2180          * @param       $keyGroup       Main group for the key
2181          * @param       $subGroup       Sub group for the key
2182          * @param       $key            Key to unset
2183          * @param       $value          Value to add/append
2184          * @return      void
2185          */
2186         protected final function appendStringToGenericArrayKey ($keyGroup, $subGroup, $key, $value, $appendGlue = '') {
2187                 // Debug message
2188                 //* 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);
2189
2190                 // Is it already there?
2191                 if ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2192                         // Append it
2193                         $this->genericArray[$keyGroup][$subGroup][$key] .= $appendGlue . (string) $value;
2194                 } else {
2195                         // Add it
2196                         $this->genericArray[$keyGroup][$subGroup][$key] = (string) $value;
2197                 }
2198         }
2199
2200         /**
2201          * Append a string to a given generic array element
2202          *
2203          * @param       $keyGroup       Main group for the key
2204          * @param       $subGroup       Sub group for the key
2205          * @param       $key            Key to unset
2206          * @param       $element        Element to check
2207          * @param       $value          Value to add/append
2208          * @return      void
2209          */
2210         protected final function appendStringToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value, $appendGlue = '') {
2211                 // Debug message
2212                 //* 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);
2213
2214                 // Is it already there?
2215                 if ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2216                         // Append it
2217                         $this->genericArray[$keyGroup][$subGroup][$key][$element] .= $appendGlue . (string) $value;
2218                 } else {
2219                         // Add it
2220                         $this->setStringGenericArrayElement($keyGroup, $subGroup, $key, $element, $value);
2221                 }
2222         }
2223
2224         /**
2225          * Sets a string in a given generic array element
2226          *
2227          * @param       $keyGroup       Main group for the key
2228          * @param       $subGroup       Sub group for the key
2229          * @param       $key            Key to unset
2230          * @param       $element        Element to check
2231          * @param       $value          Value to add/append
2232          * @return      void
2233          */
2234         protected final function setStringGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value, $appendGlue = '') {
2235                 // Debug message
2236                 //* 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);
2237
2238                 // Set it
2239                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = (string) $value;
2240         }
2241
2242         /**
2243          * Initializes given generic array group
2244          *
2245          * @param       $keyGroup       Main group for the key
2246          * @param       $subGroup       Sub group for the key
2247          * @param       $key            Key to use
2248          * @param       $forceInit      Optionally force initialization
2249          * @return      void
2250          */
2251         protected final function initGenericArrayGroup ($keyGroup, $subGroup, $forceInit = false) {
2252                 // Debug message
2253                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',forceInit=' . intval($forceInit));
2254
2255                 // Is it already set?
2256                 if (($forceInit === false) && ($this->isGenericArrayGroupSet($keyGroup, $subGroup))) {
2257                         // Already initialized
2258                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' already initialized.');
2259                         exit;
2260                 } // END - if
2261
2262                 // Initialize it
2263                 $this->genericArray[$keyGroup][$subGroup] = array();
2264         }
2265
2266         /**
2267          * Initializes given generic array key
2268          *
2269          * @param       $keyGroup       Main group for the key
2270          * @param       $subGroup       Sub group for the key
2271          * @param       $key            Key to use
2272          * @param       $forceInit      Optionally force initialization
2273          * @return      void
2274          */
2275         protected final function initGenericArrayKey ($keyGroup, $subGroup, $key, $forceInit = false) {
2276                 // Debug message
2277                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',forceInit=' . intval($forceInit));
2278
2279                 // Is it already set?
2280                 if (($forceInit === false) && ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key))) {
2281                         // Already initialized
2282                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' already initialized.');
2283                         exit;
2284                 } // END - if
2285
2286                 // Initialize it
2287                 $this->genericArray[$keyGroup][$subGroup][$key] = array();
2288         }
2289
2290         /**
2291          * Initializes given generic array element
2292          *
2293          * @param       $keyGroup       Main group for the key
2294          * @param       $subGroup       Sub group for the key
2295          * @param       $key            Key to use
2296          * @param       $element        Element to use
2297          * @param       $forceInit      Optionally force initialization
2298          * @return      void
2299          */
2300         protected final function initGenericArrayElement ($keyGroup, $subGroup, $key, $element, $forceInit = false) {
2301                 // Debug message
2302                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',forceInit=' . intval($forceInit));
2303
2304                 // Is it already set?
2305                 if (($forceInit === false) && ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element))) {
2306                         // Already initialized
2307                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' already initialized.');
2308                         exit;
2309                 } // END - if
2310
2311                 // Initialize it
2312                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = array();
2313         }
2314
2315         /**
2316          * Pushes an element to a generic key
2317          *
2318          * @param       $keyGroup       Main group for the key
2319          * @param       $subGroup       Sub group for the key
2320          * @param       $key            Key to use
2321          * @param       $value          Value to add/append
2322          * @return      $count          Number of array elements
2323          */
2324         protected final function pushValueToGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
2325                 // Debug message
2326                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, true));
2327
2328                 // Is it set?
2329                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2330                         // Initialize array
2331                         $this->initGenericArrayKey($keyGroup, $subGroup, $key);
2332                 } // END - if
2333
2334                 // Then push it
2335                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key], $value);
2336
2337                 // Return count
2338                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
2339                 //* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
2340                 return $count;
2341         }
2342
2343         /**
2344          * Pushes an element to a generic array element
2345          *
2346          * @param       $keyGroup       Main group for the key
2347          * @param       $subGroup       Sub group for the key
2348          * @param       $key            Key to use
2349          * @param       $element        Element to check
2350          * @param       $value          Value to add/append
2351          * @return      $count          Number of array elements
2352          */
2353         protected final function pushValueToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
2354                 // Debug message
2355                 //* 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));
2356
2357                 // Is it set?
2358                 if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2359                         // Initialize array
2360                         $this->initGenericArrayElement($keyGroup, $subGroup, $key, $element);
2361                 } // END - if
2362
2363                 // Then push it
2364                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key][$element], $value);
2365
2366                 // Return count
2367                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
2368                 //* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
2369                 return $count;
2370         }
2371
2372         /**
2373          * Pops an element from  a generic group
2374          *
2375          * @param       $keyGroup       Main group for the key
2376          * @param       $subGroup       Sub group for the key
2377          * @param       $key            Key to unset
2378          * @return      $value          Last "popped" value
2379          */
2380         protected final function popGenericArrayElement ($keyGroup, $subGroup, $key) {
2381                 // Debug message
2382                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2383
2384                 // Is it set?
2385                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2386                         // Not found
2387                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
2388                         exit;
2389                 } // END - if
2390
2391                 // Then "pop" it
2392                 $value = array_pop($this->genericArray[$keyGroup][$subGroup][$key]);
2393
2394                 // Return value
2395                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
2396                 //* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, true) . PHP_EOL);
2397                 return $value;
2398         }
2399
2400         /**
2401          * Shifts an element from  a generic group
2402          *
2403          * @param       $keyGroup       Main group for the key
2404          * @param       $subGroup       Sub group for the key
2405          * @param       $key            Key to unset
2406          * @return      $value          Last "popped" value
2407          */
2408         protected final function shiftGenericArrayElement ($keyGroup, $subGroup, $key) {
2409                 // Debug message
2410                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2411
2412                 // Is it set?
2413                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2414                         // Not found
2415                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
2416                         exit;
2417                 } // END - if
2418
2419                 // Then "shift" it
2420                 $value = array_shift($this->genericArray[$keyGroup][$subGroup][$key]);
2421
2422                 // Return value
2423                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
2424                 //* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, true) . PHP_EOL);
2425                 return $value;
2426         }
2427
2428         /**
2429          * Count generic array group
2430          *
2431          * @param       $keyGroup       Main group for the key
2432          * @return      $count          Count of given group
2433          */
2434         protected final function countGenericArray ($keyGroup) {
2435                 // Debug message
2436                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
2437
2438                 // Is it there?
2439                 if (!isset($this->genericArray[$keyGroup])) {
2440                         // Abort here
2441                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' not found.');
2442                         exit;
2443                 } // END - if
2444
2445                 // Then count it
2446                 $count = count($this->genericArray[$keyGroup]);
2447
2448                 // Debug message
2449                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',count=' . $count);
2450
2451                 // Return it
2452                 return $count;
2453         }
2454
2455         /**
2456          * Count generic array sub group
2457          *
2458          * @param       $keyGroup       Main group for the key
2459          * @param       $subGroup       Sub group for the key
2460          * @return      $count          Count of given group
2461          */
2462         protected final function countGenericArrayGroup ($keyGroup, $subGroup) {
2463                 // Debug message
2464                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
2465
2466                 // Is it there?
2467                 if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
2468                         // Abort here
2469                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
2470                         exit;
2471                 } // END - if
2472
2473                 // Then count it
2474                 $count = count($this->genericArray[$keyGroup][$subGroup]);
2475
2476                 // Debug message
2477                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',count=' . $count);
2478
2479                 // Return it
2480                 return $count;
2481         }
2482
2483         /**
2484          * Count generic array elements
2485          *
2486          * @param       $keyGroup       Main group for the key
2487          * @param       $subGroup       Sub group for the key
2488          * @para        $key            Key to count
2489          * @return      $count          Count of given key
2490          */
2491         protected final function countGenericArrayElements ($keyGroup, $subGroup, $key) {
2492                 // Debug message
2493                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2494
2495                 // Is it there?
2496                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2497                         // Abort here
2498                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
2499                         exit;
2500                 } elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
2501                         // Not valid
2502                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' is not an array.');
2503                         exit;
2504                 }
2505
2506                 // Then count it
2507                 $count = count($this->genericArray[$keyGroup][$subGroup][$key]);
2508
2509                 // Debug message
2510                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',count=' . $count);
2511
2512                 // Return it
2513                 return $count;
2514         }
2515
2516         /**
2517          * Getter for whole generic group array
2518          *
2519          * @param       $keyGroup       Key group to get
2520          * @return      $array          Whole generic array group
2521          */
2522         protected final function getGenericArray ($keyGroup) {
2523                 // Debug message
2524                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
2525
2526                 // Is it there?
2527                 if (!isset($this->genericArray[$keyGroup])) {
2528                         // Then abort here
2529                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' does not exist.');
2530                         exit;
2531                 } // END - if
2532
2533                 // Return it
2534                 return $this->genericArray[$keyGroup];
2535         }
2536
2537         /**
2538          * Setter for generic array key
2539          *
2540          * @param       $keyGroup       Key group to get
2541          * @param       $subGroup       Sub group for the key
2542          * @param       $key            Key to unset
2543          * @param       $value          Mixed value from generic array element
2544          * @return      void
2545          */
2546         protected final function setGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
2547                 // Debug message
2548                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, true));
2549
2550                 // Set value here
2551                 $this->genericArray[$keyGroup][$subGroup][$key] = $value;
2552         }
2553
2554         /**
2555          * Getter for generic array key
2556          *
2557          * @param       $keyGroup       Key group to get
2558          * @param       $subGroup       Sub group for the key
2559          * @param       $key            Key to unset
2560          * @return      $value          Mixed value from generic array element
2561          */
2562         protected final function getGenericArrayKey ($keyGroup, $subGroup, $key) {
2563                 // Debug message
2564                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2565
2566                 // Is it there?
2567                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2568                         // Then abort here
2569                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' does not exist.');
2570                         exit;
2571                 } // END - if
2572
2573                 // Return it
2574                 return $this->genericArray[$keyGroup][$subGroup][$key];
2575         }
2576
2577         /**
2578          * Sets a value in given generic array key/element
2579          *
2580          * @param       $keyGroup       Main group for the key
2581          * @param       $subGroup       Sub group for the key
2582          * @param       $key            Key to set
2583          * @param       $element        Element to set
2584          * @param       $value          Value to set
2585          * @return      void
2586          */
2587         protected final function setGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
2588                 // Debug message
2589                 //* 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));
2590
2591                 // Then set it
2592                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = $value;
2593         }
2594
2595         /**
2596          * Getter for generic array element
2597          *
2598          * @param       $keyGroup       Key group to get
2599          * @param       $subGroup       Sub group for the key
2600          * @param       $key            Key to look for
2601          * @param       $element        Element to look for
2602          * @return      $value          Mixed value from generic array element
2603          */
2604         protected final function getGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
2605                 // Debug message
2606                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2607
2608                 // Is it there?
2609                 if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2610                         // Then abort here
2611                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' does not exist.');
2612                         exit;
2613                 } // END - if
2614
2615                 // Return it
2616                 return $this->genericArray[$keyGroup][$subGroup][$key][$element];
2617         }
2618
2619         /**
2620          * Checks if a given sub group is valid (array)
2621          *
2622          * @param       $keyGroup       Key group to get
2623          * @param       $subGroup       Sub group for the key
2624          * @return      $isValid        Whether given sub group is valid
2625          */
2626         protected final function isValidGenericArrayGroup ($keyGroup, $subGroup) {
2627                 // Debug message
2628                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
2629
2630                 // Determine it
2631                 $isValid = (($this->isGenericArrayGroupSet($keyGroup, $subGroup)) && (is_array($this->getGenericSubArray($keyGroup, $subGroup))));
2632
2633                 // Return it
2634                 return $isValid;
2635         }
2636
2637         /**
2638          * Checks if a given key is valid (array)
2639          *
2640          * @param       $keyGroup       Key group to get
2641          * @param       $subGroup       Sub group for the key
2642          * @param       $key            Key to check
2643          * @return      $isValid        Whether given sub group is valid
2644          */
2645         protected final function isValidGenericArrayKey ($keyGroup, $subGroup, $key) {
2646                 // Debug message
2647                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2648
2649                 // Determine it
2650                 $isValid = (($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) && (is_array($this->getGenericArrayKey($keyGroup, $subGroup, $key))));
2651
2652                 // Return it
2653                 return $isValid;
2654         }
2655
2656         /**
2657          * Initializes the web output instance
2658          *
2659          * @return      void
2660          */
2661         protected function initWebOutputInstance () {
2662                 // Get application instance
2663                 $applicationInstance = GenericRegistry::getRegistry()->getInstance('application');
2664
2665                 // Init web output instance
2666                 $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class', array($applicationInstance));
2667
2668                 // Set it locally
2669                 $this->setWebOutputInstance($outputInstance);
2670         }
2671
2672         /**
2673          * Translates boolean true to 'Y' and false to 'N'
2674          *
2675          * @param       $boolean                Boolean value
2676          * @return      $translated             Translated boolean value
2677          */
2678         public static final function translateBooleanToYesNo (bool $boolean) {
2679                 // Make sure it is really boolean
2680                 assert(is_bool($boolean));
2681
2682                 // "Translate" it
2683                 $translated = ($boolean === true) ? 'Y' : 'N';
2684
2685                 // ... and return it
2686                 return $translated;
2687         }
2688
2689         /**
2690          * Creates a full-qualified file name (FQFN) for given file name by adding
2691          * a configured temporary file path to it.
2692          *
2693          * @param       $infoInstance   An instance of a SplFileInfo class
2694          * @return      $tempInstance   An instance of a SplFileInfo class (temporary file)
2695          * @throw       PathWriteProtectedException If the path in 'temp_file_path' is write-protected
2696          * @throws      FileIoException If the file cannot be written
2697          */
2698          protected static function createTempPathForFile (SplFileInfo $infoInstance) {
2699                 // Get config entry
2700                 $basePath = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('temp_file_path');
2701
2702                 // Is the path writeable?
2703                 if (!is_writable($basePath)) {
2704                         // Path is write-protected
2705                         throw new PathWriteProtectedException($infoInstance, self::EXCEPTION_PATH_CANNOT_BE_WRITTEN);
2706                 } // END - if
2707
2708                 // Add it
2709                 $tempInstance = new SplFileInfo($basePath . DIRECTORY_SEPARATOR . $infoInstance->getBasename());
2710
2711                 // Is it reachable?
2712                 if (!FrameworkBootstrap::isReachableFilePath($tempInstance)) {
2713                         // Not reachable
2714                         throw new FileIoException($tempInstance, self::EXCEPTION_FILE_NOT_REACHABLE);
2715                 } // END - if
2716
2717                 // Return it
2718                 return $tempInstance;
2719          }
2720
2721         /**
2722          * "Getter" for a printable state name
2723          *
2724          * @return      $stateName      Name of the node's state in a printable format
2725          */
2726         public final function getPrintableState () {
2727                 // Default is 'null'
2728                 $stateName = 'null';
2729
2730                 // Get the state instance
2731                 $stateInstance = $this->getStateInstance();
2732
2733                 // Is it an instance of Stateable?
2734                 if ($stateInstance instanceof Stateable) {
2735                         // Then use that state name
2736                         $stateName = $stateInstance->getStateName();
2737                 } // END - if
2738
2739                 // Return result
2740                 return $stateName;
2741         }
2742
2743 }