protected static function normalizeQuery(?string $query): ?string
    {
        if (null === $query) {
            return null;
        }

        if ('' === $query) {
            return '';
        }

        $parts = [];
        $order = [];

        // sort query params by key and remove missing keys
        foreach (explode('&', $query) as $param) {
            if ('' === $param || '=' === $param[0]) {
                continue;
            }
            $parts[] = $param;
            $kvp = explode('=', $param, 2);
            $order[] = $kvp[0];
        }

        array_multisort($order, SORT_ASC, $parts);

        return parent::normalizeQuery(implode('&', $parts));
    }