public static function concatDeep($collection1, $collection2)
    {
        return __::reduceRight(func_get_args(), function ($source, $result) {
            __::doForEach($source, function ($sourceValue, $key) use (&$result) {
                if (!__::has($result, $key)) {
                    $result = __::set($result, $key, $sourceValue);
                } else {
                    if (is_numeric($key)) {
                        $result = __::concat($result, [$sourceValue]);
                    } else {
                        $resultValue = __::get($result, $key);
                        $result = __::set($result, $key, __::concatDeep(
                            __::isCollection($resultValue) ? $resultValue : (array)$resultValue,
                            __::isCollection($sourceValue) ? $sourceValue : (array)$sourceValue
                        ));
                    }
                }
            });

            return $result;
        }, []);
    }