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