public static function fromString(string $str) : Cookie
    {
        $err = false;
        $name = "";
        $value = "";
        $expires = null;
        $domain = null;
        $path = "/";
        $secure = false;
        $httpOnly = false;


        if ($str === "") {
            $err = "The string is not a valid representation of a cookie.";
        }


        if ($err === false) {
            $parts = array_map("trim", explode(";", $str));

            $nameValue = explode("=", $parts[0]);

            $name = $nameValue[0];
            $value = ((count($nameValue) === 2) ? $nameValue[1] : "");

            if (count($parts) > 1) {
                array_shift($parts);

                foreach ($parts as $p) {
                    $keyPair = array_map("trim", explode("=", $p));
                    if (count($keyPair) === 1) {
                        $keyPair[] = null;
                    }

                    $val = $keyPair[1];

                    switch (strtolower($keyPair[0])) {
                        case "expires":
                            if ($val !== null) {
                                if (is_numeric($val) === true) {
                                    $expires = new \DateTime();
                                    $expires->setTimestamp((int)$val);
                                } else {
                                    if (strpos(strtolower($val), " utc") !== false ||
                                        strpos(strtolower($val), " gmt") !== false) {
                                        $val = substr($val, 0, strlen($val) - 4);
                                    }
                                    $expires = \DateTime::createFromFormat("D, d M Y H:i:s", $val);
                                }
                            }
                            break;

                        case "domain":
                            $domain = $val;
                            break;

                        case "path":
                            $path = $val;
                            break;

                        case "secure":
                            $secure = true;
                            break;

                        case "httponly":
                            $httpOnly = true;
                            break;
                    }
                }
            }
        }


        if ($err === false) {
            return new Cookie($name, $value, $expires, $domain, $path, $secure, $httpOnly);
        } else {
            throw new \InvalidArgumentException($err);
        }
    }