]> 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\EntryPoint\ApplicationEntryPoint;
8 use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
9 use Org\Mxchange\CoreFramework\Filesystem\FileIoException;
10 use Org\Mxchange\CoreFramework\Filesystem\PathWriteProtectedException;
11 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
12 use Org\Mxchange\CoreFramework\Generic\NullPointerException;
13 use Org\Mxchange\CoreFramework\Generic\UnsupportedOperationException;
14 use Org\Mxchange\CoreFramework\Helper\Application\ApplicationHelper;
15 use Org\Mxchange\CoreFramework\Loader\ClassLoader;
16 use Org\Mxchange\CoreFramework\Manager\ManageableApplication;
17 use Org\Mxchange\CoreFramework\Middleware\Debug\DebugMiddleware;
18 use Org\Mxchange\CoreFramework\Registry\Object\ObjectRegistry;
19 use Org\Mxchange\CoreFramework\Result\Database\CachedDatabaseResult;
20 use Org\Mxchange\CoreFramework\State\Stateable;
21 use Org\Mxchange\CoreFramework\Stream\Output\OutputStreamer;
22 use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils;
23
24 // Import SPL stuff
25 use \BadMethodCallException;
26 use \InvalidArgumentException;
27 use \ReflectionClass;
28 use \SplFileInfo;
29 use \stdClass;
30
31 /**
32  * The simulator system class is the super class of all other classes. This
33  * class handles saving of games etc.
34  *
35  * @author              Roland Haeder <webmaster@shipsimu.org>
36  * @version             0.0.0
37  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
38  * @license             GNU GPL 3.0 or any newer version
39  * @link                http://www.shipsimu.org
40  *
41  * This program is free software: you can redistribute it and/or modify
42  * it under the terms of the GNU General Public License as published by
43  * the Free Software Foundation, either version 3 of the License, or
44  * (at your option) any later version.
45  *
46  * This program is distributed in the hope that it will be useful,
47  * but WITHOUT ANY WARRANTY; without even the implied warranty of
48  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
49  * GNU General Public License for more details.
50  *
51  * You should have received a copy of the GNU General Public License
52  * along with this program. If not, see <http://www.gnu.org/licenses/>.
53  */
54 abstract class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
55         /**
56          * Self-referencing instance
57          */
58         private static $selfInstance = NULL;
59
60         /**
61          * Debug instance
62          */
63         private static $debugInstance = NULL;
64
65         /**
66          * Stub methods
67          */
68         private static $stubMethods = [
69                 'partialStub' => true,
70                 '__call' => true,
71                 '__callStatic' => true,
72         ];
73
74         /**
75          * The real class name
76          */
77         private $realClass = __CLASS__;
78
79         /**
80          * Call-back instance
81          */
82         private $callbackInstance = NULL;
83
84         /**
85          * Generic array
86          */
87         private $genericArray = [];
88
89         /***********************
90          * Exception codes.... *
91          ***********************/
92
93         // @todo Try to clean these constants up
94         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
95         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
96         const EXCEPTION_MISSING_METHOD               = 0x004;
97         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
98         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
99         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
100         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
101         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
102         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
103         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
104         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
105         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
106         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
107         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
108         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
109         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
110         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
111         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
112         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
113         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
114         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
115         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
116         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
117         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
118         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
119         const EXCEPTION_INVALID_RESOURCE             = 0x01b;
120         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
121         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
122         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
123         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
124         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
125         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
126         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
127         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
128         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
129         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
130         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
131         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
132         const EXCEPTION_INVALID_STRING               = 0x029;
133         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
134         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
135         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
136         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
137         const EXCEPTION_FACTORY_REQUIRE_PARAMETER    = 0x02e;
138         const EXCEPTION_MISSING_ELEMENT              = 0x02f;
139         const EXCEPTION_HEADERS_ALREADY_SENT         = 0x030;
140         const EXCEPTION_DEFAULT_CONTROLLER_GONE      = 0x031;
141         const EXCEPTION_REQUIRED_INTERFACE_MISSING   = 0x033;
142         const EXCEPTION_FATAL_ERROR                  = 0x034;
143         const EXCEPTION_FILE_NOT_FOUND               = 0x035;
144         const EXCEPTION_ASSERTION_FAILED             = 0x036;
145         const EXCEPTION_FILE_NOT_REACHABLE           = 0x037;
146         const EXCEPTION_FILE_CANNOT_BE_READ          = 0x038;
147         const EXCEPTION_FILE_CANNOT_BE_WRITTEN       = 0x039;
148         const EXCEPTION_PATH_CANNOT_BE_WRITTEN       = 0x03a;
149         const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x03b;
150         const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x03c;
151         const EXCEPTION_INVALID_SOCKET               = 0x03d;
152         const EXCEPTION_SELF_INSTANCE                = 0x03e;
153
154         /**
155          * Startup time in miliseconds
156          */
157         private static $startupTime = 0;
158
159         /**
160          * Protected super constructor
161          *
162          * @param       $className      Name of the class
163          * @return      void
164          */
165         protected function __construct (string $className) {
166                 // Set real class
167                 $this->setRealClass($className);
168
169                 // Is the startup time set? (0 cannot be true anymore)
170                 if (self::$startupTime == 0) {
171                         // Then set it
172                         self::$startupTime = microtime(true);
173                 }
174         }
175
176         /**
177          * Destructor for all classes. You should not call this method on your own.
178          *
179          * @return      void
180          */
181         public function __destruct () {
182                 // Is this object already destroyed?
183                 if ($this->__toString() != 'DestructedObject') {
184                         // Destroy all informations about this class but keep some text about it alive
185                         $this->setRealClass('DestructedObject');
186                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
187                         // Already destructed object
188                         self::createDebugInstance(__CLASS__, __LINE__)->warningMessage(sprintf('The object <span class="object_name">%s</span> is already destroyed.',
189                                 $this->__toString()
190                         ));
191                 } else {
192                         // Do not call this twice
193                         trigger_error(__METHOD__ . ': Called twice.');
194                         exit(255);
195                 }
196         }
197
198         /**
199          * The __call() method where all non-implemented methods end up
200          *
201          * @param       $methodName             Name of the missing method
202          * @args        $args                   Arguments passed to the method
203          * @return      void
204          */
205         public final function __call (string $methodName, array $args = NULL) {
206                 // Set self-instance
207                 self::$selfInstance = $this;
208
209                 // Call static method
210                 self::__callStatic($methodName, $args);
211
212                 // Clear self-instance
213                 self::$selfInstance = NULL;
214         }
215
216         /**
217          * The __callStatic() method where all non-implemented static methods end up
218          *
219          * @param       $methodName             Name of the missing method
220          * @param       $args                   Arguments passed to the method
221          * @return      void
222          * @throws      InvalidArgumentException If self::$selfInstance is not a framework's own object
223          */
224         public static final function __callStatic (string $methodName, array $args = NULL) {
225                 // Init argument string and class name
226                 //* PRINT-DEBUG: */ printf('[%s:%d]: methodName=%s,args[]=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $methodName, gettype($args));
227                 $argsString = '';
228                 $className = 'unknown';
229
230                 // Is self-instance set?
231                 if (self::$selfInstance instanceof FrameworkInterface) {
232                         // Framework's own instance
233                         $className = self::$selfInstance->__toString();
234                 } elseif (!is_null(self::$selfInstance)) {
235                         // Invalid argument!
236                         throw new InvalidArgumentException(sprintf('self::instance[%s] is not expected.', gettype(self::$selfInstance)), self::EXCEPTION_SELF_INSTANCE);
237                 }
238
239                 // Is it NULL, empty or an array?
240                 if (is_null($args)) {
241                         // No arguments
242                         $argsString = 'NULL';
243                 } elseif (is_array($args)) {
244                         // Start braces
245                         $argsString = '(';
246
247                         // Some arguments are there
248                         foreach ($args as $arg) {
249                                 // Add data about the argument
250                                 $argsString .= gettype($arg) . ':';
251
252                                 if (is_null($arg)) {
253                                         // Found a NULL argument
254                                         $argsString .= 'NULL';
255                                 } elseif (is_string($arg)) {
256                                         // Add length for strings
257                                         $argsString .= strlen($arg);
258                                 } elseif ((is_int($arg)) || (is_float($arg))) {
259                                         // ... integer/float
260                                         $argsString .= $arg;
261                                 } elseif (is_array($arg)) {
262                                         // .. or size if array
263                                         $argsString .= count($arg);
264                                 } elseif (is_object($arg)) {
265                                         // Get reflection
266                                         $reflection = new ReflectionClass($arg);
267
268                                         // Is an other object, maybe no __toString() available
269                                         $argsString .= $reflection->getName();
270                                 } elseif ($arg === true) {
271                                         // ... is boolean 'true'
272                                         $argsString .= 'true';
273                                 } elseif ($arg === false) {
274                                         // ... is boolean 'false'
275                                         $argsString .= 'false';
276                                 }
277
278                                 // Comma for next one
279                                 $argsString .= ', ';
280                         }
281
282                         // Last comma found?
283                         if (substr($argsString, -2, 1) == ',') {
284                                 // Remove last comma
285                                 $argsString = substr($argsString, 0, -2);
286                         }
287
288                         // Close braces
289                         $argsString .= ')';
290                 }
291
292                 // Output stub message
293                 // @TODO __CLASS__ does always return BaseFrameworkSystem but not the extending (=child) class
294                 self::createDebugInstance(__CLASS__, __LINE__)->warningMessage(sprintf('[%s::%s]: Stub! Args: %s',
295                         $className,
296                         $methodName,
297                         $argsString
298                 ));
299
300                 // Return nothing
301                 return NULL;
302         }
303
304         /**
305          * Getter for $realClass
306          *
307          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
308          */
309         public function __toString () {
310                 return $this->realClass;
311         }
312
313         /**
314          * Magic method to catch setting of missing but set class fields/attributes
315          *
316          * @param       $name   Name of the field/attribute
317          * @param       $value  Value to store
318          * @return      void
319          */
320         public final function __set (string $name, $value) {
321                 $this->debugBackTrace(sprintf('Tried to set a missing field. name=%s, value[%s]=%s',
322                         $name,
323                         gettype($value),
324                         print_r($value, true)
325                 ));
326         }
327
328         /**
329          * Magic method to catch getting of missing fields/attributes
330          *
331          * @param       $name   Name of the field/attribute
332          * @return      void
333          */
334         public final function __get (string $name) {
335                 $this->debugBackTrace(sprintf('Tried to get a missing field. name=%s',
336                         $name
337                 ));
338         }
339
340         /**
341          * Magic method to catch unsetting of missing fields/attributes
342          *
343          * @param       $name   Name of the field/attribute
344          * @return      void
345          */
346         public final function __unset (string $name) {
347                 $this->debugBackTrace(sprintf('Tried to unset a missing field. name=%s',
348                         $name
349                 ));
350         }
351
352         /**
353          * Magic method to catch object serialization
354          *
355          * @return      $unsupported    Unsupported method
356          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
357          */
358         public final function __sleep () {
359                 throw new UnsupportedOperationException([$this, __FUNCTION__], FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION);
360         }
361
362         /**
363          * Magic method to catch object deserialization
364          *
365          * @return      $unsupported    Unsupported method
366          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
367          */
368         public final function __wakeup () {
369                 throw new UnsupportedOperationException([$this, __FUNCTION__], FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION);
370         }
371
372         /**
373          * Magic method to catch calls when an object instance is called
374          *
375          * @return      $unsupported    Unsupported method
376          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
377          */
378         public final function __invoke () {
379                 throw new UnsupportedOperationException([$this, __FUNCTION__], FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION);
380         }
381
382         /**
383          * Setter for the real class name
384          *
385          * @param       $realClass      Class name (string)
386          * @return      void
387          */
388         public final function setRealClass (string $realClass) {
389                 // Set real class
390                 $this->realClass = $realClass;
391         }
392
393         /**
394          * Setter for debug instance
395          *
396          * @param       $debugInstance  The instance for debug output class
397          * @return      void
398          */
399         public final function setDebugInstance (DebugMiddleware $debugInstance) {
400                 self::$debugInstance = $debugInstance;
401         }
402
403         /**
404          * Getter for debug instance
405          *
406          * @return      $debugInstance  Instance to class DebugConsoleOutput or DebugWebOutput
407          */
408         public final function getDebugInstance () {
409                 return self::$debugInstance;
410         }
411
412         /**
413          * Setter for web output instance
414          *
415          * @param       $webInstance    The instance for web output class
416          * @return      void
417          */
418         public final function setWebOutputInstance (OutputStreamer $webInstance) {
419                 ObjectRegistry::getRegistry('generic')->addInstance('web_output', $webInstance);
420         }
421
422         /**
423          * Getter for web output instance
424          *
425          * @return      $webOutputInstance - Instance to class WebOutput
426          */
427         public final function getWebOutputInstance () {
428                 return ObjectRegistry::getRegistry('generic')->getInstance('web_output');
429         }
430
431         /**
432          * Setter for call-back instance
433          *
434          * @param       $callbackInstance       An instance of a FrameworkInterface class
435          * @return      void
436          */
437         public final function setCallbackInstance (FrameworkInterface $callbackInstance) {
438                 $this->callbackInstance = $callbackInstance;
439         }
440
441         /**
442          * Getter for call-back instance
443          *
444          * @return      $callbackInstance       An instance of a FrameworkInterface class
445          */
446         protected final function getCallbackInstance () {
447                 return $this->callbackInstance;
448         }
449
450         /**
451          * Checks whether an object equals this object. You should overwrite this
452          * method to implement own equality checks
453          *
454          * @param       $objectInstance         An instance of a FrameworkInterface object
455          * @return      $equals                         Whether both objects equals
456          */
457         public function equals (FrameworkInterface $objectInstance) {
458                 // Now test it
459                 $equals = ((
460                         $this->__toString() == $objectInstance->__toString()
461                 ) && (
462                         $this->hashCode() == $objectInstance->hashCode()
463                 ));
464
465                 // Return the result
466                 return $equals;
467         }
468
469         /**
470          * Generates a generic hash code of this class. You should really overwrite
471          * this method with your own hash code generator code. But keep KISS in mind.
472          *
473          * @return      $hashCode       A generic hash code respresenting this whole class
474          */
475         public function hashCode () {
476                 // Simple hash code
477                 return crc32($this->__toString());
478         }
479
480         /**
481          * Appends a trailing slash to a string
482          *
483          * @param       $str    A string (maybe) without trailing slash
484          * @return      $str    A string with an auto-appended trailing slash
485          * @throws      InvalidArgumentException        If a paramter has an invalid value
486          */
487         public final function addMissingTrailingSlash (string $str) {
488                 // Check parameter
489                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: str=%s - CALLED!', $str));
490                 if (empty($str)) {
491                         // Throw IAE
492                         throw new InvalidArgumentException('Parameter "str" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
493                 }
494
495                 // Is there a trailing slash?
496                 if (substr($str, -1, 1) != '/') {
497                         $str .= '/';
498                 }
499
500                 // Return string with trailing slash
501                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: str=%s - EXIT!', $str));
502                 return $str;
503         }
504
505         /**
506          * Debugs this instance by putting out it's full content
507          *
508          * @param       $message        Optional message to show in debug output
509          * @return      void
510          * @throws      InvalidArgumentException        If a paramter has an invalid value
511          */
512         public final function debugInstance (string $message = '') {
513                 // Check parameter
514                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: message=%s - CALLED!', $message));
515                 if (empty($message)) {
516                         // Throw IAE
517                         throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
518                 }
519
520                 // Restore the error handler to avoid trouble with missing array elements or undeclared variables
521                 restore_error_handler();
522
523                 // Init content
524                 $content = '';
525
526                 // Is a message set?
527                 if (!empty($message)) {
528                         // Construct message
529                         $content = sprintf('<div class="debug_message">
530         Message: %s
531 </div>' . PHP_EOL, $message);
532                 }
533
534                 // Generate the output
535                 $content .= sprintf('<pre>%s</pre>',
536                         trim(
537                                 htmlentities(
538                                         print_r($this, true)
539                                 )
540                         )
541                 );
542
543                 // Output it
544                 ApplicationEntryPoint::exitApplication(sprintf('<div class="debug_header">
545         %s debug output:
546 </div>
547 <div class="debug_content">
548         %s
549 </div>
550 Loaded includes:
551 <div class="debug_include_list">
552         %s
553 </div>',
554                         $this->__toString(),
555                         $content,
556                         ClassLoader::getSelfInstance()->getPrintableIncludeList()
557                 ));
558         }
559
560         /**
561          * Outputs a debug backtrace and stops further script execution
562          *
563          * @param       $message        An optional message to output
564          * @param       $doExit         Whether exit the program (true is default)
565          * @return      void
566          * @throws      InvalidArgumentException        If a paramter has an invalid value
567          */
568         public function debugBackTrace (string $message = '', bool $doExit = true) {
569                 // Check parameter
570                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: message=%s,doExit=%d - CALLED!', $message, intval($doExit)));
571                 if (empty($message)) {
572                         // Throw IAE
573                         throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
574                 }
575
576                 // Sorry, there is no other way getting this nice backtrace
577                 if (!empty($message)) {
578                         // Output message
579                         printf('Message: %s<br />' . PHP_EOL, $message);
580                 }
581
582                 print('<pre>');
583                 debug_print_backtrace();
584                 print('</pre>');
585
586                 // Exit program?
587                 if ($doExit === true) {
588                         // Yes, with error code
589                         exit(255);
590                 }
591         }
592
593         /**
594          * Creates an instance of a debugger instance
595          *
596          * @param       $className              Name of the class (currently unsupported)
597          * @param       $lineNumber             Line number where the call was made
598          * @return      $debugInstance  An instance of a debugger class
599          * @throws      InvalidArgumentException        If a parameter has an invalid value
600          * @deprecated  Not fully, as the new Logger facilities are not finished yet.
601          */
602         public final static function createDebugInstance (string $className, int $lineNumber = NULL) {
603                 // Validate parameter
604                 //* NOISY-DEBUG: */ printf('[%s:%d]: className=%s,lineNumber[%s]=%d - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $className, gettype($lineNumber), $lineNumber);
605                 if (empty($className)) {
606                         // Throw IAE
607                         throw new InvalidArgumentException('Parameter "className" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
608                 }
609
610                 // Is the debug instance set?
611                 //* NOISY-DEBUG: */ printf('[%s:%d]: self::debugInstance[]=%s' . PHP_EOL, __METHOD__, __LINE__, gettype(self::$debugInstance));
612                 if (is_null(self::$debugInstance)) {
613                         // Init debug instance
614                         self::$debugInstance = NULL;
615
616                         // Try it
617                         try {
618                                 // Get a debugger instance
619                                 //* NOISY-DEBUG: */ printf('[%s:%d]: className=%s' . PHP_EOL, __METHOD__, __LINE__, $className);
620                                 self::$debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_class'), $className);
621                         } catch (NullPointerException $e) {
622                                 // Didn't work, no instance there
623                                 exit(sprintf('[%s:%d]: Cannot create debugInstance! Exception=%s,message=%s,className=%s,lineNumber=%d' . PHP_EOL, __METHOD__, __LINE__, $e->__toString(), $e->getMessage(), $className, $lineNumber));
624                         }
625                 }
626
627                 // Return it
628                 //* NOISY-DEBUG: */ printf('[%s:%d]: self::debugInstance=%s - EXIT!' . PHP_EOL, __METHOD__, __LINE__, self::$debugInstance->__toString());
629                 return self::$debugInstance;
630         }
631
632         /**
633          * Simple output of a message with line-break
634          *
635          * @param       $message        Message to output
636          * @return      void
637          * @throws      InvalidArgumentException        If a paramter has an invalid value
638          */
639         public function outputLine (string $message) {
640                 // Check parameter
641                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: message=%s - CALLED!', $message));
642                 if (empty($message)) {
643                         // Throw IAE
644                         throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
645                 }
646
647                 // Simply output it
648                 print($message . PHP_EOL);
649         }
650
651         /**
652          * Marks up the code by adding e.g. line numbers
653          *
654          * @param       $phpCode                Unmarked PHP code
655          * @return      $markedCode             Marked PHP code
656          * @throws      InvalidArgumentException        If a paramter has an invalid value
657          */
658         public function markupCode (string $phpCode) {
659                 // Check parameter
660                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: phpCode=%s - CALLED!', $phpCode));
661                 if (empty($phpCode)) {
662                         // Throw IAE
663                         throw new InvalidArgumentException('Parameter "phpCode" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
664                 }
665
666                 // Init marked code
667                 $markedCode = '';
668
669                 // Get last error
670                 $errorArray = error_get_last();
671
672                 // Init the code with error message
673                 if (is_array($errorArray)) {
674                         // Get error infos
675                         $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>',
676                                 basename($errorArray['file']),
677                                 $errorArray['line'],
678                                 $errorArray['message'],
679                                 $errorArray['type']
680                         );
681                 }
682
683                 // Add line number to the code
684                 foreach (explode(chr(10), $phpCode) as $lineNo => $code) {
685                         // Add line numbers
686                         $markedCode .= sprintf('<span id="code_line">%s</span>: %s' . PHP_EOL,
687                                 ($lineNo + 1),
688                                 htmlentities($code, ENT_QUOTES)
689                         );
690                 }
691
692                 // Return the code
693                 return $markedCode;
694         }
695
696         /**
697          * "Getter" for databse entry
698          *
699          * @return      $entry  An array with database entries
700          * @throws      NullPointerException    If the database result is not found
701          * @throws      InvalidDatabaseResultException  If the database result is invalid
702          * @deprecated  Monolithic method, should be moved to proper classes
703          */
704         protected final function getDatabaseEntry () {
705                 // This method is deprecated
706                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: CALLED!');
707                 $this->deprecationWarning('Monolithic method, should be moved to proper classes');
708
709                 // Is there an instance?
710                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->resultInstance[]=%s', gettype($this->getResultInstance())));
711                 if (!$this->getResultInstance() instanceof SearchableResult) {
712                         // Throw an exception here
713                         throw new NullPointerException($this, FrameworkInterface::EXCEPTION_IS_NULL_POINTER);
714                 }
715
716                 // Rewind it
717                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: Invoking this->resultInstance->rewind() ...');
718                 $this->getResultInstance()->rewind();
719
720                 // Do we have an entry?
721                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->resultInstance->isValid()=%d', intval($this->getResultInstance()->isValid())));
722                 if ($this->getResultInstance()->valid() === false) {
723                         // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available
724                         throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
725                 }
726
727                 // Get next entry
728                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: Invoking this->resultInstance->next() ...');
729                 $this->getResultInstance()->next();
730
731                 // Fetch it
732                 $entry = $this->getResultInstance()->current();
733
734                 // And return it
735                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: entry[]=%s - EXIT!', gettype($entry)));
736                 return $entry;
737         }
738
739         /**
740          * Getter for field name
741          *
742          * @param       $fieldName              Field name which we shall get
743          * @return      $fieldValue             Field value from the user
744          * @throws      NullPointerException    If the result instance is null
745          * @throws      InvalidArgumentException        If a parameter is not valid
746          * @deprecated  Monolithic method, should be moved to proper classes
747          */
748         public final function getField (string $fieldName) {
749                 // Check parameter
750                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName=%s - CALLED!', $fieldName));
751                 if (empty($fieldName)) {
752                         // Throw IAE
753                         throw new InvalidArgumentException('Parameter "fieldName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
754                 }
755
756                 // This method is deprecated
757                 $this->deprecationWarning('Monolithic method, should be moved to proper classes');
758
759                 // Default field value
760                 $fieldValue = NULL;
761
762                 // Get result instance
763                 $resultInstance = $this->getResultInstance();
764
765                 // Is this instance null?
766                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: resultInstance[]=%s', gettype($resultInstance)));
767                 if (is_null($resultInstance)) {
768                         // Then the user instance is no longer valid (expired cookies?)
769                         throw new NullPointerException($this, FrameworkInterface::EXCEPTION_IS_NULL_POINTER);
770                 }
771
772                 // Get current array
773                 $fieldArray = $resultInstance->current();
774
775                 // Convert dashes to underscore
776                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldArray()=%d', count($fieldArray)));
777                 $fieldName2 = StringUtils::convertDashesToUnderscores($fieldName);
778
779                 // Does the field exist?
780                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName2=%s', $fieldName2));
781                 if ($this->isFieldSet($fieldName)) {
782                         // Get it
783                         $fieldValue = $fieldArray[$fieldName2];
784                 } elseif (FrameworkBootstrap::getConfigurationInstance()->isEnabled('developer_mode')) {
785                         // Missing field entry, may require debugging
786                         self::createDebugInstance(__CLASS__, __LINE__)->warningMessage('BASE-FRAMEWORK-SYSTEM: fieldArray<pre>=' . print_r($fieldArray, true) . '</pre>,fieldName=' . $fieldName . ' not found!');
787                 } else {
788                         // Missing field entry, may require debugging
789                         self::createDebugInstance(__CLASS__, __LINE__)->warningMessage('BASE-FRAMEWORK-SYSTEM: fieldName=' . $fieldName . ' not found!');
790                 }
791
792                 // Return it
793                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldValue[]=%s - EXIT!', gettype($fieldValue)));
794                 return $fieldValue;
795         }
796
797         /**
798          * Checks if given field is set
799          *
800          * @param       $fieldName      Field name to check
801          * @return      $isSet          Whether the given field name is set
802          * @throws      NullPointerException    If the result instance is null
803          * @throws      InvalidArgumentException        If a parameter is not valid
804          */
805         public function isFieldSet (string $fieldName) {
806                 // Check parameter
807                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName=%s - CALLED!', $fieldName));
808                 if (empty($fieldName)) {
809                         // Throw IAE
810                         throw new InvalidArgumentException('Parameter "fieldName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
811                 }
812
813                 // Get result instance
814                 $resultInstance = $this->getResultInstance();
815
816                 // Is this instance null?
817                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: resultInstance[]=%s', gettype($resultInstance)));
818                 if (is_null($resultInstance)) {
819                         // Then the user instance is no longer valid (expired cookies?)
820                         throw new NullPointerException($this, FrameworkInterface::EXCEPTION_IS_NULL_POINTER);
821                 }
822
823                 // Get current array
824                 $fieldArray = $resultInstance->current();
825
826                 // Convert dashes to underscore
827                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldArray()=%d,fieldName=%s - BEFORE!', count($fieldArray), $fieldName));
828                 $fieldName = StringUtils::convertDashesToUnderscores($fieldName);
829
830                 // Determine it
831                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fieldName=%s - AFTER!', $fieldName));
832                 $isset = isset($fieldArray[$fieldName]);
833
834                 // Return result
835                 /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isset=%d - EXIT!', intval($isset)));
836                 return $isset;
837         }
838
839         /**
840          * Outputs a deprecation warning to the developer.
841          *
842          * @param       $message        The message we shall output to the developer
843          * @return      void
844          * @throws      InvalidArgumentException        If a paramter has an invalid value
845          * @todo        Write a logging mechanism for productive mode
846          */
847         public function deprecationWarning (string $message) {
848                 // Check parameter
849                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: message=%s - CALLED!', $message));
850                 if (empty($message)) {
851                         // Throw IAE
852                         throw new InvalidArgumentException('Parameter "message" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
853                 }
854
855                 // Is developer mode active?
856                 if (FrameworkBootstrap::getConfigurationInstance()->isEnabled('developer_mode')) {
857                         // Debug instance is there?
858                         if (!is_null($this->getDebugInstance())) {
859                                 // Output stub message
860                                 self::createDebugInstance(__CLASS__, __LINE__)->warningMessage($message);
861                         } else {
862                                 // Trigger an error
863                                 trigger_error($message . "<br />\n");
864                                 exit(255);
865                         }
866                 } else {
867                         // @TODO Finish this part!
868                         DebugMiddleware::getSelfInstance()->partialStub('Developer mode inactive. Message:' . $message);
869                 }
870
871                 // Trace mesage
872                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
873         }
874
875         /**
876          * Checks whether the given PHP extension is loaded
877          *
878          * @param       $phpExtension   The PHP extension we shall check
879          * @return      $isLoaded       Whether the PHP extension is loaded
880          * @throws      InvalidArgumentException        If a parameter is not valid
881          */
882         public final function isPhpExtensionLoaded (string $phpExtension) {
883                 // Check parameter
884                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: phpExtension=%s - CALLED!', $phpExtension));
885                 if (empty($phpExtension)) {
886                         // Throw IAE
887                         throw new InvalidArgumentException('Parameter "phpExtension" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
888                 }
889
890                 // Is it loaded?
891                 $isLoaded = in_array($phpExtension, get_loaded_extensions());
892
893                 // Return result
894                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isLoaded=%d - EXIT!', intval($isLoaded)));
895                 return $isLoaded;
896         }
897
898         /**
899          * "Getter" as a time() replacement but with milliseconds. You should use this
900          * method instead of the encapsulated getimeofday() function.
901          *
902          * @return      $milliTime      Timestamp with milliseconds
903          */
904         public function getMilliTime () {
905                 // Get the time of day as float
906                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: CALLED!');
907                 $milliTime = gettimeofday(true);
908
909                 // Return it
910                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: milliTime=%s - EXIT!', $milliTime));
911                 return $milliTime;
912         }
913
914         /**
915          * Idles (sleeps) for given milliseconds
916          *
917          * @return      $hasSlept       Whether it goes fine
918          * @throws      InvalidArgumentException        If a parameter is not valid
919          */
920         public function idle (int $milliSeconds) {
921                 // Check parameter
922                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: milliSeconds=%s - CALLED!', $milliSeconds));
923                 if ($milliSeconds < 1) {
924                         // Throw IAE
925                         throw new InvalidArgumentException(sprintf('milliSeconds=%d are not a reasonable value to idle', $milliSeconds));
926                 }
927
928                 // Sleep is fine by default
929                 $hasSlept = true;
930
931                 // Idle so long with found function
932                 if (function_exists('time_sleep_until')) {
933                         // Get current time and add idle time
934                         $sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
935
936                         // New PHP 5.1.0 function found, ignore errors
937                         $hasSlept = @time_sleep_until($sleepUntil);
938                 } else {
939                         /*
940                          * My Sun station doesn't have that function even with latest PHP
941                          * package. :(
942                          */
943                         usleep($milliSeconds * 1000);
944                 }
945
946                 // Return result
947                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: hasSlept=%d - EXIT!', intval($hasSlept)));
948                 return $hasSlept;
949         }
950
951         /**
952          * Checks whether the given encoded data was encoded with Base64
953          *
954          * @param       $encodedData    Encoded data we shall check
955          * @return      $isBase64               Whether the encoded data is Base64
956          * @throws      InvalidArgumentException        If a parameter is not valid
957          */
958         protected function isBase64Encoded (string $encodedData) {
959                 // Check parameter
960                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: encodedData=%s - CALLED!', $encodedData));
961                 if (empty($encodedData)) {
962                         // Throw IAE
963                         throw new InvalidArgumentException('Parameter "encodedData" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
964                 }
965
966                 // Determine it
967                 $isBase64 = (@base64_decode($encodedData, true) !== false);
968
969                 // Return it
970                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isBase64=%d - EXIT!', intval($isBase64)));
971                 return $isBase64;
972         }
973
974         /**
975          * Getter for startup time in miliseconds
976          *
977          * @return      $startupTime    Startup time in miliseconds
978          */
979         protected function getStartupTime () {
980                 return self::$startupTime;
981         }
982
983         /**
984          * "Getter" for a printable currently execution time in nice braces
985          *
986          * @return      $executionTime  Current execution time in nice braces
987          */
988         protected function getPrintableExecutionTime () {
989                 // Calculate execution time and pack it in nice braces
990                 $executionTime = sprintf('[ %01.5f ] ', (microtime(true) - $this->getStartupTime()));
991
992                 // And return it
993                 return $executionTime;
994         }
995
996         /**
997          * Determines if an element is set in the generic array
998          *
999          * @param       $keyGroup       Main group for the key
1000          * @param       $subGroup       Sub group for the key
1001          * @param       $key            Key to check
1002          * @param       $element        Element to check
1003          * @return      $isset          Whether the given key is set
1004          * @throws      InvalidArgumentException        If a parameter is not valid
1005          */
1006         protected final function isGenericArrayElementSet (string $keyGroup, string $subGroup, string $key, string $element) {
1007                 // Check parameter
1008                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s - CALLED!', $keyGroup, $subGroup, $key, $element));
1009                 if (empty($keyGroup)) {
1010                         // Throw IAE
1011                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1012                 } elseif (empty($subGroup)) {
1013                         // Throw IAE
1014                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1015                 } elseif (empty($key)) {
1016                         // Throw IAE
1017                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1018                 } elseif ($element === '') {
1019                         // Throw IAE
1020                         throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1021                 }
1022
1023                 // Is it there?
1024                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
1025
1026                 // Return it
1027                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isset=%d - EXIT!', intval($isset)));
1028                 return $isset;
1029         }
1030         /**
1031          * Determines if a key is set in the generic array
1032          *
1033          * @param       $keyGroup       Main group for the key
1034          * @param       $subGroup       Sub group for the key
1035          * @param       $key            Key to check
1036          * @return      $isset          Whether the given key is set
1037          * @throws      InvalidArgumentException        If a parameter is not valid
1038          */
1039         protected final function isGenericArrayKeySet (string $keyGroup, string $subGroup, string $key) {
1040                 // Check parameter
1041                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1042                 if (empty($keyGroup)) {
1043                         // Throw IAE
1044                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1045                 } elseif (empty($subGroup)) {
1046                         // Throw IAE
1047                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1048                 } elseif (empty($key)) {
1049                         // Throw IAE
1050                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1051                 }
1052
1053                 // Is it there?
1054                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key]);
1055
1056                 // Return it
1057                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isset=%d - EXIT!', intval($isset)));
1058                 return $isset;
1059         }
1060
1061         /**
1062          * Determines if a group is set in the generic array
1063          *
1064          * @param       $keyGroup       Main group
1065          * @param       $subGroup       Sub group
1066          * @return      $isset          Whether the given group is set
1067          * @throws      InvalidArgumentException        If a parameter is not valid
1068          */
1069         protected final function isGenericArrayGroupSet (string $keyGroup, string $subGroup) {
1070                 // Check parameter
1071                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s - CALLED!', $keyGroup, $subGroup));
1072                 if (empty($keyGroup)) {
1073                         // Throw IAE
1074                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1075                 } elseif (empty($subGroup)) {
1076                         // Throw IAE
1077                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1078                 }
1079
1080                 // Is it there?
1081                 $isset = isset($this->genericArray[$keyGroup][$subGroup]);
1082
1083                 // Return it
1084                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isset=%d - EXIT!', intval($isset)));
1085                 return $isset;
1086         }
1087
1088         /**
1089          * Getter for sub key group
1090          *
1091          * @param       $keyGroup       Main key group
1092          * @param       $subGroup       Sub key group
1093          * @return      $array          An array with all array elements
1094          * @throws      InvalidArgumentException        If a parameter is not valid
1095          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1096          */
1097         protected final function getGenericSubArray (string $keyGroup, string $subGroup) {
1098                 // Check parameter
1099                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s - CALLED!', $keyGroup, $subGroup));
1100                 if (empty($keyGroup)) {
1101                         // Throw IAE
1102                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1103                 } elseif (empty($subGroup)) {
1104                         // Throw IAE
1105                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1106                 } elseif (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
1107                         // No, then abort here
1108                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s not found.', $keyGroup, $subGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1109                 }
1110
1111                 // Return it
1112                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->genericArray[%s][%s][]=%s - EXIT!', $keyGroup, $subGroup, gettype($this->genericArray[$keyGroup][$subGroup])));
1113                 return $this->genericArray[$keyGroup][$subGroup];
1114         }
1115
1116         /**
1117          * Unsets a given key in generic array
1118          *
1119          * @param       $keyGroup       Main group for the key
1120          * @param       $subGroup       Sub group for the key
1121          * @param       $key            Key to unset
1122          * @return      void
1123          * @throws      InvalidArgumentException        If a parameter is not valid
1124          */
1125         protected final function unsetGenericArrayKey (string $keyGroup, string $subGroup, string $key) {
1126                 // Check parameter
1127                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1128                 if (empty($keyGroup)) {
1129                         // Throw IAE
1130                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1131                 } elseif (empty($subGroup)) {
1132                         // Throw IAE
1133                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1134                 } elseif (empty($key)) {
1135                         // Throw IAE
1136                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1137                 }
1138
1139                 // Remove it
1140                 unset($this->genericArray[$keyGroup][$subGroup][$key]);
1141
1142                 // Trace mesage
1143                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1144         }
1145
1146         /**
1147          * Unsets a given element in generic array
1148          *
1149          * @param       $keyGroup       Main group for the key
1150          * @param       $subGroup       Sub group for the key
1151          * @param       $key            Key to unset
1152          * @param       $element        Element to unset
1153          * @return      void
1154          * @throws      InvalidArgumentException        If a parameter is not valid
1155          */
1156         protected final function unsetGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element) {
1157                 // Check parameter
1158                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s - CALLED!', $keyGroup, $subGroup, $key, $element));
1159                 if (empty($keyGroup)) {
1160                         // Throw IAE
1161                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1162                 } elseif (empty($subGroup)) {
1163                         // Throw IAE
1164                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1165                 } elseif (empty($key)) {
1166                         // Throw IAE
1167                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1168                 } elseif ($element === '') {
1169                         // Throw IAE
1170                         throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1171                 }
1172
1173                 // Remove it
1174                 unset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
1175
1176                 // Trace mesage
1177                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1178         }
1179
1180         /**
1181          * Append a string to a given generic array key
1182          *
1183          * @param       $keyGroup       Main group for the key
1184          * @param       $subGroup       Sub group for the key
1185          * @param       $key            Key to unset
1186          * @param       $value          Value to add/append
1187          * @return      void
1188          * @throws      InvalidArgumentException        If a parameter is not valid
1189          */
1190         protected final function appendStringToGenericArrayKey (string $keyGroup, string $subGroup, string $key, string $value, string $appendGlue = '') {
1191                 // Check parameter
1192                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,value=%s,appendGlue=%s - CALLED!', $keyGroup, $subGroup, $key, $value, $appendGlue));
1193                 if (empty($keyGroup)) {
1194                         // Throw IAE
1195                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1196                 } elseif (empty($subGroup)) {
1197                         // Throw IAE
1198                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1199                 } elseif (empty($key)) {
1200                         // Throw IAE
1201                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1202                 }
1203
1204                 // Is it already there?
1205                 if ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1206                         // Append it
1207                         $this->genericArray[$keyGroup][$subGroup][$key] .= $appendGlue . $value;
1208                 } else {
1209                         // Add it
1210                         $this->genericArray[$keyGroup][$subGroup][$key] = $value;
1211                 }
1212
1213                 // Trace mesage
1214                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1215         }
1216
1217         /**
1218          * Append a string to a given generic array element
1219          *
1220          * @param       $keyGroup       Main group for the key
1221          * @param       $subGroup       Sub group for the key
1222          * @param       $key            Key to unset
1223          * @param       $element        Element to check
1224          * @param       $value          Value to add/append
1225          * @return      void
1226          * @throws      InvalidArgumentException        If a parameter is not valid
1227          */
1228         protected final function appendStringToGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element, string $value, string $appendGlue = '') {
1229                 // Check parameter
1230                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s,value=%s,appendGlue=%s - CALLED!', $keyGroup, $subGroup, $key, $element, $value, $appendGlue));
1231                 if (empty($keyGroup)) {
1232                         // Throw IAE
1233                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1234                 } elseif (empty($subGroup)) {
1235                         // Throw IAE
1236                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1237                 } elseif (empty($key)) {
1238                         // Throw IAE
1239                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1240                 } elseif ($element === '') {
1241                         // Throw IAE
1242                         throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1243                 }
1244
1245                 // Is it already there?
1246                 if ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
1247                         // Append it
1248                         $this->genericArray[$keyGroup][$subGroup][$key][$element] .= $appendGlue . $value;
1249                 } else {
1250                         // Add it
1251                         $this->setGenericArrayElement($keyGroup, $subGroup, $key, $element, $value);
1252                 }
1253
1254                 // Trace mesage
1255                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1256         }
1257
1258         /**
1259          * Initializes given generic array group
1260          *
1261          * @param       $keyGroup       Main group for the key
1262          * @param       $subGroup       Sub group for the key
1263          * @param       $key            Key to use
1264          * @param       $forceInit      Optionally force initialization
1265          * @return      void
1266          * @throws      InvalidArgumentException        If a parameter is not valid
1267          * @throws      BadMethodCallException  If key/sub group has already been initialized
1268          */
1269         protected final function initGenericArrayGroup (string $keyGroup, string $subGroup, bool $forceInit = false) {
1270                 // Check parameter
1271                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,forceInit=%d - CALLED!', $keyGroup, $subGroup, intval($forceInit)));
1272                 if (empty($keyGroup)) {
1273                         // Throw IAE
1274                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1275                 } elseif (empty($subGroup)) {
1276                         // Throw IAE
1277                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1278                 } elseif (($forceInit === false) && ($this->isGenericArrayGroupSet($keyGroup, $subGroup))) {
1279                         // Already initialized
1280                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s already initialized.', $keyGroup, $subGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1281                 }
1282
1283                 // Initialize it
1284                 $this->genericArray[$keyGroup][$subGroup] = [];
1285
1286                 // Trace mesage
1287                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1288         }
1289
1290         /**
1291          * Initializes given generic array key
1292          *
1293          * @param       $keyGroup       Main group for the key
1294          * @param       $subGroup       Sub group for the key
1295          * @param       $key            Key to use
1296          * @param       $forceInit      Optionally force initialization
1297          * @return      void
1298          * @throws      InvalidArgumentException        If a parameter is not valid
1299          * @throws      BadMethodCallException  If key/sub group has already been initialized
1300          */
1301         protected final function initGenericArrayKey (string $keyGroup, string $subGroup, string $key, bool $forceInit = false) {
1302                 // Check parameter
1303                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,forceInit=%d - CALLED!', $keyGroup, $subGroup, $key, intval($forceInit)));
1304                 if (empty($keyGroup)) {
1305                         // Throw IAE
1306                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1307                 } elseif (empty($subGroup)) {
1308                         // Throw IAE
1309                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1310                 } elseif (empty($key)) {
1311                         // Throw IAE
1312                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1313                 } elseif (($forceInit === false) && ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key))) {
1314                         // Already initialized
1315                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s already initialized.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1316                 }
1317
1318                 // Initialize it
1319                 $this->genericArray[$keyGroup][$subGroup][$key] = [];
1320
1321                 // Trace mesage
1322                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1323         }
1324
1325         /**
1326          * Initializes given generic array element
1327          *
1328          * @param       $keyGroup       Main group for the key
1329          * @param       $subGroup       Sub group for the key
1330          * @param       $key            Key to use
1331          * @param       $element        Element to use
1332          * @param       $forceInit      Optionally force initialization
1333          * @return      void
1334          * @throws      InvalidArgumentException        If a parameter is not valid
1335          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1336          */
1337         protected final function initGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element, bool $forceInit = false) {
1338                 // Check parameter
1339                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s,forceInit=%d - CALLED!', $keyGroup, $subGroup, $key, $element, intval($forceInit)));
1340                 if (empty($keyGroup)) {
1341                         // Throw IAE
1342                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1343                 } elseif (empty($subGroup)) {
1344                         // Throw IAE
1345                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1346                 } elseif (empty($key)) {
1347                         // Throw IAE
1348                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1349                 } elseif ($element === '') {
1350                         // Throw IAE
1351                         throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1352                 } elseif (($forceInit === false) && ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element))) {
1353                         // Already initialized
1354                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s,element[%s]=%s already initialized.', $keyGroup, $subGroup, gettype($key), $key, gettype($element), $element), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1355                 }
1356
1357                 // Initialize it
1358                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = [];
1359
1360                 // Trace mesage
1361                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1362         }
1363
1364         /**
1365          * Pushes an element to a generic key. If the key isn't found, it will be initialized.
1366          *
1367          * @param       $keyGroup       Main group for the key
1368          * @param       $subGroup       Sub group for the key
1369          * @param       $key            Key to use
1370          * @param       $value          Value to add/append
1371          * @return      $count          Number of array elements
1372          * @throws      InvalidArgumentException        If a parameter is not valid
1373          */
1374         protected final function pushValueToGenericArrayKey (string $keyGroup, string $subGroup, string $key, $value) {
1375                 // Check parameter
1376                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,value[]=%s - CALLED!', $keyGroup, $subGroup, $key, gettype($value)));
1377                 if (empty($keyGroup)) {
1378                         // Throw IAE
1379                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1380                 } elseif (empty($subGroup)) {
1381                         // Throw IAE
1382                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1383                 } elseif (empty($key)) {
1384                         // Throw IAE
1385                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1386                 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1387                         // Initialize array
1388                         $this->initGenericArrayKey($keyGroup, $subGroup, $key);
1389                 }
1390
1391                 // Then push it
1392                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key], $value);
1393
1394                 // Return count
1395                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
1396                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1397                 return $count;
1398         }
1399
1400         /**
1401          * Pushes an element to a generic array element. If the key isn't found, it will be initialized.
1402          *
1403          * @param       $keyGroup       Main group for the key
1404          * @param       $subGroup       Sub group for the key
1405          * @param       $key            Key to use
1406          * @param       $element        Element to check
1407          * @param       $value          Value to add/append
1408          * @return      $count          Number of array elements
1409          * @throws      InvalidArgumentException        If a parameter is not valid
1410          */
1411         protected final function pushValueToGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element, $value) {
1412                 // Check parameter
1413                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s,value[]=%s - CALLED!', $keyGroup, $subGroup, $key, $element, gettype($value)));
1414                 if (empty($keyGroup)) {
1415                         // Throw IAE
1416                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1417                 } elseif (empty($subGroup)) {
1418                         // Throw IAE
1419                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1420                 } elseif (empty($key)) {
1421                         // Throw IAE
1422                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1423                 } elseif ($element === '') {
1424                         // Throw IAE
1425                         throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1426                 } elseif (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
1427                         // Initialize array
1428                         //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: Invoking this->initGenericArrayElement(%s,%s,%s,%s) ...', $keyGroup, $subGroup, $key, $element));
1429                         $this->initGenericArrayElement($keyGroup, $subGroup, $key, $element);
1430                 }
1431
1432                 // Then push it
1433                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key][$element], $value);
1434
1435                 // Return count
1436                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
1437                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1438                 return $count;
1439         }
1440
1441         /**
1442          * Pops an element from  a generic group
1443          *
1444          * @param       $keyGroup       Main group for the key
1445          * @param       $subGroup       Sub group for the key
1446          * @param       $key            Key to unset
1447          * @return      $value          Last "popped" value
1448          * @throws      InvalidArgumentException        If a parameter is not valid
1449          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1450          */
1451         protected final function popGenericArrayElement (string $keyGroup, string $subGroup, string $key) {
1452                 // Check parameter
1453                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1454                 if (empty($keyGroup)) {
1455                         // Throw IAE
1456                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1457                 } elseif (empty($subGroup)) {
1458                         // Throw IAE
1459                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1460                 } elseif (empty($key)) {
1461                         // Throw IAE
1462                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1463                 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1464                         // Not found
1465                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1466                 }
1467
1468                 // Then "pop" it
1469                 $value = array_pop($this->genericArray[$keyGroup][$subGroup][$key]);
1470
1471                 // Return value
1472                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
1473                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: value[]=%s - EXIT!', gettype($value)));
1474                 return $value;
1475         }
1476
1477         /**
1478          * Shifts an element from  a generic group
1479          *
1480          * @param       $keyGroup       Main group for the key
1481          * @param       $subGroup       Sub group for the key
1482          * @param       $key            Key to unset
1483          * @return      $value          Last "shifted" value
1484          * @throws      InvalidArgumentException        If a parameter is not valid
1485          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1486          */
1487         protected final function shiftGenericArrayElement (string $keyGroup, string $subGroup, string $key) {
1488                 // Check parameter
1489                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1490                 if (empty($keyGroup)) {
1491                         // Throw IAE
1492                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1493                 } elseif (empty($subGroup)) {
1494                         // Throw IAE
1495                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1496                 } elseif (empty($key)) {
1497                         // Throw IAE
1498                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1499                 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1500                         // Not found
1501                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1502                 }
1503
1504                 // Then "shift" it
1505                 $value = array_shift($this->genericArray[$keyGroup][$subGroup][$key]);
1506
1507                 // Return value
1508                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
1509                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: value[]=%s - EXIT!', gettype($value)));
1510                 return $value;
1511         }
1512
1513         /**
1514          * Count generic array group
1515          *
1516          * @param       $keyGroup       Main group for the key
1517          * @return      $count          Count of given group
1518          * @throws      InvalidArgumentException        If a parameter is not valid
1519          * @throws      BadMethodCallException  If key group isn't there but this method is invoked
1520          */
1521         protected final function countGenericArray (string $keyGroup) {
1522                 // Check parameter
1523                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s - CALLED!', $keyGroup));
1524                 if (empty($keyGroup)) {
1525                         // Throw IAE
1526                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1527                 } elseif (!isset($this->genericArray[$keyGroup])) {
1528                         // Not found
1529                         throw new BadMethodCallException(sprintf('keyGroup=%s not found.', $keyGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1530                 }
1531
1532                 // Then count it
1533                 $count = count($this->genericArray[$keyGroup]);
1534
1535                 // Return it
1536                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1537                 return $count;
1538         }
1539
1540         /**
1541          * Count generic array sub group
1542          *
1543          * @param       $keyGroup       Main group for the key
1544          * @param       $subGroup       Sub group for the key
1545          * @return      $count          Count of given group
1546          * @throws      InvalidArgumentException        If a parameter is not valid
1547          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1548          */
1549         protected final function countGenericArrayGroup (string $keyGroup, string $subGroup) {
1550                 // Check parameter
1551                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s - CALLED!', $keyGroup, $subGroup));
1552                 if (empty($keyGroup)) {
1553                         // Throw IAE
1554                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1555                 } elseif (empty($subGroup)) {
1556                         // Throw IAE
1557                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1558                 } elseif (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
1559                         // Abort here
1560                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s not found.', $keyGroup, $subGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1561                 }
1562
1563                 // Then count it
1564                 $count = count($this->genericArray[$keyGroup][$subGroup]);
1565
1566                 // Return it
1567                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1568                 return $count;
1569         }
1570
1571         /**
1572          * Count generic array elements
1573          *
1574          * @param       $keyGroup       Main group for the key
1575          * @param       $subGroup       Sub group for the key
1576          * @param       $key            Key to count
1577          * @return      $count          Count of given key
1578          * @throws      InvalidArgumentException        If a parameter is not valid
1579          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1580          */
1581         protected final function countGenericArrayElements (string $keyGroup, string $subGroup, string $key) {
1582                 // Check parameter
1583                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1584                 if (empty($keyGroup)) {
1585                         // Throw IAE
1586                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1587                 } elseif (empty($subGroup)) {
1588                         // Throw IAE
1589                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1590                 } elseif (empty($key)) {
1591                         // Throw IAE
1592                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1593                 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1594                         // Abort here
1595                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1596                 } elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
1597                         // Not valid
1598                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s is not a valid key/sub group.', $keyGroup, $subGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1599                 }
1600
1601                 // Then count it
1602                 $count = count($this->genericArray[$keyGroup][$subGroup][$key]);
1603
1604                 // Return it
1605                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: count=%d - EXIT!', $count));
1606                 return $count;
1607         }
1608
1609         /**
1610          * Getter for whole generic group array
1611          *
1612          * @param       $keyGroup       Key group to get
1613          * @return      $array          Whole generic array group
1614          * @throws      InvalidArgumentException        If a parameter is not valid
1615          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1616          */
1617         protected final function getGenericArray (string $keyGroup) {
1618                 // Check parameters
1619                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s - CALLED!', $keyGroup));
1620                 if (empty($keyGroup)) {
1621                         // Throw IAE
1622                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1623                 } elseif (!isset($this->genericArray[$keyGroup])) {
1624                         // Then abort here
1625                         throw new BadMethodCallException(sprintf('keyGroup=%s not found', $keyGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1626                 }
1627
1628                 // Return it
1629                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->genericArray[%s][]=%s - EXIT!', $keyGroup, gettype($this->genericArray[$keyGroup])));
1630                 return $this->genericArray[$keyGroup];
1631         }
1632
1633         /**
1634          * Setter for generic array key
1635          *
1636          * @param       $keyGroup       Key group to get
1637          * @param       $subGroup       Sub group for the key
1638          * @param       $key            Key to unset
1639          * @param       $value          Mixed value from generic array element
1640          * @return      void
1641          * @throws      InvalidArgumentException        If a parameter is not valid
1642          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1643          */
1644         protected final function setGenericArrayKey (string $keyGroup, string $subGroup, string $key, $value) {
1645                 // Check parameters
1646                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,value[]=%s - CALLED!', $keyGroup, $subGroup, $key, gettype($value)));
1647                 if (empty($keyGroup)) {
1648                         // Throw IAE
1649                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1650                 } elseif (empty($subGroup)) {
1651                         // Throw IAE
1652                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1653                 } elseif (empty($key)) {
1654                         // Throw IAE
1655                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1656                 } elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
1657                         // Then abort here
1658                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s not found', $keyGroup), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1659                 }
1660
1661                 // Set value here
1662                 $this->genericArray[$keyGroup][$subGroup][$key] = $value;
1663
1664                 // Trace mesage
1665                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1666         }
1667
1668         /**
1669          * Getter for generic array key
1670          *
1671          * @param       $keyGroup       Key group to get
1672          * @param       $subGroup       Sub group for the key
1673          * @param       $key            Key to unset
1674          * @return      $value          Mixed value from generic array element
1675          * @throws      InvalidArgumentException        If a parameter is not valid
1676          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1677          */
1678         protected final function getGenericArrayKey (string $keyGroup, string $subGroup, string $key) {
1679                 // Check parameters
1680                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1681                 if (empty($keyGroup)) {
1682                         // Throw IAE
1683                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1684                 } elseif (empty($subGroup)) {
1685                         // Throw IAE
1686                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1687                 } elseif (empty($key)) {
1688                         // Throw IAE
1689                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1690                 } elseif (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
1691                         // Then abort here
1692                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1693                 }
1694
1695                 // Return it
1696                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->genericArray[%s][%s][%s][]=%s - EXIT!', $keyGroup, $subGroup, $key, gettype($this->genericArray[$keyGroup][$subGroup][$key])));
1697                 return $this->genericArray[$keyGroup][$subGroup][$key];
1698         }
1699
1700         /**
1701          * Sets a value in given generic array key/element
1702          *
1703          * @param       $keyGroup       Main group for the key
1704          * @param       $subGroup       Sub group for the key
1705          * @param       $key            Key to set
1706          * @param       $element        Element to set
1707          * @param       $value          Value to set
1708          * @return      void
1709          * @throws      InvalidArgumentException        If a parameter is not valid
1710          */
1711         protected final function setGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element, $value) {
1712                 // Check parameter
1713                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s,value[]=%s - CALLED!', $keyGroup, $subGroup, $key, $element, gettype($value)));
1714                 if (empty($keyGroup)) {
1715                         // Throw IAE
1716                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1717                 } elseif (empty($subGroup)) {
1718                         // Throw IAE
1719                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1720                 } elseif (empty($key)) {
1721                         // Throw IAE
1722                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1723                 } elseif ($element === '') {
1724                         // Throw IAE
1725                         throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1726                 } elseif (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
1727                         // Initialize array
1728                         $this->initGenericArrayElement($keyGroup, $subGroup, $key, $element);
1729                 }
1730
1731                 // Then set it
1732                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = $value;
1733
1734                 // Trace mesage
1735                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1736         }
1737
1738         /**
1739          * Getter for generic array element
1740          *
1741          * @param       $keyGroup       Key group to get
1742          * @param       $subGroup       Sub group for the key
1743          * @param       $key            Key to look for
1744          * @param       $element        Element to look for
1745          * @return      $value          Mixed value from generic array element
1746          * @throws      InvalidArgumentException        If a parameter is not valid
1747          * @throws      BadMethodCallException  If key/sub group isn't there but this method is invoked
1748          */
1749         protected final function getGenericArrayElement (string $keyGroup, string $subGroup, string $key, string $element) {
1750                 // Check parameter
1751                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s,element=%s - CALLED!', $keyGroup, $subGroup, $key, $element));
1752                 if (empty($keyGroup)) {
1753                         // Throw IAE
1754                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1755                 } elseif (empty($subGroup)) {
1756                         // Throw IAE
1757                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1758                 } elseif (empty($key)) {
1759                         // Throw IAE
1760                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1761                 } elseif ($element === '') {
1762                         // Throw IAE
1763                         throw new InvalidArgumentException('Parameter "element" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1764                 } elseif (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
1765                         // Then abort here
1766                         throw new BadMethodCallException(sprintf('keyGroup=%s,subGroup=%s,key[%s]=%s,element[%s]=%s not found.', $keyGroup, $subGroup, gettype($key), $key, gettype($element), $element), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1767                 }
1768
1769                 // Return it
1770                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: this->genericArray[%s][%s][%s][%s][]=%s - EXIT!', $keyGroup, $subGroup, $key, gettype($this->genericArray[$keyGroup][$subGroup][$key][$element])));
1771                 return $this->genericArray[$keyGroup][$subGroup][$key][$element];
1772         }
1773
1774         /**
1775          * Checks if a given sub group is valid (array)
1776          *
1777          * @param       $keyGroup       Key group to get
1778          * @param       $subGroup       Sub group for the key
1779          * @return      $isValid        Whether given sub group is valid
1780          * @throws      InvalidArgumentException        If a parameter is not valid
1781          */
1782         protected final function isValidGenericArrayGroup (string $keyGroup, string $subGroup) {
1783                 // Check parameter
1784                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s - CALLED!', $keyGroup, $subGroup));
1785                 if (empty($keyGroup)) {
1786                         // Throw IAE
1787                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1788                 } elseif (empty($subGroup)) {
1789                         // Throw IAE
1790                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1791                 }
1792
1793                 // Determine it
1794                 $isValid = (($this->isGenericArrayGroupSet($keyGroup, $subGroup)) && (is_array($this->getGenericSubArray($keyGroup, $subGroup))));
1795
1796                 // Return it
1797                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isValid=%d - EXIT!', intval($isValid)));
1798                 return $isValid;
1799         }
1800
1801         /**
1802          * Checks if a given key is valid (array)
1803          *
1804          * @param       $keyGroup       Key group to get
1805          * @param       $subGroup       Sub group for the key
1806          * @param       $key            Key to check
1807          * @return      $isValid        Whether given sub group is valid
1808          */
1809         protected final function isValidGenericArrayKey (string $keyGroup, string $subGroup, string $key) {
1810                 // Check parameters
1811                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: keyGroup=%s,subGroup=%s,key=%s - CALLED!', $keyGroup, $subGroup, $key));
1812                 if (empty($keyGroup)) {
1813                         // Throw IAE
1814                         throw new InvalidArgumentException('Parameter "keyGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1815                 } elseif (empty($subGroup)) {
1816                         // Throw IAE
1817                         throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1818                 } elseif (empty($key)) {
1819                         // Throw IAE
1820                         throw new InvalidArgumentException('Parameter "key" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
1821                 }
1822
1823                 // Determine it
1824                 $isValid = (($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) && (is_array($this->getGenericArrayKey($keyGroup, $subGroup, $key))));
1825
1826                 // Return it
1827                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: isValid=%d - EXIT!', intval($isValid)));
1828                 return $isValid;
1829         }
1830
1831         /**
1832          * Initializes the web output instance
1833          *
1834          * @return      void
1835          */
1836         protected function initWebOutputInstance () {
1837                 // Init web output instance
1838                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: CALLED!');
1839                 $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class');
1840
1841                 // Set it locally
1842                 $this->setWebOutputInstance($outputInstance);
1843
1844                 // Trace mesage
1845                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: EXIT!');
1846         }
1847
1848         /**
1849          * Translates boolean true to 'Y' and false to 'N'
1850          *
1851          * @param       $boolean                Boolean value
1852          * @return      $translated             Translated boolean value
1853          */
1854         public static final function translateBooleanToYesNo (bool $boolean) {
1855                 // "Translate" it
1856                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: boolean=%d - CALLED!', intval($boolean)));
1857                 $translated = ($boolean === true) ? 'Y' : 'N';
1858
1859                 // ... and return it
1860                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: translated=%s - EXIT!', $translated));
1861                 return $translated;
1862         }
1863
1864         /**
1865          * Creates a full-qualified file name (FQFN) for given file name by adding
1866          * a configured temporary file path to it.
1867          *
1868          * @param       $infoInstance   An instance of a SplFileInfo class
1869          * @return      $fileInfoInstance       An instance of a SplFileInfo class (temporary file)
1870          * @throw       PathWriteProtectedException If the path in 'temp_file_path' is write-protected
1871          * @throws      FileIoException If the file cannot be written
1872          */
1873          protected static function createTempPathForFile (SplFileInfo $infoInstance) {
1874                 // Get config entry
1875                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: infoInstance=%s - CALLED!', $infoInstance->__toString()));
1876                 $basePath = FrameworkBootstrap::getConfigurationInstance()->getConfigEntry('temp_file_path');
1877
1878                 // Is the path writeable?
1879                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: basePath=%s', $basePath));
1880                 if (!is_writable($basePath)) {
1881                         // Path is write-protected
1882                         throw new PathWriteProtectedException($infoInstance, self::EXCEPTION_PATH_CANNOT_BE_WRITTEN);
1883                 }
1884
1885                 // Add it
1886                 $fileInfoInstance = new SplFileInfo($basePath . DIRECTORY_SEPARATOR . $infoInstance->getBasename());
1887
1888                 // Is it reachable?
1889                 if (!FrameworkBootstrap::isReachableFilePath($fileInfoInstance)) {
1890                         // Not reachable
1891                         throw new FileIoException($fileInfoInstance, self::EXCEPTION_FILE_NOT_REACHABLE);
1892                 }
1893
1894                 // Return it
1895                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: fileInfoInstance=%s - EXIT!', $fileInfoInstance->__toString()));
1896                 return $fileInfoInstance;
1897          }
1898
1899         /**
1900          * "Getter" for a printable state name
1901          *
1902          * @return      $stateName      Name of the node's state in a printable format
1903          * @throws      BadMethodCallException  If this instance doesn't have a callable getter for stateInstance
1904          * @todo        Move this class away from this monolithic place (not whole class is monolithic)
1905          */
1906         public final function getPrintableState () {
1907                 // Check if getter is there
1908                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('BASE-FRAMEWORK-SYSTEM: CALLED!');
1909                 if (!is_callable($this, 'getStateInstance')) {
1910                         // Throw BMCE
1911                         throw new BadMethodCallException(sprintf('this=%s has no callable getter for stateInstance', $this->__toString()), FrameworkInterface::EXCEPTION_BAD_METHOD_CALL);
1912                 }
1913
1914                 // Default is 'null'
1915                 $stateName = 'null';
1916
1917                 // Get the state instance
1918                 $stateInstance = $this->getStateInstance();
1919
1920                 // Is it an instance of Stateable?
1921                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: stateInstance[]=%s', gettype($stateInstance)));
1922                 if ($stateInstance instanceof Stateable) {
1923                         // Then use that state name
1924                         $stateName = $stateInstance->getStateName();
1925                 }
1926
1927                 // Return result
1928                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('BASE-FRAMEWORK-SYSTEM: stateName=%s - EXIT!', $stateName));
1929                 return $stateName;
1930         }
1931
1932 }