public static function validateNonce(string $action, Session $session, Dictionary $arguments, array $context = [])
    {
        // Check if a nonce was posted at all
        if (!$arguments->has(self::$nonce_parameter, Type::STRING))
        {
            // No nonce submitted, indeterminate outcome
            return null;
        }
        
        $context_values = [];
        foreach ($context as $key => $value)
        {
            if (is_int($key)) 
            {
                $key = $value;
                $value = $arguments->get($key);
            }
            $context_values[$key] = $value;
        }

        $nonce = $arguments->getString(self::$nonce_parameter);

        $parts = explode('$', $nonce);
        if (count($parts) !== 2)
            return false;

        list($hash, $timestamp) = $parts;

        // Check that the nonce has not expired yet
        $now = time();
        if ($timestamp > $now || $now - $timestamp  > self::$nonce_timeout)
            return false;

        // Generate the expected nonce
        $expected_nonce = self::getNonce($action, $session, $context_values, $timestamp);

        // Compare the generated nonce with the submitted nonce
        return $expected_nonce === $nonce;
    }