public static function join($paths)
    {
        if (!is_array($paths)) {
            $paths = func_get_args();
        }

        Assert::allString($paths, 'The paths must be strings. Got: %s');

        $finalPath = null;
        $wasScheme = false;

        foreach ($paths as $path) {
            $path = (string) $path;

            if ('' === $path) {
                continue;
            }

            if (null === $finalPath) {
                // For first part we keep slashes, like '/top', 'C:\' or 'phar://'
                $finalPath = $path;
                $wasScheme = (strpos($path, '://') !== false);
                continue;
            }

            // Only add slash if previous part didn't end with '/' or '\'
            if (!in_array(substr($finalPath, -1), array('/', '\\'))) {
                $finalPath .= '/';
            }

            // If first part included a scheme like 'phar://' we allow current part to start with '/', otherwise trim
            $finalPath .= $wasScheme ? $path : ltrim($path, '/');
            $wasScheme = false;
        }

        if (null === $finalPath) {
            return '';
        }

        return self::canonicalize($finalPath);
    }