Continued:
[core.git] / framework / main / classes / lists / class_BaseList.php
index bb58363627f216a7fff2c56cc2c68282b760f1d7..061733a44c14c496a733354567cafde11a2c166f 100644 (file)
@@ -3,12 +3,15 @@
 namespace Org\Mxchange\CoreFramework\Lists;
 
 // Import framework stuff
-use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
+use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
 use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
+use Org\Mxchange\CoreFramework\Traits\Iterator\IteratorTrait;
 use Org\Mxchange\CoreFramework\Visitor\Visitable;
 
 // Import SPL stuff
+use \BadMethodCallException;
+use \InvalidArgumentException;
 use \IteratorAggregate;
 use \Countable;
 
@@ -17,7 +20,7 @@ use \Countable;
  *
  * @author             Roland Haeder <webmaster@shipsimu.org>
  * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
  * @license            GNU GPL 3.0 or any newer version
  * @link               http://www.shipsimu.org
  *
@@ -35,6 +38,9 @@ use \Countable;
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate, Countable {
+       // Load traits
+       use IteratorTrait;
+
        // Exception constants
        const EXCEPTION_GROUP_ALREADY_ADDED = 0xf20;
        const EXCEPTION_GROUP_NOT_FOUND     = 0xf21;
@@ -43,17 +49,25 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
        /**
         * List groups array
         */
-       private $listGroups = array();
+       private $listGroups = [];
 
        /**
         * List entries array
         */
-       private $listEntries = array();
+       private $listEntries = [];
 
        /**
         * List index array
         */
-       private $listIndex = array();
+       private $listIndex = [];
+
+       /**
+        * Cached values from "expensive" method calls
+        */
+       private $cache = [
+               // Cached isValidHash() calls
+               'is_valid' => [],
+       ];
 
        /**
         * Protected constructor
@@ -61,7 +75,7 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @param       $className      Name of the class
         * @return      void
         */
-       protected function __construct ($className) {
+       protected function __construct (string $className) {
                // Call parent constructor
                parent::__construct($className);
        }
@@ -78,11 +92,11 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
                // Is the instance set?
                if (is_null($iteratorInstance)) {
                        // Prepare a default iterator
-                       $iteratorInstance = ObjectFactory::createObjectByConfiguredName('default_iterator_class', array($this));
+                       $iteratorInstance = ObjectFactory::createObjectByConfiguredName('default_iterator_class', [$this]);
 
                        // Set it here
                        $this->setIteratorInstance($iteratorInstance);
-               } // END - if
+               }
 
                // And return it
                return $iteratorInstance;
@@ -94,29 +108,39 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @param       $groupName      Group to check if found in list
         * @return      $isset          Whether the group is valid
         */
-       public function isGroupSet ($groupName) {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName);
+       public function isGroupSet (string $groupName) {
+               // Validate parameter
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-LIST: groupName=%s - CALLED!', $groupName));
+               if (empty($groupName)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "groupName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               }
+
+               // Check on existence ...
                return isset($this->listGroups[$groupName]);
        }
 
        /**
-        * Adds the given group or if already added issues a ListGroupAlreadyAddedException
+        * Adds the given group or if already added issues a BadMethodCallException
         *
         * @param       $groupName      Group to add
         * @return      void
-        * @throws      ListGroupAlreadyAddedException  If the given group is already added
+        * @throws      BadMethodCallException  If the given group is already added
         */
-       public function addGroup ($groupName) {
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - CALLED!');
-               // Is the group already added?
-               if ($this->isGroupSet($groupName)) {
+       public function addGroup (string $groupName) {
+               // Validate parameter
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-LIST: groupName=%s - CALLED!', $groupName));
+               if (empty($groupName)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "groupName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif ($this->isGroupSet($groupName)) {
                        // Throw the exception here
-                       throw new ListGroupAlreadyAddedException(array($this, $groupName), self::EXCEPTION_GROUP_ALREADY_ADDED);
-               } // END - if
+                       throw new BadMethodCallException(sprintf('groupName=%s is already set', $groupName), self::EXCEPTION_GROUP_ALREADY_ADDED);
+               }
 
                // Add the group which is a simple array
                $this->listGroups[$groupName] = ObjectFactory::createObjectByConfiguredName('list_group_class');
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - EXIT!');
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName . ' - EXIT!');
        }
 
        /**
@@ -126,83 +150,83 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @param       $subGroup                       Sub group to add instance to
         * @param       $visitableInstance      An instance of Visitable
         * @return      void
-        * @throws      NoListGroupException    If the given group is not found
+        * @throws      BadMethodCallException  If the given group is not found
         */
-       public function addInstance ($groupName, $subGroup, Visitable $visitableInstance) {
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName  . ',subGroup=' . $subGroup . ',visitableInstance=' . $visitableInstance->__toString() . ' - CALLED!');
-
-               // Is the group there?
-               if (!$this->isGroupSet($groupName)) {
+       public function addInstance (string $groupName, string $subGroup, Visitable $visitableInstance) {
+               // Validate parameter
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName  . ',subGroup=' . $subGroup . ',visitableInstance=' . $visitableInstance->__toString() . ' - CALLED!');
+               if (empty($groupName)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "groupName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (empty($subGroup)) {
+                       // Throw it again
+                       throw new InvalidArgumentException('Parameter "subGroup" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (!$this->isGroupSet($groupName)) {
                        // Throw the exception here
-                       throw new NoListGroupException(array($this, $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
-               } // END - if
+                       throw new BadMethodCallException(sprintf('groupName=%s is not a valid group', $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
+               }
 
                // Is the sub group there?
                if (!$this->listGroups[$groupName]->isGroupSet($subGroup)) {
                        // Automatically add it
                        $this->listGroups[$groupName]->addGroup($subGroup);
-               } // END - if
+               }
 
                // Generate the hash
                $hash = $this->generateHash($groupName, $subGroup, $visitableInstance);
 
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',this->listGroups[' . $groupName . ']=' . $this->listGroups[$groupName]->__toString());
-
                // Add the hash to the index
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: this->listGroups[' . $groupName . ']=' . $this->listGroups[$groupName]->__toString());
                array_push($this->listIndex, $hash);
 
                // Add the instance itself to the list
                $this->listEntries[$hash] = $visitableInstance;
 
                // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName  . ',subGroup=' . $subGroup . ' - EXIT!');
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName  . ',subGroup=' . $subGroup . ' - EXIT!');
        }
 
        /**
         * Gets an array from given list
         *
-        * @param       $list   The requested list
+        * @param       $groupName      The requested list
         * @return      $array  The requested array
-        * @throws      NoListGroupException    If the given group is not found
+        * @throws      BadMethodCallException  If the given group is not found
         */
-       public final function getArrayFromList ($list) {
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',list[' . gettype($list) . ']=' . $list . ' - CALLED!');
-
+       public final function getArrayFromList (string $groupName) {
                // Is the group there?
-               if ((!is_null($list)) && (!$this->isGroupSet($list))) {
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName[' . gettype($groupName) . ']=' . $groupName . ' - CALLED!');
+               if (empty($groupName)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "groupName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (!$this->isGroupSet($groupName)) {
                        // Throw the exception here
-                       throw new NoListGroupException(array($this, $list), self::EXCEPTION_GROUP_NOT_FOUND);
-               } // END - if
+                       throw new BadMethodCallException(sprintf('groupName=%s is not a valid group', $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
+               }
 
                // Init array
-               $array = array();
+               $array = [];
 
                // Is there another list?
-               if (!is_null($list)) {
+               if ($this->listGroups[$groupName]->isGroupSet($groupName)) {
                        // Then get it as well
-                       $array = $this->listGroups[$list]->getArrayFromList(NULL);
-               } // END - if
+                       //* DEBUG-DIE: */ die(sprintf('[%s:%d]: groupName=%s,this=%s', __METHOD__, __LINE__, $groupName, print_r($this, TRUE)));
+                       $array = $this->listGroups[$groupName]->getArrayFromList($groupName);
+               }
 
                // Walk through all entries
                foreach ($this->listIndex as $hash) {
-                       // Debug message
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: hash=' . $hash);
-
                        // Is the list entry set?
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: hash=' . $hash);
                        if ($this->isHashValid($hash)) {
                                // Add it
                                array_push($array, $this->listEntries[$hash]);
-                               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: hash=' . $hash . ',array(' . count($array) . ')=' . print_r($array, true) . ' - ADDED!');
-                       } // END - if
-               } // END - foreach
-
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',list[' . gettype($list) . ']=' . $list . ',array()=' . count($array) . ' - EXIT!');
+                               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: hash=' . $hash . ',array(' . count($array) . ')=' . print_r($array, true) . ' - ADDED!');
+                       }
+               }
 
                // Return it
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName[' . gettype($groupName) . ']=' . $groupName . ',[]=' . count($array) . ' - EXIT!');
                return $array;
        }
 
@@ -212,35 +236,36 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @param       $groupName      Group to add instance to
         * @param       $entry          An entry of any type
         * @return      void
-        * @throws      NoListGroupException    If the given group is not found
+        * @throws      BadMethodCallException  If the given group is not found
         */
-       public function addEntry ($groupName, $entry) {
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - CALLED!');
-
+       public function addEntry (string $groupName, $entry) {
                // Is the group already added?
-               if (!$this->isGroupSet($groupName)) {
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName . ' - CALLED!');
+               if (empty($groupName)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "groupName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (!$this->isGroupSet($groupName)) {
                        // Throw the exception here
-                       throw new NoListGroupException(array($this, $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
-               } // END - if
+                       throw new BadMethodCallException(sprintf('groupName=%s is not a valid group', $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
+               }
 
                // Generate hash
                $hash = $this->generateHash($groupName, $groupName, $entry);
 
                // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',entry=' . print_r($entry, true) . ', hash=' . $hash);
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName . ',entry=' . print_r($entry, true) . ', hash=' . $hash);
 
                // Add the hash to the index
                array_push($this->listIndex, $hash);
 
                // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',listEntries()=' . count($this->listEntries));
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName . ',listEntries()=' . count($this->listEntries));
 
                // Now add the entry to the list
                $this->listEntries[$hash] = $entry;
 
                // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',listEntries()=' . count($this->listEntries) . ' - EXIT!');
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName . ',listEntries()=' . count($this->listEntries) . ' - EXIT!');
        }
 
        /**
@@ -249,23 +274,24 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @param       $groupName      Group where we should remove the entry from
         * @param       $entry          The entry we should remove
         * @return      void
-        * @throws      NoListGroupException    If the given group is not found
+        * @throws      BadMethodCallException  If the given group is not found
         */
-       public function removeEntry ($groupName, $entry) {
-               // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - CALLED!');
-
+       public function removeEntry (string $groupName, $entry) {
                // Is the group already added?
-               if (!$this->isGroupSet($groupName)) {
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName . ' - CALLED!');
+               if (empty($groupName)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "groupName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (!$this->isGroupSet($groupName)) {
                        // Throw the exception here
-                       throw new NoListGroupException(array($this, $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
-               } // END - if
+                       throw new BadMethodCallException(sprintf('groupName=%s is not a valid group', $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
+               }
 
                // Generate hash
                $hash = $this->generateHash($groupName, $groupName, $entry);
 
                // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ',entry=' . $entry . ', hash=' . $hash);
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName . ',entry=' . $entry . ', hash=' . $hash);
 
                // Remove it from the list ...
                unset($this->listEntries[$hash]);
@@ -274,7 +300,7 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
                unset($this->listIndex[array_search($hash, $this->listIndex)]);
 
                // Debug message
-               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: this=' . $this->__toString() . ',groupName=' . $groupName . ' - EXIT!');
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName . ' - EXIT!');
        }
 
        /**
@@ -285,8 +311,9 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @param       $entry          An entry of any type
         * @return      $hash           The generated
         */
-       private function generateHash ($groupName, $subGroup, $entry) {
+       private function generateHash (string $groupName, string $subGroup, $entry) {
                // Created entry, 'null' is default
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: groupName=' . $groupName  . ',subGroup=' . $subGroup . ',entry[]=' . gettype($entry) . ' - CALLED!');
                $entry2 = 'null';
 
                // Determine type of entry
@@ -309,19 +336,20 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
                        $entry2 = $this->getCallbackInstance()->generateListHashFromEntry($entry);
                } else {
                        // Unsupported type detected
-                       self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST[' . __METHOD__ . ':' . __LINE__ . ']: Entry type ' . gettype($entry) . ' is unsupported (this->callbackInstance=' . $this->getCallbackInstance() . ').');
+                       self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: Entry type ' . gettype($entry) . ' is unsupported (this->callbackInstance=' . $this->getCallbackInstance() . ').');
 
                        // At least take all keys from array
                        $entry2 = gettype($entry) . ':' . implode(':', array_keys($entry));
                }
 
                // Construct string which we shall hash
-               $hashString = $groupName . ':' . $subGroup . ':' . $entry2;
+               $hashString = sprintf('%s:%s:%s', $groupName, $subGroup, $entry2);
 
                // Hash it with fastest hasher
                $hash = crc32($hashString);
 
                // And return it
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-LIST: hash=%s - EXIT!', $hash));
                return $hash;
        }
 
@@ -336,7 +364,7 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
                foreach ($groupNames as $groupName) {
                        // Clear this group
                        $this->clearGroup($groupName);
-               } // END - foreach
+               }
        }
 
        /**
@@ -345,19 +373,22 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @param       $groupName      Name of an existing group to clear
         * @return      void
         */
-       protected function clearGroup ($groupName) {
+       protected function clearGroup (string $groupName) {
                // Does this group exist?
-               if (!$this->isGroupSet($groupName)) {
+               if (empty($groupName)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "groupName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (!$this->isGroupSet($groupName)) {
                        // Throw the exception here
-                       throw new NoListGroupException(array($this, $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
-               } // END - if
+                       throw new BadMethodCallException(sprintf('groupName=%s is not a valid group', $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
+               }
 
                // Then clear this group list
                $this->listGroups[$groupName]->clearList();
 
                // Clear this list
-               $this->listIndex = array();
-               $this->listEntries = array();
+               $this->listIndex = [];
+               $this->listEntries = [];
        }
        
        /**
@@ -375,12 +406,18 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @param       $hash           The hash we should validate
         * @return      $isValid        Whether the given hash is valid
         */
-       public final function isHashValid ($hash) {
-               // Check it
-               $isValid = ((in_array($hash, $this->listIndex)) && (isset($this->listEntries[$hash])));
+       public final function isHashValid (string $hash) {
+               // Validate parameter
+               if (empty($hash)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "hash" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (!isset($this->cache['is_valid'][$hash])) {
+                       // Check it
+                       $this->cache['is_valid'][$hash] = ((in_array($hash, $this->listIndex)) && (isset($this->listEntries[$hash])));
+               }
 
                // Return the result
-               return $isValid;
+               return $this->cache['is_valid'][$hash];
        }
 
        /**
@@ -389,7 +426,7 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @param       $hashIndex      Index holding the hash
         * @return      $hash           The hash
         */
-       public final function getHash ($hashIndex) {
+       public final function getHashByIndex (int $hashIndex) {
                // Get it ...
                $hash = $this->listIndex[$hashIndex];
 
@@ -404,15 +441,15 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @return      $entry          Solved entry from list
         * @throws      InvalidListHashException        If the solved hash index is invalid
         */
-       public function getEntry ($hashIndex) {
+       public function getEntryByIndex (int $hashIndex) {
                // Get the hash value
-               $hash = $this->getHash($hashIndex);
+               $hash = $this->getHashByIndex($hashIndex);
 
                // Is the hash valid?
                if (!$this->isHashValid($hash)) {
                        // Throw an exception here
                        throw new InvalidListHashException(array($this, $hash, $hashIndex), self::EXCEPTION_INVALID_HASH);
-               } // END - if
+               }
 
                // Now copy the entry
                $entry = $this->listEntries[$hash];
@@ -426,17 +463,21 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         *
         * @param       $groupName      The group name to get a list for
         * @return      $entries        The array with all entries
-        * @throws      NoListGroupException    If the specified group is invalid
+        * @throws      BadMethodCallException  If the specified group is invalid
         */
-       public function getArrayFromProtocolInstance ($groupName) {
+       public function getArrayFromProtocolInstance (string $groupName) {
                // Is the group valid?
-               if (!$this->isGroupSet($groupName)) {
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-LIST: groupName=%s - CALLED!', $groupName));
+               if (empty($groupName)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "groupName" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (!$this->isGroupSet($groupName)) {
                        // Throw the exception here
-                       throw new NoListGroupException(array($this, $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
-               } // END - if
+                       throw new BadMethodCallException(sprintf('groupName=%s is not a valid group', $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
+               }
 
                // Init the entries' array
-               $entries = array();
+               $entries = [];
 
                // Get an iterator
                $iteratorInstance = $this->listGroups[$groupName]->getIterator();
@@ -450,17 +491,15 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
                        $entryIndex = $iteratorInstance->key();
 
                        // ... and the final entry which is the stored instance
-                       $entry = $this->getEntry($entryIndex);
-
-                       // Debug message
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('LIST: Adding entry ' . $entry . ' ...');
+                       $entry = $this->getEntryByIndex($entryIndex);
 
                        // Add it to the list
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-LIST: Adding entry ' . $entry . ' ...');
                        $entries[$iteratorInstance->current()] = $entry;
 
                        // Skip to next one
                        $iteratorInstance->next();
-               } // END - while
+               }
 
                // Return the list
                return $entries;
@@ -474,12 +513,15 @@ abstract class BaseList extends BaseFrameworkSystem implements IteratorAggregate
         * @return      void
         * @throws      InvalidListHashException        If the solved hash index is invalid
         */
-       public function updateCurrentEntryByHash ($hash, array $entryArray) {
+       public function updateCurrentEntryByHash (string $hash, array $entryArray) {
                // Is the hash valid?
-               if (!$this->isHashValid($hash)) {
+               if (empty($hash)) {
+                       // Throw IAE
+                       throw new InvalidArgumentException('Parameter "hash" is empty', FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+               } elseif (!$this->isHashValid($hash)) {
                        // Throw an exception here, hashIndex is unknown at this point
                        throw new InvalidListHashException(array($this, $hash, -999), self::EXCEPTION_INVALID_HASH);
-               } // END - if
+               }
 
                // Set the entry
                $this->listEntries[$hash] = $entryArray;