protected function redirect_to_policies($userid, $returnurl = null) {

        // Make a list of all policies that the user has not answered yet.
        $allpolicies = $this->policies;

        if ($this->isexistinguser) {
            $acceptances = api::get_user_acceptances($userid);
            foreach ($allpolicies as $ix => $policy) {
                $isaccepted = api::is_user_version_accepted($userid, $policy->id, $acceptances);
                if ($isaccepted) {
                    // The user has accepted this policy, do not show it again.
                    unset($allpolicies[$ix]);
                } else if ($isaccepted === false && $policy->optional == policy_version::AGREEMENT_OPTIONAL) {
                    // The user declined this policy but the agreement was optional, do not show it.
                    unset($allpolicies[$ix]);
                } else {
                    // The user has not answered the policy yet, or the agreement is compulsory. Show it.
                    continue;
                }
            }

        } else {
            $presignupcache = \cache::make('core', 'presignup');
            $acceptances = $presignupcache->get('tool_policy_policyversionidsagreed');
            if ($acceptances) {
                foreach ($allpolicies as $ix => $policy) {
                    if (in_array($policy->id, $acceptances)) {
                        unset($allpolicies[$ix]);
                    }
                }
            }
        }

        if (!empty($allpolicies)) {
            // Check if some of the to-be-accepted policies should be agreed on their own page.
            foreach ($allpolicies as $policy) {
                if ($policy->agreementstyle == policy_version::AGREEMENTSTYLE_OWNPAGE) {
                    if (empty($returnurl)) {
                        $returnurl = (new moodle_url('/admin/tool/policy/index.php'))->out_as_local_url(false);
                    }
                    $urlparams = ['versionid' => $policy->id, 'returnurl' => $returnurl];
                    redirect(new moodle_url('/admin/tool/policy/view.php', $urlparams));
                }
            }

            $currentpolicyversionids = [];
            foreach ($allpolicies as $policy) {
                $currentpolicyversionids[] = $policy->id;
            }

            $cache = \cache::make('core', 'presignup');
            $cachekey = 'tool_policy_viewedpolicies';

            $viewedpolicies = $cache->get($cachekey);
            if (!empty($viewedpolicies)) {
                // Get the list of the policies docs which the user haven't viewed during this session.
                $pendingpolicies = array_diff($currentpolicyversionids, $viewedpolicies);
            } else {
                $pendingpolicies = $currentpolicyversionids;
            }
            if (count($pendingpolicies) > 0) {
                // Still is needed to show some policies docs. Save in the session and redirect.
                $policyversionid = array_shift($pendingpolicies);
                $viewedpolicies[] = $policyversionid;
                $cache->set($cachekey, $viewedpolicies);
                if (empty($returnurl)) {
                    $returnurl = new moodle_url('/admin/tool/policy/index.php');
                }
                $urlparams = ['versionid' => $policyversionid,
                              'returnurl' => $returnurl,
                              'numpolicy' => count($currentpolicyversionids) - count($pendingpolicies),
                              'totalpolicies' => count($currentpolicyversionids),
                ];
                redirect(new moodle_url('/admin/tool/policy/view.php', $urlparams));
            }
        } else {
            // Update the policyagreed for the user to avoid infinite loop because there are no policies to-be-accepted.
            api::update_policyagreed($userid);
            $this->redirect_to_previous_url();
        }
    }