static function joinChains(\Throwable ...$nodes): ?\Throwable
    {
        $lastNodeIndex = count($nodes) - 1;

        if ($lastNodeIndex > 0) {
            // iterate over all but the last node
            for ($i = 0; $i < $lastNodeIndex; ++$i) {
                // find initial node of the next chain
                $initialNode = $nodes[$i + 1];
                $hashMap = [];
                while (($previousNode = $initialNode->getPrevious()) && !isset($hashMap[$hash = spl_object_hash($previousNode)])) {
                    $initialNode = $previousNode;
                }

                // connect end of the current chain (= current node)
                // to the initial node of the next chain
                $previousProperty = new \ReflectionProperty(
                    ($parents = class_parents($initialNode)) ? end($parents) : $initialNode,
                    'previous'
                );

                $previousProperty->setAccessible(true);
                $previousProperty->setValue($initialNode, $nodes[$i]);
            }
        }

        return $nodes[$lastNodeIndex] ?? null;
    }