static public function arrayTraverse(array $inNode, callable $inFunction, array &$inOutResult, array $inOptParent=null) {

        // Sanity checks
        if (! array_key_exists(self::$__dataTag, $inNode)) {
            throw new \Exception("This given array in not a valid tree. Key '" . self::$__dataTag . "' is missing!");
        }

        if (! array_key_exists(self::$__childrenTag, $inNode)) {
            throw new \Exception("This given array in not a valid tree. Key '" . self::$__childrenTag . "' is missing!");
        }

        if (! is_array($inNode[self::$__childrenTag])) {
            throw new \Exception("This given array in not a valid tree. Key '" . self::$__childrenTag . "' is not an array!");
        }

        // Call the user provided function on the current node.
        $inFunction($inNode, count($inNode[self::$__childrenTag]) > 0, $inOptParent, $inOutResult);

        // Walk through the children.
        foreach ($inNode[self::$__childrenTag] as $_child) {
            if (count($_child[self::$__childrenTag]) > 0) {
                // The actual node is not a leaf. Let's walk through the children.
                self::arrayTraverse($_child, $inFunction, $inOutResult, $inNode);
                // As long as we encounter a child, we call the method recursively. Thus method's execution's contexts pile up.
                // However, as soon as we encounter a leaf, we start to continue the execution of all previously piled up method's execution's contexts.
                // Once all piled up execution's contexts have ended, we walk through the next tree's node.
                continue;
            }
            // The current node is a leaf.
            $inFunction($_child, true, $inNode, $inOutResult);
        }
    }